xen/21716-iommu-alloc.patch
Charles Arnold 9fd34708c1 - bnc#626262 - Populate-on-demand memory problem on xen with hvm
guest
  21971-pod-accounting.patch

- bnc#584204 - xm usb-list broken
  usb-list.patch

- bnc#625520 - TP-L3: NMI cannot be triggered for xen kernel
  21926-x86-pv-NMI-inject.patch

- bnc#613529 - TP-L3: kdump kernel hangs when crash was initiated
  from xen kernel
  21886-kexec-shutdown.patch

- Upstream Intel patches to improve X2APIC handling.
  21716-iommu-alloc.patch
  21717-ir-qi.patch
  21718-x2apic-logic.patch

  21933-vtd-ioapic-write.patch
  21953-msi-enable.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=71
2010-08-19 14:34:50 +00:00

212 lines
6.9 KiB
Diff

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1279186958 -3600
# Node ID 4ba86edf38f816a0d94cfb85b90074a72113e41c
# Parent 57859775f88f5339fa256e43ee2744be7226c093
x2APIC/VT-d: allocate iommu when create a drhd
A drhd is created when parse ACPI DMAR table, but drhd->iommu is not
allocated until iommu setup. But iommu is needed by x2APIC which will
enable interrupt remapping before iommu setup. This patch allocates
iommu when create drhd. And then drhd->ecap can be removed because
it's the same as iommu->ecap.
Signed-off-by: Weidong Han <weidong.han@intel.com>
xen-unstable changeset: 21716:64a80813978f
xen-unstable date: Mon Jul 05 08:29:10 2010 +0100
Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.c
===================================================================
--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/dmar.c
+++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.c
@@ -32,6 +32,7 @@
#include "dmar.h"
#include "iommu.h"
#include "extern.h"
+#include "vtd.h"
#undef PREFIX
#define PREFIX VTDPREFIX "ACPI DMAR:"
@@ -378,7 +379,6 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
struct acpi_table_drhd * drhd = (struct acpi_table_drhd *)header;
void *dev_scope_start, *dev_scope_end;
struct acpi_drhd_unit *dmaru;
- void *addr;
int ret;
static int include_all = 0;
@@ -397,8 +397,9 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
dprintk(VTDPREFIX, " dmaru->address = %"PRIx64"\n",
dmaru->address);
- addr = map_to_nocache_virt(0, drhd->address);
- dmaru->ecap = dmar_readq(addr, DMAR_ECAP_REG);
+ ret = iommu_alloc(dmaru);
+ if ( ret )
+ goto out;
dev_scope_start = (void *)(drhd + 1);
dev_scope_end = ((void *)drhd) + header->length;
@@ -420,7 +421,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
}
if ( ret )
- xfree(dmaru);
+ goto out;
else if ( force_iommu || dmaru->include_all )
acpi_register_drhd_unit(dmaru);
else
@@ -451,14 +452,15 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
if ( invalid_cnt )
{
- xfree(dmaru);
-
if ( iommu_workaround_bios_bug &&
invalid_cnt == dmaru->scope.devices_cnt )
{
dprintk(XENLOG_WARNING VTDPREFIX,
" Workaround BIOS bug: ignore the DRHD due to all "
"devices under its scope are not PCI discoverable!\n");
+
+ iommu_free(dmaru);
+ xfree(dmaru);
}
else
{
@@ -474,6 +476,12 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
acpi_register_drhd_unit(dmaru);
}
+out:
+ if ( ret )
+ {
+ iommu_free(dmaru);
+ xfree(dmaru);
+ }
return ret;
}
Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.h
===================================================================
--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/dmar.h
+++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/dmar.h
@@ -50,7 +50,6 @@ struct acpi_drhd_unit {
struct dmar_scope scope; /* must be first member of struct */
struct list_head list;
u64 address; /* register base address of the unit */
- u64 ecap;
u8 include_all:1;
struct iommu *iommu;
struct list_head ioapic_list;
Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c
===================================================================
--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/intremap.c
+++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/intremap.c
@@ -135,15 +135,20 @@ int iommu_supports_eim(void)
/* We MUST have a DRHD unit for each IOAPIC. */
for ( apic = 0; apic < nr_ioapics; apic++ )
if ( !ioapic_to_drhd(IO_APIC_ID(apic)) )
+ {
+ dprintk(XENLOG_WARNING VTDPREFIX,
+ "There is not a DRHD for IOAPIC 0x%x (id: 0x%x)!\n",
+ apic, IO_APIC_ID(apic));
return 0;
+ }
if ( list_empty(&acpi_drhd_units) )
return 0;
for_each_drhd_unit ( drhd )
- if ( !ecap_queued_inval(drhd->ecap) ||
- !ecap_intr_remap(drhd->ecap) ||
- !ecap_eim(drhd->ecap) )
+ if ( !ecap_queued_inval(drhd->iommu->ecap) ||
+ !ecap_intr_remap(drhd->iommu->ecap) ||
+ !ecap_eim(drhd->iommu->ecap) )
return 0;
return 1;
Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c
===================================================================
--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/iommu.c
+++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/iommu.c
@@ -143,15 +143,18 @@ struct iommu_flush *iommu_get_flush(stru
return iommu ? &iommu->intel->flush : NULL;
}
-static unsigned int clflush_size;
static int iommus_incoherent;
static void __iommu_flush_cache(void *addr, unsigned int size)
{
int i;
+ static unsigned int clflush_size = 0;
if ( !iommus_incoherent )
return;
+ if ( clflush_size == 0 )
+ clflush_size = get_cache_line_size();
+
for ( i = 0; i < size; i += clflush_size )
cacheline_flush((char *)addr + i);
}
@@ -1036,7 +1039,7 @@ static int iommu_set_interrupt(struct io
return irq;
}
-static int iommu_alloc(struct acpi_drhd_unit *drhd)
+int __init iommu_alloc(struct acpi_drhd_unit *drhd)
{
struct iommu *iommu;
unsigned long sagaw, nr_dom;
@@ -1130,7 +1133,7 @@ static int iommu_alloc(struct acpi_drhd_
return 0;
}
-static void iommu_free(struct acpi_drhd_unit *drhd)
+void __init iommu_free(struct acpi_drhd_unit *drhd)
{
struct iommu *iommu = drhd->iommu;
@@ -1938,8 +1941,6 @@ int intel_vtd_setup(void)
platform_quirks();
- clflush_size = get_cache_line_size();
-
irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs);
BUG_ON(!irq_to_iommu);
memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*));
@@ -1953,9 +1954,6 @@ int intel_vtd_setup(void)
*/
for_each_drhd_unit ( drhd )
{
- if ( iommu_alloc(drhd) != 0 )
- goto error;
-
iommu = drhd->iommu;
if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) )
@@ -1995,8 +1993,6 @@ int intel_vtd_setup(void)
return 0;
error:
- for_each_drhd_unit ( drhd )
- iommu_free(drhd);
iommu_enabled = 0;
iommu_snoop = 0;
iommu_passthrough = 0;
Index: xen-4.0.0-testing/xen/drivers/passthrough/vtd/vtd.h
===================================================================
--- xen-4.0.0-testing.orig/xen/drivers/passthrough/vtd/vtd.h
+++ xen-4.0.0-testing/xen/drivers/passthrough/vtd/vtd.h
@@ -108,4 +108,7 @@ void unmap_vtd_domain_page(void *va);
void iommu_flush_cache_entry(void *addr, unsigned int size);
void iommu_flush_cache_page(void *addr, unsigned long npages);
+int iommu_alloc(struct acpi_drhd_unit *drhd);
+void iommu_free(struct acpi_drhd_unit *drhd);
+
#endif // _VTD_H_