diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 16:06:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 16:06:49 -0400 |
commit | 781c5a67f152c17c3e4a9ed9647f8c0be6ea5ae9 (patch) | |
tree | 5cba2f98482e4612e4daf8e57e4e50a24a273fe9 | |
parent | e990c77d06dbacc8e5c5edd2c4a1005d318a4fa6 (diff) | |
parent | 9ea77bdb39b62c9bf9fd3cdd1c25a9420bccd380 (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.txt | 5 | ||||
-rw-r--r-- | arch/x86/Kconfig | 47 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 106 |
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 | ||
1344 | config X86_RESERVE_LOW_64K | 1344 | config 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 | ||
1364 | config MATH_EMULATION | 1373 | config 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 | 622 | static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10; |
623 | static 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 */ | ||
637 | static 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 | ||
696 | static void __init trim_bios_range(void) | 624 | static 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 | ||
647 | static 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 | |||
667 | early_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. |