aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vmsi.c
diff options
context:
space:
mode:
authorWei Liu <liuw@liuw.name>2011-05-26 14:58:28 +0100
committerWei Liu <liuw@liuw.name>2011-05-26 14:58:28 +0100
commit080bc640708f40ade856a4eba67f47781415d754 (patch)
tree54ec765a82f05eef8aff728d2c90b98a7c1f733f /xen/arch/x86/hvm/vmsi.c
parenteadf449efd7518d8f5789c90aaa93c487b88fb98 (diff)
downloadxen-080bc640708f40ade856a4eba67f47781415d754.tar.gz
xen-080bc640708f40ade856a4eba67f47781415d754.tar.bz2
xen-080bc640708f40ade856a4eba67f47781415d754.zip
x86: Add a new operation in HVMOP to inject emulated MSI.
The original vmsi_deliver is renamed to vmsi_deliver_pirq. New vmsi_deliver is dedicated to the actually delivering. Original HVMOP number is unchanged. New operation is numbered 16 and enclosed by (__XEN__) and (__XEN_TOOLS__). Signed-off-by: Wei Liu <liuw@liuw.name> Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/hvm/vmsi.c')
-rw-r--r--xen/arch/x86/hvm/vmsi.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c
index cba074852f..2457fb407e 100644
--- a/xen/arch/x86/hvm/vmsi.c
+++ b/xen/arch/x86/hvm/vmsi.c
@@ -65,29 +65,14 @@ static void vmsi_inj_irq(
}
}
-int vmsi_deliver(struct domain *d, int pirq)
+int vmsi_deliver(
+ struct domain *d, int vector,
+ uint8_t dest, uint8_t dest_mode,
+ uint8_t delivery_mode, uint8_t trig_mode)
{
- struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
- uint32_t flags = hvm_irq_dpci->mirq[pirq].gmsi.gflags;
- int vector = hvm_irq_dpci->mirq[pirq].gmsi.gvec;
- uint8_t dest = (uint8_t)flags;
- uint8_t dest_mode = !!(flags & VMSI_DM_MASK);
- uint8_t delivery_mode = (flags & VMSI_DELIV_MASK) >> GFLAGS_SHIFT_DELIV_MODE;
- uint8_t trig_mode = (flags & VMSI_TRIG_MODE) >> GFLAGS_SHIFT_TRG_MODE;
struct vlapic *target;
struct vcpu *v;
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
- "msi: dest=%x dest_mode=%x delivery_mode=%x "
- "vector=%x trig_mode=%x\n",
- dest, dest_mode, delivery_mode, vector, trig_mode);
-
- if ( !( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_GUEST_MSI ) )
- {
- gdprintk(XENLOG_WARNING, "pirq %x not msi \n", pirq);
- return 0;
- }
-
switch ( delivery_mode )
{
case dest_LowestPrio:
@@ -125,6 +110,32 @@ int vmsi_deliver(struct domain *d, int pirq)
return 1;
}
+int vmsi_deliver_pirq(struct domain *d, int pirq)
+{
+ struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+ uint32_t flags = hvm_irq_dpci->mirq[pirq].gmsi.gflags;
+ int vector = hvm_irq_dpci->mirq[pirq].gmsi.gvec;
+ uint8_t dest = (uint8_t)flags;
+ uint8_t dest_mode = !!(flags & VMSI_DM_MASK);
+ uint8_t delivery_mode = (flags & VMSI_DELIV_MASK)
+ >> GFLAGS_SHIFT_DELIV_MODE;
+ uint8_t trig_mode = (flags&VMSI_TRIG_MODE) >> GFLAGS_SHIFT_TRG_MODE;
+
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
+ "msi: dest=%x dest_mode=%x delivery_mode=%x "
+ "vector=%x trig_mode=%x\n",
+ dest, dest_mode, delivery_mode, vector, trig_mode);
+
+ if ( !(hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_GUEST_MSI) )
+ {
+ gdprintk(XENLOG_WARNING, "pirq %x not msi \n", pirq);
+ return 0;
+ }
+
+ vmsi_deliver(d, vector, dest, dest_mode, delivery_mode, trig_mode);
+ return 1;
+}
+
/* Return value, -1 : multi-dests, non-negative value: dest_vcpu_id */
int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_mode)
{