From: Kamala Narasimhan Date: Mon, 7 Dec 2009 19:48:46 +0000 (-0500) Subject: Workaround resume from host S3 issue encountered on HP laptops. X-Git-Url: http://xenbits.xen.org/gitweb?a=commitdiff_plain;h=ecc35cd2cedd4d1e97221c361ee5a8514f9f9a47;p=xenclient%2Fxen-pq.git Workaround resume from host S3 issue encountered on HP laptops. --- diff --git a/master/hp-host-resume-workaround b/master/hp-host-resume-workaround new file mode 100644 index 0000000..292bb38 --- /dev/null +++ b/master/hp-host-resume-workaround @@ -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 diff --git a/master/series b/master/series index 4ced81c..9f1291e 100644 --- a/master/series +++ b/master/series @@ -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