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
This commit is contained in:
@@ -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
|
|||||||
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
|
||||||
|
range 4 640
|
||||||
---help---
|
---help---
|
||||||
Reserve the first 64K of physical RAM on BIOSes that are known
|
Specify the amount of low memory to reserve for the BIOS.
|
||||||
to potentially corrupt that memory range. A numbers of BIOSes are
|
|
||||||
known to utilize this area during suspend/resume, so it must not
|
|
||||||
be used by the kernel.
|
|
||||||
|
|
||||||
Set this to N if you are absolutely sure that you trust the BIOS
|
The first page contains BIOS data structures that the kernel
|
||||||
to get all its memory reservations and usages right.
|
must not use, so that page must always be reserved.
|
||||||
|
|
||||||
If you have doubts about the BIOS (e.g. suspend/resume does not
|
By default we reserve the first 64K of physical RAM, as a
|
||||||
work or there's kernel crashes after certain hardware hotplug
|
number of BIOSes are known to corrupt that memory range
|
||||||
events) and it's not AMI or Phoenix, then you might want to enable
|
during events such as suspend/resume or monitor cable
|
||||||
X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
|
insertion, so it must not be used by the kernel.
|
||||||
corruption patterns.
|
|
||||||
|
|
||||||
Say Y if unsure.
|
You can set this to 4 if you are absolutely sure that you
|
||||||
|
trust the BIOS to get all its memory reservations and usages
|
||||||
|
right. If you know your BIOS have problems beyond the
|
||||||
|
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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
|
|
||||||
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.
|
||||||
|
Reference in New Issue
Block a user