aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXudong Hao <xudong.hao@intel.com>2013-04-02 12:33:47 +0200
committerJan Beulich <jbeulich@suse.com>2013-04-02 12:33:47 +0200
commit7c0d6df2557a86510ace568ecaf5a02dd4440c99 (patch)
tree238b76aafaf90acb32e0e7a4a7a759628d7cfd06
parent842a6cedc61eabe5731ef192bf39dad66403d0c6 (diff)
downloadxen-7c0d6df2557a86510ace568ecaf5a02dd4440c99.tar.gz
xen-7c0d6df2557a86510ace568ecaf5a02dd4440c99.tar.bz2
xen-7c0d6df2557a86510ace568ecaf5a02dd4440c99.zip
x86: reserve pages when SandyBridge integrated graphics
SNB graphics devices have a bug that prevent them from accessing certain memory ranges, namely anything below 1M and in the pages listed in the table. Xen does not initialize below 1MB to heap, i.e. below 1MB pages don't be allocated, so it's unnecessary to reserve memory below the 1 MB mark that has not already been reserved. So reserve those pages listed in the table at xen boot if set detect a SNB gfx device on the CPU to avoid GPU hangs. Signed-off-by: Xudong Hao <xudong.hao@intel.com> Acked-by: Keir Fraser <keir@xen.org> master commit: db537fe3023bf157b85c8246782cb72a6f989b31 master date: 2013-03-26 14:22:07 +0100
-rw-r--r--xen/arch/x86/mm.c20
-rw-r--r--xen/common/page_alloc.c23
-rw-r--r--xen/drivers/passthrough/vtd/quirks.c1
-rw-r--r--xen/include/asm-x86/mm.h1
-rw-r--r--xen/include/xen/pci.h5
5 files changed, 49 insertions, 1 deletions
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index ca2c8f8346..0ee088a41a 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -113,6 +113,7 @@
#include <public/memory.h>
#include <public/sched.h>
#include <xsm/xsm.h>
+#include <xen/pci.h>
#include <xen/trace.h>
#include <asm/setup.h>
#include <asm/fixmap.h>
@@ -5693,6 +5694,25 @@ void memguard_unguard_stack(void *p)
memguard_unguard_range(p, PAGE_SIZE);
}
+const unsigned long *__init get_platform_badpages(unsigned int *array_size)
+{
+ u32 igd_id;
+ static unsigned long __initdata bad_pages[] = {
+ 0x20050000,
+ 0x20110000,
+ 0x20130000,
+ 0x20138000,
+ 0x40004000,
+ };
+
+ *array_size = ARRAY_SIZE(bad_pages);
+ igd_id = pci_conf_read32(0, 2, 0, 0);
+ if ( !IS_SNB_GFX(igd_id) )
+ return NULL;
+
+ return bad_pages;
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 311b5ee2a4..f0de320ec9 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -144,6 +144,10 @@ void __init init_boot_pages(paddr_t ps, paddr_t pe)
{
unsigned long bad_spfn, bad_epfn;
const char *p;
+#ifdef CONFIG_X86
+ const unsigned long *badpage = NULL;
+ unsigned int i, array_size;
+#endif
ps = round_pgup(ps);
pe = round_pgdown(pe);
@@ -154,6 +158,25 @@ void __init init_boot_pages(paddr_t ps, paddr_t pe)
bootmem_region_add(ps >> PAGE_SHIFT, pe >> PAGE_SHIFT);
+#ifdef CONFIG_X86
+ /*
+ * Here we put platform-specific memory range workarounds, i.e.
+ * memory known to be corrupt or otherwise in need to be reserved on
+ * specific platforms.
+ * We get these certain pages and remove them from memory region list.
+ */
+ badpage = get_platform_badpages(&array_size);
+ if ( badpage )
+ {
+ for ( i = 0; i < array_size; i++ )
+ {
+ bootmem_region_zap(*badpage >> PAGE_SHIFT,
+ (*badpage >> PAGE_SHIFT) + 1);
+ badpage++;
+ }
+ }
+#endif
+
/* Check new pages against the bad-page list. */
p = opt_badpage;
while ( *p != '\0' )
diff --git a/xen/drivers/passthrough/vtd/quirks.c b/xen/drivers/passthrough/vtd/quirks.c
index b540b9c39a..19c1a96f72 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -47,7 +47,6 @@
#define IS_CTG(id) (id == 0x2a408086)
#define IS_ILK(id) (id == 0x00408086 || id == 0x00448086 || id== 0x00628086 || id == 0x006A8086)
#define IS_CPT(id) (id == 0x01008086 || id == 0x01048086)
-#define IS_SNB_GFX(id) (id == 0x01068086 || id == 0x01168086 || id == 0x01268086 || id == 0x01028086 || id == 0x01128086 || id == 0x01228086 || id == 0x010A8086)
u32 ioh_id;
u32 igd_id;
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index c93a022952..2013ba9280 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -329,6 +329,7 @@ int is_iomem_page(unsigned long mfn);
void clear_superpage_mark(struct page_info *page);
+const unsigned long *get_platform_badpages(unsigned int *array_size);
struct domain *page_get_owner_and_reference(struct page_info *page);
void put_page(struct page_info *page);
int get_page(struct page_info *page, struct domain *domain);
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 3b8067ebbe..ea514da91b 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -127,4 +127,9 @@ int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable);
void msixtbl_pt_unregister(struct domain *d, int pirq);
void pci_enable_acs(struct pci_dev *pdev);
+#define IS_SNB_GFX(id) (id == 0x01068086 || id == 0x01168086 \
+ || id == 0x01268086 || id == 0x01028086 \
+ || id == 0x01128086 || id == 0x01228086 \
+ || id == 0x010A8086 )
+
#endif /* __XEN_PCI_H__ */