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:
commit
781c5a67f1
3 changed files with 59 additions and 91 deletions
|
@ -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
|
||||
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
|
||||
during initialization.
|
||||
|
||||
|
|
|
@ -1341,25 +1341,34 @@ config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
|
|||
Set whether the default state of memory_corruption_check is
|
||||
on or off.
|
||||
|
||||
config X86_RESERVE_LOW_64K
|
||||
bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
|
||||
default y
|
||||
config X86_RESERVE_LOW
|
||||
int "Amount of low memory, in kilobytes, to reserve for the BIOS"
|
||||
default 64
|
||||
range 4 640
|
||||
---help---
|
||||
Reserve the first 64K of physical RAM on BIOSes that are known
|
||||
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.
|
||||
Specify the amount of low memory to reserve for the BIOS.
|
||||
|
||||
Set this to N if you are absolutely sure that you trust the BIOS
|
||||
to get all its memory reservations and usages right.
|
||||
The first page contains BIOS data structures that the kernel
|
||||
must not use, so that page must always be reserved.
|
||||
|
||||
If you have doubts about the BIOS (e.g. suspend/resume does not
|
||||
work or there's kernel crashes after certain hardware hotplug
|
||||
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
|
||||
corruption patterns.
|
||||
By default we reserve the first 64K of physical RAM, as a
|
||||
number of BIOSes are known to corrupt that memory range
|
||||
during events such as suspend/resume or monitor cable
|
||||
insertion, so it must not be used by the kernel.
|
||||
|
||||
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
|
||||
bool
|
||||
|
|
|
@ -619,79 +619,7 @@ static __init void reserve_ibft_region(void)
|
|||
reserve_early_overlap_ok(addr, addr + size, "ibft");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_RESERVE_LOW_64K
|
||||
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 unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
|
||||
|
||||
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;
|
||||
* This is a BIOS owned area, not kernel ram, but generally
|
||||
* 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
|
||||
* 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);
|
||||
}
|
||||
|
||||
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
|
||||
* 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_check_system(bad_bios_dmi_table);
|
||||
|
||||
/*
|
||||
* VMware detection requires dmi to be available, so this
|
||||
* needs to be done after dmi_scan_machine, for the BP.
|
||||
|
|
Loading…
Reference in a new issue