Skip to content

Commit

Permalink
Merge branch 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/tip/tip

Pull x86 fixes from Peter Anvin:
 "This is mainly a workaround for a bug in Sandy Bridge graphics which
  causes corruption of certain memory pages."

* 'x86/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/Sandy Bridge: Sandy Bridge workaround depends on CONFIG_PCI
  x86/Sandy Bridge: mark arrays in __init functions as __initconst
  x86/Sandy Bridge: reserve pages when integrated graphics is present
  x86, efi: correct precedence of operators in setup_efi_pci
  • Loading branch information
Linus Torvalds committed Jan 16, 2013
2 parents c4ef9bc + e43b3ce commit 2409c87
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
if (status != EFI_SUCCESS)
continue;

if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
continue;

if (!pci->romimage || !pci->romsize)
Expand Down
80 changes: 80 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,83 @@ static __init void reserve_ibft_region(void)

static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;

static bool __init snb_gfx_workaround_needed(void)
{
#ifdef CONFIG_PCI
int i;
u16 vendor, devid;
static const __initconst 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;
#endif

return false;
}

/*
* Sandy Bridge graphics has trouble with certain ranges, exclude
* them from allocation.
*/
static void __init trim_snb_memory(void)
{
static const __initconst 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)
{
/*
Expand All @@ -630,6 +707,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);
}

Expand Down Expand Up @@ -908,6 +986,8 @@ void __init setup_arch(char **cmdline_p)

setup_real_mode();

trim_platform_memory_ranges();

init_gbpages();

/* max_pfn_mapped is updated here */
Expand Down

0 comments on commit 2409c87

Please sign in to comment.