7f6bd728fd
xend-cpuid.patch - Rename 2XXXX-vif-bridge.patch -> vif-bridge-tap-fix.patch - bnc#747331 - XEN: standard "newburn" kernel QA stress test on guest (+ smartd on Dom0?) freezes the guest 24883-x86-guest-walk-not-present.patch - bnc#745367 - MCE bank handling during migration 24781-x86-vmce-mcg_ctl.patch 24886-x86-vmce-mcg_ctl-default.patch 24887-x86-vmce-sr.patch - bnc#744771 - L3: VM with passed through PCI card fails to reboot under dom0 load 24888-pci-release-devices.patch - Upstream patches from Jan 24517-VT-d-fault-softirq.patch 24527-AMD-Vi-fault-softirq.patch 24535-x86-vMSI-misc.patch 24615-VESA-lfb-flush.patch 24690-x86-PCI-SERR-no-deadlock.patch 24701-gnttab-map-grant-ref-recovery.patch 24742-gnttab-misc.patch 24780-x86-paging-use-clear_guest.patch 24805-x86-MSI-X-dom0-ro.patch ioemu-9869-MSI-X-init.patch ioemu-9873-MSI-X-fix-unregister_iomem.patch - bnc#745005 - Update vif configuration examples in xmexample* Updated xen-xmexample.diff OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=172
90 lines
2.8 KiB
Diff
90 lines
2.8 KiB
Diff
References: bnc#712051, CVE-2011-3131
|
|
|
|
# HG changeset patch
|
|
# User Dario Faggioli <dario.faggioli@citrix.com>
|
|
# Date 1326798686 0
|
|
# Node ID a7ae457c327cd790704643e0ed4def3e717b47b3
|
|
# Parent 2913ccc6d70f15ffcc15c7e066c9269b15a30a09
|
|
Move IOMMU faults handling into softirq for VT-d.
|
|
|
|
Dealing with interrupts from VT-d IOMMU(s) is deferred to a
|
|
softirq-tasklet, raised by the actual IRQ handler. Since a new
|
|
interrupt is not generated, even if further faults occur, until we
|
|
cleared all the pending ones, there's no need of disabling IRQs, as
|
|
the hardware does it by its own. Notice that this may cause the log
|
|
to overflow, but none of the existing entry will be overwritten.
|
|
|
|
Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com>
|
|
Committed-by: Keir Fraser <keir@xen.org>
|
|
|
|
--- a/xen/drivers/passthrough/vtd/iommu.c
|
|
+++ b/xen/drivers/passthrough/vtd/iommu.c
|
|
@@ -53,6 +53,8 @@ bool_t __read_mostly untrusted_msi;
|
|
|
|
int nr_iommus;
|
|
|
|
+static struct tasklet vtd_fault_tasklet;
|
|
+
|
|
static void setup_dom0_devices(struct domain *d);
|
|
static void setup_dom0_rmrr(struct domain *d);
|
|
|
|
@@ -866,10 +868,8 @@ static void iommu_fault_status(u32 fault
|
|
}
|
|
|
|
#define PRIMARY_FAULT_REG_LEN (16)
|
|
-static void iommu_page_fault(int irq, void *dev_id,
|
|
- struct cpu_user_regs *regs)
|
|
+static void __do_iommu_page_fault(struct iommu *iommu)
|
|
{
|
|
- struct iommu *iommu = dev_id;
|
|
int reg, fault_index;
|
|
u32 fault_status;
|
|
unsigned long flags;
|
|
@@ -943,6 +943,37 @@ clear_overflow:
|
|
}
|
|
}
|
|
|
|
+static void do_iommu_page_fault(unsigned long data)
|
|
+{
|
|
+ struct acpi_drhd_unit *drhd;
|
|
+
|
|
+ if ( list_empty(&acpi_drhd_units) )
|
|
+ {
|
|
+ INTEL_IOMMU_DEBUG("no device found, something must be very wrong!\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * No matter from whom the interrupt came from, check all the
|
|
+ * IOMMUs present in the system. This allows for having just one
|
|
+ * tasklet (instead of one per each IOMMUs) and should be more than
|
|
+ * fine, considering how rare the event of a fault should be.
|
|
+ */
|
|
+ for_each_drhd_unit ( drhd )
|
|
+ __do_iommu_page_fault(drhd->iommu);
|
|
+}
|
|
+
|
|
+static void iommu_page_fault(int irq, void *dev_id,
|
|
+ struct cpu_user_regs *regs)
|
|
+{
|
|
+ /*
|
|
+ * Just flag the tasklet as runnable. This is fine, according to VT-d
|
|
+ * specs since a new interrupt won't be generated until we clear all
|
|
+ * the faults that caused this one to happen.
|
|
+ */
|
|
+ tasklet_schedule(&vtd_fault_tasklet);
|
|
+}
|
|
+
|
|
static void dma_msi_unmask(unsigned int irq)
|
|
{
|
|
struct iommu *iommu = irq_to_iommu[irq];
|
|
@@ -2083,6 +2114,8 @@ int __init intel_vtd_setup(void)
|
|
iommu_hap_pt_share = FALSE;
|
|
}
|
|
|
|
+ softirq_tasklet_init(&vtd_fault_tasklet, do_iommu_page_fault, 0);
|
|
+
|
|
if ( !iommu_qinval && iommu_intremap )
|
|
{
|
|
iommu_intremap = 0;
|