xen/22223-vtd-igd-workaround.patch
Charles Arnold 08a77ed8c4 - fate#310510 - fix xenpaging
xenpaging.tools_xenpaging_cleanup.patch

- fate#310510 - fix xenpaging
  xenpaging.mem_event_check_ring-free_requests.patch

- install /etc/xen/examples/xentrace_formats.txt to get human readable
  tracedata if xenalyze is not used

- fate#310510 - fix xenpaging
  xenpaging.autostart_delay.patch
  xenpaging.blacklist.patch
  xenpaging.MRU_SIZE.patch
  remove xenpaging.hacks.patch, realmode works

- Upstream patches from Jan including fixes for the following bugs
  bnc#583568 - Xen kernel is not booting
  bnc#615206 - Xen kernel fails to boot with IO-APIC problem
  bnc#640773 - Xen kernel crashing right after grub
  bnc#643477 - issues with PCI hotplug/hotunplug to Xen driver domain
  22223-vtd-igd-workaround.patch
  22222-x86-timer-extint.patch
  22214-x86-msr-misc-enable.patch
  22213-x86-xsave-cpuid-check.patch
  22194-tmem-check-pv-mfn.patch
  22177-i386-irq-safe-map_domain_page.patch
  22175-x86-irq-enter-exit.patch
  22174-x86-pmtimer-accuracy.patch
  22160-Intel-C6-EOI.patch

OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=76
2010-10-20 21:00:35 +00:00

132 lines
3.9 KiB
Diff

# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1286028261 -3600
# Node ID 4beee577912215c734b79cb84bfe3fb20c1afbfc
# Parent aed9fd361340158daf2d7160d1b367478b6312d6
Vt-d: fix dom0 graphics problem on Levnovo T410.
References: bnc#643477
The patch is derived from a similar quirk in Linux kernel by David
Woodhouse and Adam Jackson. It checks for VT enabling bit in IGD GGC
register. If VT is not enabled correctly in the IGD, Xen does not
enable VT-d translation for IGD VT-d engine. In case where iommu boot
parameter is set to force, Xen calls panic().
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
jb: Simplified and switched operands of && in first if() added to
iommu_enable_translation().
--- a/xen/drivers/passthrough/vtd/dmar.c
+++ b/xen/drivers/passthrough/vtd/dmar.c
@@ -46,6 +46,7 @@ LIST_HEAD(acpi_rmrr_units);
LIST_HEAD(acpi_atsr_units);
LIST_HEAD(acpi_rhsa_units);
+static u64 igd_drhd_address;
u8 dmar_host_address_width;
void dmar_scope_add_buses(struct dmar_scope *scope, u16 sec_bus, u16 sub_bus)
@@ -239,6 +240,11 @@ struct acpi_rhsa_unit * drhd_to_rhsa(str
return NULL;
}
+int is_igd_drhd(struct acpi_drhd_unit *drhd)
+{
+ return ( drhd->address == igd_drhd_address ? 1 : 0);
+}
+
/*
* Count number of devices in device scope. Do not include PCI sub
* hierarchies.
@@ -333,6 +339,15 @@ static int __init acpi_parse_dev_scope(v
if ( iommu_verbose )
dprintk(VTDPREFIX, " endpoint: %x:%x.%x\n",
bus, path->dev, path->fn);
+
+ if ( type == DMAR_TYPE )
+ {
+ struct acpi_drhd_unit *drhd = acpi_entry;
+
+ if ( (bus == 0) && (path->dev == 2) && (path->fn == 0) )
+ igd_drhd_address = drhd->address;
+ }
+
break;
case ACPI_DEV_IOAPIC:
--- a/xen/drivers/passthrough/vtd/dmar.h
+++ b/xen/drivers/passthrough/vtd/dmar.h
@@ -114,5 +114,6 @@ void *map_to_nocache_virt(int nr_iommus,
int vtd_hw_check(void);
void disable_pmr(struct iommu *iommu);
int is_usb_device(u8 bus, u8 devfn);
+int is_igd_drhd(struct acpi_drhd_unit *drhd);
#endif /* _DMAR_H_ */
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -688,10 +688,34 @@ static int iommu_set_root_entry(struct i
return 0;
}
-static void iommu_enable_translation(struct iommu *iommu)
+#define GGC 0x52
+#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
+static int is_igd_vt_enabled(void)
+{
+ unsigned short ggc;
+
+ /* integrated graphics on Intel platforms is located at 0:2.0 */
+ ggc = pci_conf_read16(0, 2, 0, GGC);
+ return ( ggc & GGC_MEMORY_VT_ENABLED ? 1 : 0 );
+}
+
+static void iommu_enable_translation(struct acpi_drhd_unit *drhd)
{
u32 sts;
unsigned long flags;
+ struct iommu *iommu = drhd->iommu;
+
+ if ( is_igd_drhd(drhd) && !is_igd_vt_enabled() )
+ {
+ if ( force_iommu )
+ panic("BIOS did not enable IGD for VT properly, crash Xen for security purpose!\n");
+ else
+ {
+ dprintk(XENLOG_WARNING VTDPREFIX,
+ "BIOS did not enable IGD for VT properly. Disabling IGD VT-d engine.\n");
+ return;
+ }
+ }
if ( iommu_verbose )
dprintk(VTDPREFIX,
@@ -1178,7 +1202,6 @@ static int intel_iommu_domain_init(struc
static void intel_iommu_dom0_init(struct domain *d)
{
- struct iommu *iommu;
struct acpi_drhd_unit *drhd;
if ( !iommu_passthrough && !need_iommu(d) )
@@ -1194,8 +1217,7 @@ static void intel_iommu_dom0_init(struct
for_each_drhd_unit ( drhd )
{
- iommu = drhd->iommu;
- iommu_enable_translation(iommu);
+ iommu_enable_translation(drhd);
}
}
@@ -2163,7 +2185,7 @@ static void vtd_resume(void)
(u32) iommu_state[i][DMAR_FEUADDR_REG]);
spin_unlock_irqrestore(&iommu->register_lock, flags);
- iommu_enable_translation(iommu);
+ iommu_enable_translation(drhd);
}
}