# HG changeset patch
# User Shan Haitao <haitao.shan@xxxxxxxxx>
# Date 1311060259 -3600
# Node ID 43f7bdbe47d3f1a5312f5cb50cb0f18c83dbcc76
# Parent c2888876abd3a9c33010d0b7be1cd6fb94af0776
Adding back guest MSI eoi support for unmaskable MSI interrupt
This patch adds back proper guest MSI EOI hook for correctly handling
unmaskable MSI interrupt, which is wrongly removed by changset 23703.
Signed-off-by: Shan Haitao <haitao.shan@xxxxxxxxx>
---
diff -r c2888876abd3 -r 43f7bdbe47d3 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Tue Jul 19 08:22:19 2011 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Tue Jul 19 08:24:19 2011 +0100
@@ -400,6 +400,8 @@
if ( vlapic_test_and_clear_vector(vector, &vlapic->regs->data[APIC_TMR]) )
vioapic_update_EOI(vlapic_domain(vlapic), vector);
+
+ hvm_dpci_msi_eoi(current->domain, vector);
}
int vlapic_ipi(
diff -r c2888876abd3 -r 43f7bdbe47d3 xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c Tue Jul 19 08:22:19 2011 +0100
+++ b/xen/drivers/passthrough/io.c Tue Jul 19 08:24:19 2011 +0100
@@ -421,6 +421,56 @@
}
#ifdef SUPPORT_MSI_REMAPPING
+/* called with d->event_lock held */
+static void __msi_pirq_eoi(struct hvm_pirq_dpci *pirq_dpci)
+{
+ irq_desc_t *desc;
+
+ if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) &&
+ (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) )
+ {
+ struct pirq *pirq = dpci_pirq(pirq_dpci);
+
+ BUG_ON(!local_irq_is_enabled());
+ desc = pirq_spin_lock_irq_desc(pirq, NULL);
+ if ( !desc )
+ return;
+ desc_guest_eoi(desc, pirq);
+ }
+}
+
+static int _hvm_dpci_msi_eoi(struct domain *d,
+ struct hvm_pirq_dpci *pirq_dpci, void *arg)
+{
+ int vector = (long)arg;
+
+ if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) &&
+ (pirq_dpci->gmsi.gvec == vector) )
+ {
+ int dest = pirq_dpci->gmsi.gflags & VMSI_DEST_ID_MASK;
+ int dest_mode = !!(pirq_dpci->gmsi.gflags & VMSI_DM_MASK);
+
+ if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest,
+ dest_mode) )
+ {
+ __msi_pirq_eoi(pirq_dpci);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void hvm_dpci_msi_eoi(struct domain *d, int vector)
+{
+ if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci )
+ return;
+
+ spin_lock(&d->event_lock);
+ pt_pirq_iterate(d, _hvm_dpci_msi_eoi, (void *)(long)vector);
+ spin_unlock(&d->event_lock);
+}
+
static int hvm_pci_msi_assert(struct domain *d,
struct hvm_pirq_dpci *pirq_dpci)
{
@@ -458,6 +508,14 @@
else
hvm_pci_intx_assert(d, device, intx);
pirq_dpci->pending++;
+
+#ifdef SUPPORT_MSI_REMAPPING
+ if ( pirq_dpci->flags & HVM_IRQ_DPCI_TRANSLATE )
+ {
+ /* for translated MSI to INTx interrupt, eoi as early as
possible */
+ __msi_pirq_eoi(pirq_dpci);
+ }
+#endif
}
/*
diff -r c2888876abd3 -r 43f7bdbe47d3 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Tue Jul 19 08:22:19 2011 +0100
+++ b/xen/include/asm-x86/hvm/io.h Tue Jul 19 08:24:19 2011 +0100
@@ -139,5 +139,6 @@
void stdvga_init(struct domain *d);
void stdvga_deinit(struct domain *d);
+extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
#endif /* __ASM_X86_HVM_IO_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|