Commit 781c5a67 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-bios-for-linus' of...

Merge branch 'x86-bios-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'x86-bios-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, bios: Make the x86 early memory reservation a kernel option
  x86, bios: By default, reserve the low 64K for all BIOSes
parents e990c77d 9ea77bdb
...@@ -2153,6 +2153,11 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -2153,6 +2153,11 @@ and is between 256 and 4096 characters. It is defined in the file
Reserves a hole at the top of the kernel virtual Reserves a hole at the top of the kernel virtual
address space. address space.
reservelow= [X86]
Format: nn[K]
Set the amount of memory to reserve for BIOS at
the bottom of the address space.
reset_devices [KNL] Force drivers to reset the underlying device reset_devices [KNL] Force drivers to reset the underlying device
during initialization. during initialization.
......
...@@ -1341,25 +1341,34 @@ config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK ...@@ -1341,25 +1341,34 @@ config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
Set whether the default state of memory_corruption_check is Set whether the default state of memory_corruption_check is
on or off. on or off.
config X86_RESERVE_LOW_64K config X86_RESERVE_LOW
bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen" int "Amount of low memory, in kilobytes, to reserve for the BIOS"
default y default 64
---help--- range 4 640
Reserve the first 64K of physical RAM on BIOSes that are known ---help---
to potentially corrupt that memory range. A numbers of BIOSes are Specify the amount of low memory to reserve for the BIOS.
known to utilize this area during suspend/resume, so it must not
be used by the kernel. The first page contains BIOS data structures that the kernel
must not use, so that page must always be reserved.
Set this to N if you are absolutely sure that you trust the BIOS
to get all its memory reservations and usages right. By default we reserve the first 64K of physical RAM, as a
number of BIOSes are known to corrupt that memory range
If you have doubts about the BIOS (e.g. suspend/resume does not during events such as suspend/resume or monitor cable
work or there's kernel crashes after certain hardware hotplug insertion, so it must not be used by the kernel.
events) and it's not AMI or Phoenix, then you might want to enable
X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical You can set this to 4 if you are absolutely sure that you
corruption patterns. trust the BIOS to get all its memory reservations and usages
right. If you know your BIOS have problems beyond the
Say Y if unsure. default 64K area, you can set this to 640 to avoid using the
entire low memory range.
If you have doubts about the BIOS (e.g. suspend/resume does
not work or there's kernel crashes after certain hardware
hotplug events) then you might want to enable
X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check
typical corruption patterns.
Leave this to the default value of 64 if you are unsure.
config MATH_EMULATION config MATH_EMULATION
bool bool
......
...@@ -619,79 +619,7 @@ static __init void reserve_ibft_region(void) ...@@ -619,79 +619,7 @@ static __init void reserve_ibft_region(void)
reserve_early_overlap_ok(addr, addr + size, "ibft"); reserve_early_overlap_ok(addr, addr + size, "ibft");
} }
#ifdef CONFIG_X86_RESERVE_LOW_64K static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
{
printk(KERN_NOTICE
"%s detected: BIOS may corrupt low RAM, working around it.\n",
d->ident);
e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
return 0;
}
#endif
/* List of systems that have known low memory corruption BIOS problems */
static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
#ifdef CONFIG_X86_RESERVE_LOW_64K
{
.callback = dmi_low_memory_corruption,
.ident = "AMI BIOS",
.matches = {
DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
},
},
{
.callback = dmi_low_memory_corruption,
.ident = "Phoenix BIOS",
.matches = {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
},
},
{
.callback = dmi_low_memory_corruption,
.ident = "Phoenix/MSC BIOS",
.matches = {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
},
},
/*
* AMI BIOS with low memory corruption was found on Intel DG45ID and
* DG45FC boards.
* It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
* match only DMI_BOARD_NAME and see if there is more bad products
* with this vendor.
*/
{
.callback = dmi_low_memory_corruption,
.ident = "AMI BIOS",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
},
},
{
.callback = dmi_low_memory_corruption,
.ident = "AMI BIOS",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
},
},
/*
* The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
* match on the product name.
*/
{
.callback = dmi_low_memory_corruption,
.ident = "Phoenix BIOS",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
},
},
#endif
{}
};
static void __init trim_bios_range(void) static void __init trim_bios_range(void)
{ {
...@@ -699,8 +627,14 @@ static void __init trim_bios_range(void) ...@@ -699,8 +627,14 @@ static void __init trim_bios_range(void)
* A special case is the first 4Kb of memory; * A special case is the first 4Kb of memory;
* This is a BIOS owned area, not kernel ram, but generally * This is a BIOS owned area, not kernel ram, but generally
* not listed as such in the E820 table. * not listed as such in the E820 table.
*
* This typically reserves additional memory (64KiB by default)
* since some BIOSes are known to corrupt low memory. See the
* Kconfig help text for X86_RESERVE_LOW.
*/ */
e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED); e820_update_range(0, ALIGN(reserve_low, PAGE_SIZE),
E820_RAM, E820_RESERVED);
/* /*
* special case: Some BIOSen report the PC BIOS * special case: Some BIOSen report the PC BIOS
* area (640->1Mb) as ram even though it is not. * area (640->1Mb) as ram even though it is not.
...@@ -710,6 +644,28 @@ static void __init trim_bios_range(void) ...@@ -710,6 +644,28 @@ static void __init trim_bios_range(void)
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
} }
static int __init parse_reservelow(char *p)
{
unsigned long long size;
if (!p)
return -EINVAL;
size = memparse(p, &p);
if (size < 4096)
size = 4096;
if (size > 640*1024)
size = 640*1024;
reserve_low = size;
return 0;
}
early_param("reservelow", parse_reservelow);
/* /*
* Determine if we were loaded by an EFI loader. If so, then we have also been * Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures * passed the efi memmap, systab, etc., so we should use these data structures
...@@ -865,8 +821,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -865,8 +821,6 @@ void __init setup_arch(char **cmdline_p)
dmi_scan_machine(); dmi_scan_machine();
dmi_check_system(bad_bios_dmi_table);
/* /*
* VMware detection requires dmi to be available, so this * VMware detection requires dmi to be available, so this
* needs to be done after dmi_scan_machine, for the BP. * needs to be done after dmi_scan_machine, for the BP.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment