From: Stefano Stabellini Date: Tue, 3 Jul 2012 12:39:01 +0000 (+0100) Subject: xen: event channel remapping for emulated MSIs X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~8214 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=88fccdd11ca0c2df915d7d56ab78ea70d4b60e52;p=xen.git xen: event channel remapping for emulated MSIs Linux PV on HVM guests remap all the MSIs onto event channels, including MSIs corresponding to QEMU's emulated devices. This patch makes sure that we handle correctly the case of emulated MSI that have been remapped, sending a pirq to the guest instead. Signed-off-by: Stefano Stabellini Tested-by: Deep Debroy Committed-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index a90927aac7..f44f3b957e 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -281,6 +281,31 @@ void hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data) >> MSI_DATA_TRIGGER_SHIFT; uint8_t vector = data & MSI_DATA_VECTOR_MASK; + if ( !vector ) + { + int pirq = ((addr >> 32) & 0xffffff00) | ((addr >> 12) & 0xff); + if ( pirq > 0 ) + { + struct pirq *info = pirq_info(d, pirq); + + /* if it is the first time, allocate the pirq */ + if (info->arch.hvm.emuirq == IRQ_UNBOUND) + { + spin_lock(&d->event_lock); + map_domain_emuirq_pirq(d, pirq, IRQ_MSI_EMU); + spin_unlock(&d->event_lock); + } else if (info->arch.hvm.emuirq != IRQ_MSI_EMU) + { + printk("%s: pirq %d does not correspond to an emulated MSI\n", __func__, pirq); + return; + } + send_guest_pirq(d, info); + return; + } else { + printk("%s: error getting pirq from MSI: pirq = %d\n", __func__, pirq); + } + } + vmsi_deliver(d, vector, dest, dest_mode, delivery_mode, trig_mode); } diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h index 40e22452d6..066f64d91e 100644 --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -188,6 +188,7 @@ void cleanup_domain_irq_mapping(struct domain *); }) #define IRQ_UNBOUND -1 #define IRQ_PT -2 +#define IRQ_MSI_EMU -3 bool_t cpu_has_pending_apic_eoi(void);