08a77ed8c4
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
132 lines
3.9 KiB
Diff
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);
|
|
}
|
|
}
|
|
|