aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup.c
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 /arch/x86/kernel/setup.c
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
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r--arch/x86/kernel/setup.c106
1 files changed, 30 insertions, 76 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index df770ad99b3e..6154701a5fd3 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.