On Fri, 11 Jan 2013 14:39:04 -0800 tip-bot for Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> wrote: > Commit-ID: a9acc5365dbda29f7be2884efb63771dc24bd815 > Gitweb: http://git.kernel.org/tip/a9acc5365dbda29f7be2884efb63771dc24bd815 > Author: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> > AuthorDate: Wed, 14 Nov 2012 20:43:31 +0000 > Committer: H. Peter Anvin <hpa@xxxxxxxxxxxxxxx> > CommitDate: Fri, 11 Jan 2013 14:26:38 -0800 > > x86/Sandy Bridge: reserve pages when integrated graphics is present > > 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. So reserve those at boot if set detect a SNB gfx device on the > CPU to avoid GPU hangs. > > Stephane Marchesin had a similar patch to the page allocator awhile > back, but rather than reserving pages up front, it leaked them at > allocation time. > > [ hpa: made a number of stylistic changes, marked arrays as static > const, and made less verbose; use "memblock=debug" for full > verbosity. ] > > Signed-off-by: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> > Signed-off-by: H. Peter Anvin <hpa@xxxxxxxxxxxxxxx> > --- > arch/x86/kernel/setup.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 78 insertions(+) > > diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c > index 23ddd55..9dcb325 100644 > --- a/arch/x86/kernel/setup.c > +++ b/arch/x86/kernel/setup.c > @@ -610,6 +610,81 @@ static __init void reserve_ibft_region(void) > > static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10; > > +static bool __init snb_gfx_workaround_needed(void) > +{ > + int i; > + u16 vendor, devid; > + static const u16 snb_ids[] = { > + 0x0102, > + 0x0112, > + 0x0122, > + 0x0106, > + 0x0116, > + 0x0126, > + 0x010a, > + }; > + > + /* Assume no if something weird is going on with PCI */ > + if (!early_pci_allowed()) > + return false; > + > + vendor = read_pci_config_16(0, 2, 0, PCI_VENDOR_ID); > + if (vendor != 0x8086) > + return false; > + > + devid = read_pci_config_16(0, 2, 0, PCI_DEVICE_ID); > + for (i = 0; i < ARRAY_SIZE(snb_ids); i++) > + if (devid == snb_ids[i]) > + return true; > + > + return false; > +} > + > +/* > + * Sandy Bridge graphics has trouble with certain ranges, exclude > + * them from allocation. > + */ > +static void __init trim_snb_memory(void) > +{ > + static const unsigned long bad_pages[] = { > + 0x20050000, > + 0x20110000, > + 0x20130000, > + 0x20138000, > + 0x40004000, > + }; > + int i; > + > + if (!snb_gfx_workaround_needed()) > + return; > + > + printk(KERN_DEBUG "reserving inaccessible SNB gfx pages\n"); > + > + /* > + * Reserve all memory below the 1 MB mark that has not > + * already been reserved. > + */ > + memblock_reserve(0, 1<<20); > + > + for (i = 0; i < ARRAY_SIZE(bad_pages); i++) { > + if (memblock_reserve(bad_pages[i], PAGE_SIZE)) > + printk(KERN_WARNING "failed to reserve 0x%08lx\n", > + bad_pages[i]); > + } > +} > + > +/* > + * 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. > + * > + * If this gets used more widely it could use a real dispatch mechanism. > + */ > +static void __init trim_platform_memory_ranges(void) > +{ > + trim_snb_memory(); > +} > + > static void __init trim_bios_range(void) > { > /* > @@ -630,6 +705,7 @@ static void __init trim_bios_range(void) > * take them out. > */ > e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1); > + > sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); > } > > @@ -908,6 +984,8 @@ void __init setup_arch(char **cmdline_p) > > setup_real_mode(); > > + trim_platform_memory_ranges(); > + > init_gbpages(); > > /* max_pfn_mapped is updated here */ > Great, thanks Peter. Stephane, care to try this out? -- Jesse Barnes, Intel Open Source Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html