aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-10-25 13:38:43 -0400
committerIngo Molnar <mingo@elte.hu>2010-10-25 13:38:52 -0400
commit7d7a48b76012eeee25871e1d69104dec4b6d740f (patch)
treec27e3d8bb2e80ad93c7b4a5c850e1ffbc090bcd2 /arch/x86/kernel/setup.c
parente4072a9a9d186fe86293effe8828faa4be75b4a4 (diff)
parent229aebb873e29726b91e076161649cf45154b0bf (diff)
Merge branch 'linus' into x86/urgent
Merge reason: We want to queue up a dependent fix. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r--arch/x86/kernel/setup.c233
1 files changed, 112 insertions, 121 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c3a4fbb2b996..95a32746fbf9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -31,6 +31,7 @@
31#include <linux/apm_bios.h> 31#include <linux/apm_bios.h>
32#include <linux/initrd.h> 32#include <linux/initrd.h>
33#include <linux/bootmem.h> 33#include <linux/bootmem.h>
34#include <linux/memblock.h>
34#include <linux/seq_file.h> 35#include <linux/seq_file.h>
35#include <linux/console.h> 36#include <linux/console.h>
36#include <linux/mca.h> 37#include <linux/mca.h>
@@ -83,7 +84,6 @@
83#include <asm/dmi.h> 84#include <asm/dmi.h>
84#include <asm/io_apic.h> 85#include <asm/io_apic.h>
85#include <asm/ist.h> 86#include <asm/ist.h>
86#include <asm/vmi.h>
87#include <asm/setup_arch.h> 87#include <asm/setup_arch.h>
88#include <asm/bios_ebda.h> 88#include <asm/bios_ebda.h>
89#include <asm/cacheflush.h> 89#include <asm/cacheflush.h>
@@ -107,11 +107,12 @@
107#include <asm/percpu.h> 107#include <asm/percpu.h>
108#include <asm/topology.h> 108#include <asm/topology.h>
109#include <asm/apicdef.h> 109#include <asm/apicdef.h>
110#include <asm/k8.h> 110#include <asm/amd_nb.h>
111#ifdef CONFIG_X86_64 111#ifdef CONFIG_X86_64
112#include <asm/numa_64.h> 112#include <asm/numa_64.h>
113#endif 113#endif
114#include <asm/mce.h> 114#include <asm/mce.h>
115#include <asm/alternative.h>
115 116
116/* 117/*
117 * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. 118 * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
@@ -125,7 +126,6 @@ unsigned long max_pfn_mapped;
125RESERVE_BRK(dmi_alloc, 65536); 126RESERVE_BRK(dmi_alloc, 65536);
126#endif 127#endif
127 128
128unsigned int boot_cpu_id __read_mostly;
129 129
130static __initdata unsigned long _brk_start = (unsigned long)__brk_base; 130static __initdata unsigned long _brk_start = (unsigned long)__brk_base;
131unsigned long _brk_end = (unsigned long)__brk_base; 131unsigned long _brk_end = (unsigned long)__brk_base;
@@ -302,7 +302,7 @@ static inline void init_gbpages(void)
302static void __init reserve_brk(void) 302static void __init reserve_brk(void)
303{ 303{
304 if (_brk_end > _brk_start) 304 if (_brk_end > _brk_start)
305 reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK"); 305 memblock_x86_reserve_range(__pa(_brk_start), __pa(_brk_end), "BRK");
306 306
307 /* Mark brk area as locked down and no longer taking any 307 /* Mark brk area as locked down and no longer taking any
308 new allocations */ 308 new allocations */
@@ -324,17 +324,16 @@ static void __init relocate_initrd(void)
324 char *p, *q; 324 char *p, *q;
325 325
326 /* We need to move the initrd down into lowmem */ 326 /* We need to move the initrd down into lowmem */
327 ramdisk_here = find_e820_area(0, end_of_lowmem, area_size, 327 ramdisk_here = memblock_find_in_range(0, end_of_lowmem, area_size,
328 PAGE_SIZE); 328 PAGE_SIZE);
329 329
330 if (ramdisk_here == -1ULL) 330 if (ramdisk_here == MEMBLOCK_ERROR)
331 panic("Cannot find place for new RAMDISK of size %lld\n", 331 panic("Cannot find place for new RAMDISK of size %lld\n",
332 ramdisk_size); 332 ramdisk_size);
333 333
334 /* Note: this includes all the lowmem currently occupied by 334 /* Note: this includes all the lowmem currently occupied by
335 the initrd, we rely on that fact to keep the data intact. */ 335 the initrd, we rely on that fact to keep the data intact. */
336 reserve_early(ramdisk_here, ramdisk_here + area_size, 336 memblock_x86_reserve_range(ramdisk_here, ramdisk_here + area_size, "NEW RAMDISK");
337 "NEW RAMDISK");
338 initrd_start = ramdisk_here + PAGE_OFFSET; 337 initrd_start = ramdisk_here + PAGE_OFFSET;
339 initrd_end = initrd_start + ramdisk_size; 338 initrd_end = initrd_start + ramdisk_size;
340 printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", 339 printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n",
@@ -390,7 +389,7 @@ static void __init reserve_initrd(void)
390 initrd_start = 0; 389 initrd_start = 0;
391 390
392 if (ramdisk_size >= (end_of_lowmem>>1)) { 391 if (ramdisk_size >= (end_of_lowmem>>1)) {
393 free_early(ramdisk_image, ramdisk_end); 392 memblock_x86_free_range(ramdisk_image, ramdisk_end);
394 printk(KERN_ERR "initrd too large to handle, " 393 printk(KERN_ERR "initrd too large to handle, "
395 "disabling initrd\n"); 394 "disabling initrd\n");
396 return; 395 return;
@@ -413,7 +412,7 @@ static void __init reserve_initrd(void)
413 412
414 relocate_initrd(); 413 relocate_initrd();
415 414
416 free_early(ramdisk_image, ramdisk_end); 415 memblock_x86_free_range(ramdisk_image, ramdisk_end);
417} 416}
418#else 417#else
419static void __init reserve_initrd(void) 418static void __init reserve_initrd(void)
@@ -469,7 +468,7 @@ static void __init e820_reserve_setup_data(void)
469 e820_print_map("reserve setup_data"); 468 e820_print_map("reserve setup_data");
470} 469}
471 470
472static void __init reserve_early_setup_data(void) 471static void __init memblock_x86_reserve_range_setup_data(void)
473{ 472{
474 struct setup_data *data; 473 struct setup_data *data;
475 u64 pa_data; 474 u64 pa_data;
@@ -481,7 +480,7 @@ static void __init reserve_early_setup_data(void)
481 while (pa_data) { 480 while (pa_data) {
482 data = early_memremap(pa_data, sizeof(*data)); 481 data = early_memremap(pa_data, sizeof(*data));
483 sprintf(buf, "setup data %x", data->type); 482 sprintf(buf, "setup data %x", data->type);
484 reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf); 483 memblock_x86_reserve_range(pa_data, pa_data+sizeof(*data)+data->len, buf);
485 pa_data = data->next; 484 pa_data = data->next;
486 early_iounmap(data, sizeof(*data)); 485 early_iounmap(data, sizeof(*data));
487 } 486 }
@@ -502,6 +501,7 @@ static inline unsigned long long get_total_mem(void)
502 return total << PAGE_SHIFT; 501 return total << PAGE_SHIFT;
503} 502}
504 503
504#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
505static void __init reserve_crashkernel(void) 505static void __init reserve_crashkernel(void)
506{ 506{
507 unsigned long long total_mem; 507 unsigned long long total_mem;
@@ -519,23 +519,27 @@ static void __init reserve_crashkernel(void)
519 if (crash_base <= 0) { 519 if (crash_base <= 0) {
520 const unsigned long long alignment = 16<<20; /* 16M */ 520 const unsigned long long alignment = 16<<20; /* 16M */
521 521
522 crash_base = find_e820_area(alignment, ULONG_MAX, crash_size, 522 /*
523 alignment); 523 * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
524 if (crash_base == -1ULL) { 524 */
525 crash_base = memblock_find_in_range(alignment,
526 DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
527
528 if (crash_base == MEMBLOCK_ERROR) {
525 pr_info("crashkernel reservation failed - No suitable area found.\n"); 529 pr_info("crashkernel reservation failed - No suitable area found.\n");
526 return; 530 return;
527 } 531 }
528 } else { 532 } else {
529 unsigned long long start; 533 unsigned long long start;
530 534
531 start = find_e820_area(crash_base, ULONG_MAX, crash_size, 535 start = memblock_find_in_range(crash_base,
532 1<<20); 536 crash_base + crash_size, crash_size, 1<<20);
533 if (start != crash_base) { 537 if (start != crash_base) {
534 pr_info("crashkernel reservation failed - memory is in use.\n"); 538 pr_info("crashkernel reservation failed - memory is in use.\n");
535 return; 539 return;
536 } 540 }
537 } 541 }
538 reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL"); 542 memblock_x86_reserve_range(crash_base, crash_base + crash_size, "CRASH KERNEL");
539 543
540 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " 544 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
541 "for crashkernel (System RAM: %ldMB)\n", 545 "for crashkernel (System RAM: %ldMB)\n",
@@ -615,82 +619,10 @@ static __init void reserve_ibft_region(void)
615 addr = find_ibft_region(&size); 619 addr = find_ibft_region(&size);
616 620
617 if (size) 621 if (size)
618 reserve_early_overlap_ok(addr, addr + size, "ibft"); 622 memblock_x86_reserve_range(addr, addr + size, "* ibft");
619} 623}
620 624
621#ifdef CONFIG_X86_RESERVE_LOW_64K 625static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
622static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
623{
624 printk(KERN_NOTICE
625 "%s detected: BIOS may corrupt low RAM, working around it.\n",
626 d->ident);
627
628 e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
629 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
630
631 return 0;
632}
633#endif
634
635/* List of systems that have known low memory corruption BIOS problems */
636static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
637#ifdef CONFIG_X86_RESERVE_LOW_64K
638 {
639 .callback = dmi_low_memory_corruption,
640 .ident = "AMI BIOS",
641 .matches = {
642 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
643 },
644 },
645 {
646 .callback = dmi_low_memory_corruption,
647 .ident = "Phoenix BIOS",
648 .matches = {
649 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
650 },
651 },
652 {
653 .callback = dmi_low_memory_corruption,
654 .ident = "Phoenix/MSC BIOS",
655 .matches = {
656 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"),
657 },
658 },
659 /*
660 * AMI BIOS with low memory corruption was found on Intel DG45ID and
661 * DG45FC boards.
662 * It has a different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
663 * match only DMI_BOARD_NAME and see if there is more bad products
664 * with this vendor.
665 */
666 {
667 .callback = dmi_low_memory_corruption,
668 .ident = "AMI BIOS",
669 .matches = {
670 DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
671 },
672 },
673 {
674 .callback = dmi_low_memory_corruption,
675 .ident = "AMI BIOS",
676 .matches = {
677 DMI_MATCH(DMI_BOARD_NAME, "DG45FC"),
678 },
679 },
680 /*
681 * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so
682 * match on the product name.
683 */
684 {
685 .callback = dmi_low_memory_corruption,
686 .ident = "Phoenix BIOS",
687 .matches = {
688 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
689 },
690 },
691#endif
692 {}
693};
694 626
695static void __init trim_bios_range(void) 627static void __init trim_bios_range(void)
696{ 628{
@@ -698,8 +630,14 @@ static void __init trim_bios_range(void)
698 * A special case is the first 4Kb of memory; 630 * A special case is the first 4Kb of memory;
699 * This is a BIOS owned area, not kernel ram, but generally 631 * This is a BIOS owned area, not kernel ram, but generally
700 * not listed as such in the E820 table. 632 * not listed as such in the E820 table.
633 *
634 * This typically reserves additional memory (64KiB by default)
635 * since some BIOSes are known to corrupt low memory. See the
636 * Kconfig help text for X86_RESERVE_LOW.
701 */ 637 */
702 e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED); 638 e820_update_range(0, ALIGN(reserve_low, PAGE_SIZE),
639 E820_RAM, E820_RESERVED);
640
703 /* 641 /*
704 * special case: Some BIOSen report the PC BIOS 642 * special case: Some BIOSen report the PC BIOS
705 * area (640->1Mb) as ram even though it is not. 643 * area (640->1Mb) as ram even though it is not.
@@ -709,6 +647,37 @@ static void __init trim_bios_range(void)
709 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); 647 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
710} 648}
711 649
650static int __init parse_reservelow(char *p)
651{
652 unsigned long long size;
653
654 if (!p)
655 return -EINVAL;
656
657 size = memparse(p, &p);
658
659 if (size < 4096)
660 size = 4096;
661
662 if (size > 640*1024)
663 size = 640*1024;
664
665 reserve_low = size;
666
667 return 0;
668}
669
670early_param("reservelow", parse_reservelow);
671
672static u64 __init get_max_mapped(void)
673{
674 u64 end = max_pfn_mapped;
675
676 end <<= PAGE_SHIFT;
677
678 return end;
679}
680
712/* 681/*
713 * Determine if we were loaded by an EFI loader. If so, then we have also been 682 * Determine if we were loaded by an EFI loader. If so, then we have also been
714 * passed the efi memmap, systab, etc., so we should use these data structures 683 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -726,18 +695,30 @@ void __init setup_arch(char **cmdline_p)
726{ 695{
727 int acpi = 0; 696 int acpi = 0;
728 int k8 = 0; 697 int k8 = 0;
698 unsigned long flags;
729 699
730#ifdef CONFIG_X86_32 700#ifdef CONFIG_X86_32
731 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 701 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
732 visws_early_detect(); 702 visws_early_detect();
703
704 /*
705 * copy kernel address range established so far and switch
706 * to the proper swapper page table
707 */
708 clone_pgd_range(swapper_pg_dir + KERNEL_PGD_BOUNDARY,
709 initial_page_table + KERNEL_PGD_BOUNDARY,
710 KERNEL_PGD_PTRS);
711
712 load_cr3(swapper_pg_dir);
713 __flush_tlb_all();
733#else 714#else
734 printk(KERN_INFO "Command line: %s\n", boot_command_line); 715 printk(KERN_INFO "Command line: %s\n", boot_command_line);
735#endif 716#endif
736 717
737 /* VMI may relocate the fixmap; do this before touching ioremap area */ 718 /*
738 vmi_init(); 719 * If we have OLPC OFW, we might end up relocating the fixmap due to
739 720 * reserve_top(), so do this before touching the ioremap area.
740 /* OFW also may relocate the fixmap */ 721 */
741 olpc_ofw_detect(); 722 olpc_ofw_detect();
742 723
743 early_trap_init(); 724 early_trap_init();
@@ -782,7 +763,7 @@ void __init setup_arch(char **cmdline_p)
782#endif 763#endif
783 4)) { 764 4)) {
784 efi_enabled = 1; 765 efi_enabled = 1;
785 efi_reserve_early(); 766 efi_memblock_x86_reserve_range();
786 } 767 }
787#endif 768#endif
788 769
@@ -838,11 +819,8 @@ void __init setup_arch(char **cmdline_p)
838 819
839 x86_report_nx(); 820 x86_report_nx();
840 821
841 /* Must be before kernel pagetables are setup */
842 vmi_activate();
843
844 /* after early param, so could get panic from serial */ 822 /* after early param, so could get panic from serial */
845 reserve_early_setup_data(); 823 memblock_x86_reserve_range_setup_data();
846 824
847 if (acpi_mps_check()) { 825 if (acpi_mps_check()) {
848#ifdef CONFIG_X86_LOCAL_APIC 826#ifdef CONFIG_X86_LOCAL_APIC
@@ -863,8 +841,6 @@ void __init setup_arch(char **cmdline_p)
863 841
864 dmi_scan_machine(); 842 dmi_scan_machine();
865 843
866 dmi_check_system(bad_bios_dmi_table);
867
868 /* 844 /*
869 * VMware detection requires dmi to be available, so this 845 * VMware detection requires dmi to be available, so this
870 * needs to be done after dmi_scan_machine, for the BP. 846 * needs to be done after dmi_scan_machine, for the BP.
@@ -897,8 +873,6 @@ void __init setup_arch(char **cmdline_p)
897 */ 873 */
898 max_pfn = e820_end_of_ram_pfn(); 874 max_pfn = e820_end_of_ram_pfn();
899 875
900 /* preallocate 4k for mptable mpc */
901 early_reserve_e820_mpc_new();
902 /* update e820 for memory not covered by WB MTRRs */ 876 /* update e820 for memory not covered by WB MTRRs */
903 mtrr_bp_init(); 877 mtrr_bp_init();
904 if (mtrr_trim_uncached_memory(max_pfn)) 878 if (mtrr_trim_uncached_memory(max_pfn))
@@ -920,18 +894,8 @@ void __init setup_arch(char **cmdline_p)
920 max_low_pfn = max_pfn; 894 max_low_pfn = max_pfn;
921 895
922 high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1; 896 high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
923 max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
924#endif 897#endif
925 898
926#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
927 setup_bios_corruption_check();
928#endif
929
930 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
931 max_pfn_mapped<<PAGE_SHIFT);
932
933 reserve_brk();
934
935 /* 899 /*
936 * Find and reserve possible boot-time SMP configuration: 900 * Find and reserve possible boot-time SMP configuration:
937 */ 901 */
@@ -939,6 +903,26 @@ void __init setup_arch(char **cmdline_p)
939 903
940 reserve_ibft_region(); 904 reserve_ibft_region();
941 905
906 /*
907 * Need to conclude brk, before memblock_x86_fill()
908 * it could use memblock_find_in_range, could overlap with
909 * brk area.
910 */
911 reserve_brk();
912
913 memblock.current_limit = get_max_mapped();
914 memblock_x86_fill();
915
916 /* preallocate 4k for mptable mpc */
917 early_reserve_e820_mpc_new();
918
919#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
920 setup_bios_corruption_check();
921#endif
922
923 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
924 max_pfn_mapped<<PAGE_SHIFT);
925
942 reserve_trampoline_memory(); 926 reserve_trampoline_memory();
943 927
944#ifdef CONFIG_ACPI_SLEEP 928#ifdef CONFIG_ACPI_SLEEP
@@ -962,6 +946,7 @@ void __init setup_arch(char **cmdline_p)
962 max_low_pfn = max_pfn; 946 max_low_pfn = max_pfn;
963 } 947 }
964#endif 948#endif
949 memblock.current_limit = get_max_mapped();
965 950
966 /* 951 /*
967 * NOTE: On x86-32, only from this point on, fixmaps are ready for use. 952 * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
@@ -1000,10 +985,7 @@ void __init setup_arch(char **cmdline_p)
1000#endif 985#endif
1001 986
1002 initmem_init(0, max_pfn, acpi, k8); 987 initmem_init(0, max_pfn, acpi, k8);
1003#ifndef CONFIG_NO_BOOTMEM 988 memblock_find_dma_reserve();
1004 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
1005#endif
1006
1007 dma32_reserve_bootmem(); 989 dma32_reserve_bootmem();
1008 990
1009#ifdef CONFIG_KVM_CLOCK 991#ifdef CONFIG_KVM_CLOCK
@@ -1014,7 +996,12 @@ void __init setup_arch(char **cmdline_p)
1014 paging_init(); 996 paging_init();
1015 x86_init.paging.pagetable_setup_done(swapper_pg_dir); 997 x86_init.paging.pagetable_setup_done(swapper_pg_dir);
1016 998
1017 setup_trampoline_page_table(); 999#ifdef CONFIG_X86_32
1000 /* sync back kernel address range */
1001 clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
1002 swapper_pg_dir + KERNEL_PGD_BOUNDARY,
1003 KERNEL_PGD_PTRS);
1004#endif
1018 1005
1019 tboot_probe(); 1006 tboot_probe();
1020 1007
@@ -1071,6 +1058,10 @@ void __init setup_arch(char **cmdline_p)
1071 x86_init.oem.banner(); 1058 x86_init.oem.banner();
1072 1059
1073 mcheck_init(); 1060 mcheck_init();
1061
1062 local_irq_save(flags);
1063 arch_init_ideal_nop5();
1064 local_irq_restore(flags);
1074} 1065}
1075 1066
1076#ifdef CONFIG_X86_32 1067#ifdef CONFIG_X86_32