aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 16:06:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 16:06:49 -0400
commit781c5a67f152c17c3e4a9ed9647f8c0be6ea5ae9 (patch)
tree5cba2f98482e4612e4daf8e57e4e50a24a273fe9
parente990c77d06dbacc8e5c5edd2c4a1005d318a4fa6 (diff)
parent9ea77bdb39b62c9bf9fd3cdd1c25a9420bccd380 (diff)
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
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--arch/x86/Kconfig47
-rw-r--r--arch/x86/kernel/setup.c106
3 files changed, 63 insertions, 95 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ed05a4a0d24..a2ffd6be0ef 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2153,6 +2153,11 @@ and is between 256 and 4096 characters. It is defined in the file
2153 Reserves a hole at the top of the kernel virtual 2153 Reserves a hole at the top of the kernel virtual
2154 address space. 2154 address space.
2155 2155
2156 reservelow= [X86]
2157 Format: nn[K]
2158 Set the amount of memory to reserve for BIOS at
2159 the bottom of the address space.
2160
2156 reset_devices [KNL] Force drivers to reset the underlying device 2161 reset_devices [KNL] Force drivers to reset the underlying device
2157 during initialization. 2162 during initialization.
2158 2163
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a1bd569f6c5..b8676498d8d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1341,25 +1341,34 @@ config X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
1341 Set whether the default state of memory_corruption_check is 1341 Set whether the default state of memory_corruption_check is
1342 on or off. 1342 on or off.
1343 1343
1344config X86_RESERVE_LOW_64K 1344config X86_RESERVE_LOW
1345 bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen" 1345 int "Amount of low memory, in kilobytes, to reserve for the BIOS"
1346 default y 1346 default 64
1347 ---help--- 1347 range 4 640
1348 Reserve the first 64K of physical RAM on BIOSes that are known 1348 ---help---
1349 to potentially corrupt that memory range. A numbers of BIOSes are 1349 Specify the amount of low memory to reserve for the BIOS.
1350 known to utilize this area during suspend/resume, so it must not 1350
1351 be used by the kernel. 1351 The first page contains BIOS data structures that the kernel
1352 1352 must not use, so that page must always be reserved.
1353 Set this to N if you are absolutely sure that you trust the BIOS 1353
1354 to get all its memory reservations and usages right. 1354 By default we reserve the first 64K of physical RAM, as a
1355 1355 number of BIOSes are known to corrupt that memory range
1356 If you have doubts about the BIOS (e.g. suspend/resume does not 1356 during events such as suspend/resume or monitor cable
1357 work or there's kernel crashes after certain hardware hotplug 1357 insertion, so it must not be used by the kernel.
1358 events) and it's not AMI or Phoenix, then you might want to enable 1358
1359 X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical 1359 You can set this to 4 if you are absolutely sure that you
1360 corruption patterns. 1360 trust the BIOS to get all its memory reservations and usages
1361 1361 right. If you know your BIOS have problems beyond the
1362 Say Y if unsure. 1362 default 64K area, you can set this to 640 to avoid using the
1363 entire low memory range.
1364
1365 If you have doubts about the BIOS (e.g. suspend/resume does
1366 not work or there's kernel crashes after certain hardware
1367 hotplug events) then you might want to enable
1368 X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check
1369 typical corruption patterns.
1370
1371 Leave this to the default value of 64 if you are unsure.
1363 1372
1364config MATH_EMULATION 1373config MATH_EMULATION
1365 bool 1374 bool
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index df770ad99b3..6154701a5fd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -619,79 +619,7 @@ static __init void reserve_ibft_region(void)
619 reserve_early_overlap_ok(addr, addr + size, "ibft"); 619 reserve_early_overlap_ok(addr, addr + size, "ibft");
620} 620}
621 621
622#ifdef CONFIG_X86_RESERVE_LOW_64K 622static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
623static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
624{
625 printk(KERN_NOTICE
626 "%s detected: BIOS may corrupt low RAM, working around it.\n",
627 d->ident);
628
629 e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
630 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
631
632 return 0;
633}
634#endif
635
636/* List of systems that have known low memory corruption BIOS problems */
637static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
638#ifdef CONFIG_X86_RESERVE_LOW_64K
639 {
640 .callback = dmi_low_memory_corruption,
641 .ident = "AMI BIOS",
642 .matches = {
643 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
644 },
645 },
646 {
647 .callback = dmi_low_memory_corruption,
648 .ident = "Phoenix BIOS",
649 .matches = {
650 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
651 },
652 },
653 {
654 .callback = dmi_low_memory_corruption,
655 .ident = "Phoenix/MSC BIOS",
656 .matches = {
657 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
658 },
659 },
660 /*
661 * AMI BIOS with low memory corruption was found on Intel DG45ID and
662 * DG45FC boards.
663 * It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
664 * match only DMI_BOARD_NAME and see if there is more bad products
665 * with this vendor.
666 */
667 {
668 .callback = dmi_low_memory_corruption,
669 .ident = "AMI BIOS",
670 .matches = {
671 DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
672 },
673 },
674 {
675 .callback = dmi_low_memory_corruption,
676 .ident = "AMI BIOS",
677 .matches = {
678 DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
679 },
680 },
681 /*
682 * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
683 * match on the product name.
684 */
685 {
686 .callback = dmi_low_memory_corruption,
687 .ident = "Phoenix BIOS",
688 .matches = {
689 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
690 },
691 },
692#endif
693 {}
694};
695 623
696static void __init trim_bios_range(void) 624static void __init trim_bios_range(void)
697{ 625{
@@ -699,8 +627,14 @@ static void __init trim_bios_range(void)
699 * A special case is the first 4Kb of memory; 627 * A special case is the first 4Kb of memory;
700 * This is a BIOS owned area, not kernel ram, but generally 628 * This is a BIOS owned area, not kernel ram, but generally
701 * not listed as such in the E820 table. 629 * not listed as such in the E820 table.
630 *
631 * This typically reserves additional memory (64KiB by default)
632 * since some BIOSes are known to corrupt low memory. See the
633 * Kconfig help text for X86_RESERVE_LOW.
702 */ 634 */
703 e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED); 635 e820_update_range(0, ALIGN(reserve_low, PAGE_SIZE),
636 E820_RAM, E820_RESERVED);
637
704 /* 638 /*
705 * special case: Some BIOSen report the PC BIOS 639 * special case: Some BIOSen report the PC BIOS
706 * area (640->1Mb) as ram even though it is not. 640 * area (640->1Mb) as ram even though it is not.
@@ -710,6 +644,28 @@ static void __init trim_bios_range(void)
710 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); 644 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
711} 645}
712 646
647static int __init parse_reservelow(char *p)
648{
649 unsigned long long size;
650
651 if (!p)
652 return -EINVAL;
653
654 size = memparse(p, &p);
655
656 if (size < 4096)
657 size = 4096;
658
659 if (size > 640*1024)
660 size = 640*1024;
661
662 reserve_low = size;
663
664 return 0;
665}
666
667early_param("reservelow", parse_reservelow);
668
713/* 669/*
714 * Determine if we were loaded by an EFI loader. If so, then we have also been 670 * Determine if we were loaded by an EFI loader. If so, then we have also been
715 * passed the efi memmap, systab, etc., so we should use these data structures 671 * 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 821
866 dmi_scan_machine(); 822 dmi_scan_machine();
867 823
868 dmi_check_system(bad_bios_dmi_table);
869
870 /* 824 /*
871 * VMware detection requires dmi to be available, so this 825 * VMware detection requires dmi to be available, so this
872 * needs to be done after dmi_scan_machine, for the BP. 826 * needs to be done after dmi_scan_machine, for the BP.