WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-4.0-testing] Vt-d: fix dom0 graphics problem on Lev

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-4.0-testing] Vt-d: fix dom0 graphics problem on Levnovo T410.
From: "Xen patchbot-4.0-testing" <patchbot-4.0-testing@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 17 Oct 2010 05:55:26 -0700
Delivery-date: Sun, 17 Oct 2010 05:58:00 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1286028653 -3600
# Node ID 63b7e7766f2efa82c0510fcb686f101da69b4f1d
# Parent  f7d54e1d7044a7d3836b017b0806021b1c17ac7a
Vt-d: fix dom0 graphics problem on Levnovo T410.

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@xxxxxxxxx>
xen-unstable changeset:   22223:4beee5779122
xen-unstable date:        Sat Oct 02 15:04:21 2010 +0100
---
 xen/drivers/passthrough/vtd/dmar.c  |   26 +++++++++++++++++++-------
 xen/drivers/passthrough/vtd/dmar.h  |    1 +
 xen/drivers/passthrough/vtd/iommu.c |   32 +++++++++++++++++++++++++++-----
 3 files changed, 47 insertions(+), 12 deletions(-)

diff -r f7d54e1d7044 -r 63b7e7766f2e xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c        Sat Oct 02 15:10:22 2010 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.c        Sat Oct 02 15:10:53 2010 +0100
@@ -46,6 +46,7 @@ LIST_HEAD(acpi_atsr_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.
@@ -272,7 +278,8 @@ static int scope_device_count(void *star
 
 
 static int __init acpi_parse_dev_scope(void *start, void *end,
-                                       void *acpi_entry, int type)
+                                       void *acpi_entry, int type,
+                                       int *igd)
 {
     struct dmar_scope *scope = acpi_entry;
     struct acpi_ioapic_unit *acpi_ioapic_unit;
@@ -333,6 +340,8 @@ static int __init acpi_parse_dev_scope(v
             if ( iommu_verbose )
                 dprintk(VTDPREFIX, "  endpoint: %x:%x.%x\n",
                         bus, path->dev, path->fn);
+            if ( (bus == 0) && (path->dev == 2) && (path->fn == 0) )
+                *igd = 1;
             break;
 
         case ACPI_DEV_IOAPIC:
@@ -379,7 +388,7 @@ 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;
-    int ret;
+    int ret, igd = 0;
     static int include_all = 0;
 
     if ( (ret = acpi_dmar_check_length(header, sizeof(*drhd))) != 0 )
@@ -404,7 +413,10 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     dev_scope_start = (void *)(drhd + 1);
     dev_scope_end = ((void *)drhd) + header->length;
     ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
-                               dmaru, DMAR_TYPE);
+                               dmaru, DMAR_TYPE, &igd);
+
+    if ( igd )
+        igd_drhd_address = dmaru->address;
 
     if ( dmaru->include_all )
     {
@@ -492,7 +504,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
     struct acpi_rmrr_unit *rmrru;
     void *dev_scope_start, *dev_scope_end;
     u64 base_addr = rmrr->base_address, end_addr = rmrr->end_address;
-    int ret;
+    int ret, igd = 0;
 
     if ( (ret = acpi_dmar_check_length(header, sizeof(*rmrr))) != 0 )
         return ret;
@@ -524,7 +536,7 @@ acpi_parse_one_rmrr(struct acpi_dmar_ent
     dev_scope_start = (void *)(rmrr + 1);
     dev_scope_end   = ((void *)rmrr) + header->length;
     ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
-                               rmrru, RMRR_TYPE);
+                               rmrru, RMRR_TYPE, &igd);
 
     if ( ret || (rmrru->scope.devices_cnt == 0) )
         xfree(rmrru);
@@ -589,7 +601,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
 {
     struct acpi_table_atsr *atsr = (struct acpi_table_atsr *)header;
     struct acpi_atsr_unit *atsru;
-    int ret;
+    int ret, igd = 0;
     static int all_ports;
     void *dev_scope_start, *dev_scope_end;
 
@@ -610,7 +622,7 @@ acpi_parse_one_atsr(struct acpi_dmar_ent
         dev_scope_start = (void *)(atsr + 1);
         dev_scope_end   = ((void *)atsr) + header->length;
         ret = acpi_parse_dev_scope(dev_scope_start, dev_scope_end,
-                                   atsru, ATSR_TYPE);
+                                   atsru, ATSR_TYPE, &igd);
     }
     else
     {
diff -r f7d54e1d7044 -r 63b7e7766f2e xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h        Sat Oct 02 15:10:22 2010 +0100
+++ b/xen/drivers/passthrough/vtd/dmar.h        Sat Oct 02 15:10:53 2010 +0100
@@ -114,5 +114,6 @@ int vtd_hw_check(void);
 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_ */
diff -r f7d54e1d7044 -r 63b7e7766f2e xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Sat Oct 02 15:10:22 2010 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Sat Oct 02 15:10:53 2010 +0100
@@ -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_vt_enabled() && is_igd_drhd(drhd) ) 
+    {
+        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);
     }
 }
 
@@ -2160,7 +2182,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);
     }
 }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-4.0-testing] Vt-d: fix dom0 graphics problem on Levnovo T410., Xen patchbot-4.0-testing <=