diff options
author | Wei Liu <liuw@liuw.name> | 2011-05-26 14:58:28 +0100 |
---|---|---|
committer | Wei Liu <liuw@liuw.name> | 2011-05-26 14:58:28 +0100 |
commit | 080bc640708f40ade856a4eba67f47781415d754 (patch) | |
tree | 54ec765a82f05eef8aff728d2c90b98a7c1f733f /xen/arch/x86/hvm/vmsi.c | |
parent | eadf449efd7518d8f5789c90aaa93c487b88fb98 (diff) | |
download | xen-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.c | 49 |
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) { |