]> xenbits.xen.org Git - xenclient/xen-pq.git/commitdiff
Workaround resume from host S3 issue encountered on HP laptops.
authorKamala Narasimhan <kamala.narasimhan@citrix.com>
Mon, 7 Dec 2009 19:48:46 +0000 (14:48 -0500)
committerKamala Narasimhan <kamala.narasimhan@citrix.com>
Mon, 7 Dec 2009 19:48:46 +0000 (14:48 -0500)
master/hp-host-resume-workaround [new file with mode: 0644]
master/series

diff --git a/master/hp-host-resume-workaround b/master/hp-host-resume-workaround
new file mode 100644 (file)
index 0000000..292bb38
--- /dev/null
@@ -0,0 +1,59 @@
+diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
+index d8c47ce..f1b5407 100644
+--- a/xen/drivers/passthrough/vtd/iommu.c
++++ b/xen/drivers/passthrough/vtd/iommu.c
+@@ -1944,16 +1944,36 @@ static int intel_iommu_group_id(u8 bus, u8 devfn)
+         return -1;
+ }
++#define IGFX_BAR_COUNT            0x6
++
++static const u8 iGfx_bus        = 0x0;
++static const u8 iGfx_device     = 0x2;
++static const u8 iGfx_function   = 0x0;
++static const u8 iGfx_bar_size   = 0x4;
++static const u8 iGfx_bar_offset = 0x10;
++static u32 iGfx_pci_bars[IGFX_BAR_COUNT];
+ static u32 iommu_state[MAX_IOMMUS][MAX_IOMMU_REGS];
++
+ void iommu_suspend(void)
+ {
+     struct acpi_drhd_unit *drhd;
+     struct iommu *iommu;
+-    u32    i;
++    u32    i, count, bar_start;
+     if ( !vtd_enabled )
+         return;
++    /* Note:  Following is to workaround host S3 resume issue on HP laptops.
++     * Turns out saving iGfx bars during iommu suspend and restoring them
++     * in iommu resume will fix the hang/reset during host resume on 
++     * HP laptops. Following does that as a fallback on systems that doesn't
++     * have the firmware fix to save/restore iGfx bars.
++     */ 
++    memset(iGfx_pci_bars, 0, sizeof(iGfx_pci_bars));
++    for ( count = 0, bar_start=iGfx_bar_offset; count < IGFX_BAR_COUNT; count++, 
++          bar_start+=iGfx_bar_size )
++        iGfx_pci_bars[count] = pci_conf_read32(iGfx_bus, iGfx_device, iGfx_function, bar_start);
++
+     iommu_flush_all();
+     for_each_drhd_unit ( drhd )
+@@ -1985,11 +2005,15 @@ void iommu_resume(void)
+     struct acpi_drhd_unit *drhd;
+     struct iommu *iommu;
+     struct iommu_flush *flush;
+-    u32 i;
++    u32 i, count, bar_start;
+     if ( !vtd_enabled )
+         return;
++    for ( count = 0, bar_start=iGfx_bar_offset; count < IGFX_BAR_COUNT; count++, 
++          bar_start+=iGfx_bar_size )  
++        pci_conf_write32(iGfx_bus, iGfx_device, iGfx_function, bar_start, iGfx_pci_bars[count]);
++
+     /* Re-initialize the register-based flush functions.
+      * In iommu_flush_all(), we invoke iommu_flush_{context,iotlb}_global(),
+      * but at this point, on hosts that support QI(Queued Invalidation), QI
index 4ced81cdb7d9a72e01a6c2f651d4fc51dbf913cf..9f1291e2613198c8b4a4c2915800cd2a843b1b1e 100644 (file)
@@ -28,3 +28,4 @@ iommu-replace-panic-with-printk
 hack-vbe-always-on
 filter-igfx-io
 hack-vbe-dont-check-mem
+hp-host-resume-workaround