diff options
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r-- | arch/x86/kernel/setup.c | 123 |
1 files changed, 58 insertions, 65 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index e09f0e2c14b5..f7b8b9894b22 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -73,6 +73,7 @@ | |||
73 | 73 | ||
74 | #include <asm/mtrr.h> | 74 | #include <asm/mtrr.h> |
75 | #include <asm/apic.h> | 75 | #include <asm/apic.h> |
76 | #include <asm/trampoline.h> | ||
76 | #include <asm/e820.h> | 77 | #include <asm/e820.h> |
77 | #include <asm/mpspec.h> | 78 | #include <asm/mpspec.h> |
78 | #include <asm/setup.h> | 79 | #include <asm/setup.h> |
@@ -106,9 +107,11 @@ | |||
106 | #include <asm/percpu.h> | 107 | #include <asm/percpu.h> |
107 | #include <asm/topology.h> | 108 | #include <asm/topology.h> |
108 | #include <asm/apicdef.h> | 109 | #include <asm/apicdef.h> |
110 | #include <asm/k8.h> | ||
109 | #ifdef CONFIG_X86_64 | 111 | #ifdef CONFIG_X86_64 |
110 | #include <asm/numa_64.h> | 112 | #include <asm/numa_64.h> |
111 | #endif | 113 | #endif |
114 | #include <asm/mce.h> | ||
112 | 115 | ||
113 | /* | 116 | /* |
114 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | 117 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. |
@@ -247,7 +250,7 @@ EXPORT_SYMBOL(edd); | |||
247 | * from boot_params into a safe place. | 250 | * from boot_params into a safe place. |
248 | * | 251 | * |
249 | */ | 252 | */ |
250 | static inline void copy_edd(void) | 253 | static inline void __init copy_edd(void) |
251 | { | 254 | { |
252 | memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer, | 255 | memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer, |
253 | sizeof(edd.mbr_signature)); | 256 | sizeof(edd.mbr_signature)); |
@@ -256,7 +259,7 @@ static inline void copy_edd(void) | |||
256 | edd.edd_info_nr = boot_params.eddbuf_entries; | 259 | edd.edd_info_nr = boot_params.eddbuf_entries; |
257 | } | 260 | } |
258 | #else | 261 | #else |
259 | static inline void copy_edd(void) | 262 | static inline void __init copy_edd(void) |
260 | { | 263 | { |
261 | } | 264 | } |
262 | #endif | 265 | #endif |
@@ -486,42 +489,11 @@ static void __init reserve_early_setup_data(void) | |||
486 | 489 | ||
487 | #ifdef CONFIG_KEXEC | 490 | #ifdef CONFIG_KEXEC |
488 | 491 | ||
489 | /** | ||
490 | * Reserve @size bytes of crashkernel memory at any suitable offset. | ||
491 | * | ||
492 | * @size: Size of the crashkernel memory to reserve. | ||
493 | * Returns the base address on success, and -1ULL on failure. | ||
494 | */ | ||
495 | static | ||
496 | unsigned long long __init find_and_reserve_crashkernel(unsigned long long size) | ||
497 | { | ||
498 | const unsigned long long alignment = 16<<20; /* 16M */ | ||
499 | unsigned long long start = 0LL; | ||
500 | |||
501 | while (1) { | ||
502 | int ret; | ||
503 | |||
504 | start = find_e820_area(start, ULONG_MAX, size, alignment); | ||
505 | if (start == -1ULL) | ||
506 | return start; | ||
507 | |||
508 | /* try to reserve it */ | ||
509 | ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE); | ||
510 | if (ret >= 0) | ||
511 | return start; | ||
512 | |||
513 | start += alignment; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static inline unsigned long long get_total_mem(void) | 492 | static inline unsigned long long get_total_mem(void) |
518 | { | 493 | { |
519 | unsigned long long total; | 494 | unsigned long long total; |
520 | 495 | ||
521 | total = max_low_pfn - min_low_pfn; | 496 | total = max_pfn - min_low_pfn; |
522 | #ifdef CONFIG_HIGHMEM | ||
523 | total += highend_pfn - highstart_pfn; | ||
524 | #endif | ||
525 | 497 | ||
526 | return total << PAGE_SHIFT; | 498 | return total << PAGE_SHIFT; |
527 | } | 499 | } |
@@ -541,21 +513,25 @@ static void __init reserve_crashkernel(void) | |||
541 | 513 | ||
542 | /* 0 means: find the address automatically */ | 514 | /* 0 means: find the address automatically */ |
543 | if (crash_base <= 0) { | 515 | if (crash_base <= 0) { |
544 | crash_base = find_and_reserve_crashkernel(crash_size); | 516 | const unsigned long long alignment = 16<<20; /* 16M */ |
517 | |||
518 | crash_base = find_e820_area(alignment, ULONG_MAX, crash_size, | ||
519 | alignment); | ||
545 | if (crash_base == -1ULL) { | 520 | if (crash_base == -1ULL) { |
546 | pr_info("crashkernel reservation failed. " | 521 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
547 | "No suitable area found.\n"); | ||
548 | return; | 522 | return; |
549 | } | 523 | } |
550 | } else { | 524 | } else { |
551 | ret = reserve_bootmem_generic(crash_base, crash_size, | 525 | unsigned long long start; |
552 | BOOTMEM_EXCLUSIVE); | 526 | |
553 | if (ret < 0) { | 527 | start = find_e820_area(crash_base, ULONG_MAX, crash_size, |
554 | pr_info("crashkernel reservation failed - " | 528 | 1<<20); |
555 | "memory is in use\n"); | 529 | if (start != crash_base) { |
530 | pr_info("crashkernel reservation failed - memory is in use.\n"); | ||
556 | return; | 531 | return; |
557 | } | 532 | } |
558 | } | 533 | } |
534 | reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL"); | ||
559 | 535 | ||
560 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | 536 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " |
561 | "for crashkernel (System RAM: %ldMB)\n", | 537 | "for crashkernel (System RAM: %ldMB)\n", |
@@ -660,6 +636,13 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { | |||
660 | }, | 636 | }, |
661 | }, | 637 | }, |
662 | { | 638 | { |
639 | .callback = dmi_low_memory_corruption, | ||
640 | .ident = "Phoenix/MSC BIOS", | ||
641 | .matches = { | ||
642 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix/MSC"), | ||
643 | }, | ||
644 | }, | ||
645 | { | ||
663 | /* | 646 | /* |
664 | * AMI BIOS with low memory corruption was found on Intel DG45ID board. | 647 | * AMI BIOS with low memory corruption was found on Intel DG45ID board. |
665 | * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will | 648 | * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will |
@@ -691,6 +674,9 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { | |||
691 | 674 | ||
692 | void __init setup_arch(char **cmdline_p) | 675 | void __init setup_arch(char **cmdline_p) |
693 | { | 676 | { |
677 | int acpi = 0; | ||
678 | int k8 = 0; | ||
679 | |||
694 | #ifdef CONFIG_X86_32 | 680 | #ifdef CONFIG_X86_32 |
695 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 681 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
696 | visws_early_detect(); | 682 | visws_early_detect(); |
@@ -783,21 +769,18 @@ void __init setup_arch(char **cmdline_p) | |||
783 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 769 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
784 | *cmdline_p = command_line; | 770 | *cmdline_p = command_line; |
785 | 771 | ||
786 | #ifdef CONFIG_X86_64 | ||
787 | /* | 772 | /* |
788 | * Must call this twice: Once just to detect whether hardware doesn't | 773 | * x86_configure_nx() is called before parse_early_param() to detect |
789 | * support NX (so that the early EHCI debug console setup can safely | 774 | * whether hardware doesn't support NX (so that the early EHCI debug |
790 | * call set_fixmap(), and then again after parsing early parameters to | 775 | * console setup can safely call set_fixmap()). It may then be called |
791 | * honor the respective command line option. | 776 | * again from within noexec_setup() during parsing early parameters |
777 | * to honor the respective command line option. | ||
792 | */ | 778 | */ |
793 | check_efer(); | 779 | x86_configure_nx(); |
794 | #endif | ||
795 | 780 | ||
796 | parse_early_param(); | 781 | parse_early_param(); |
797 | 782 | ||
798 | #ifdef CONFIG_X86_64 | 783 | x86_report_nx(); |
799 | check_efer(); | ||
800 | #endif | ||
801 | 784 | ||
802 | /* Must be before kernel pagetables are setup */ | 785 | /* Must be before kernel pagetables are setup */ |
803 | vmi_activate(); | 786 | vmi_activate(); |
@@ -893,6 +876,20 @@ void __init setup_arch(char **cmdline_p) | |||
893 | 876 | ||
894 | reserve_brk(); | 877 | reserve_brk(); |
895 | 878 | ||
879 | /* | ||
880 | * Find and reserve possible boot-time SMP configuration: | ||
881 | */ | ||
882 | find_smp_config(); | ||
883 | |||
884 | reserve_trampoline_memory(); | ||
885 | |||
886 | #ifdef CONFIG_ACPI_SLEEP | ||
887 | /* | ||
888 | * Reserve low memory region for sleep support. | ||
889 | * even before init_memory_mapping | ||
890 | */ | ||
891 | acpi_reserve_wakeup_memory(); | ||
892 | #endif | ||
896 | init_gbpages(); | 893 | init_gbpages(); |
897 | 894 | ||
898 | /* max_pfn_mapped is updated here */ | 895 | /* max_pfn_mapped is updated here */ |
@@ -919,6 +916,8 @@ void __init setup_arch(char **cmdline_p) | |||
919 | 916 | ||
920 | reserve_initrd(); | 917 | reserve_initrd(); |
921 | 918 | ||
919 | reserve_crashkernel(); | ||
920 | |||
922 | vsmp_init(); | 921 | vsmp_init(); |
923 | 922 | ||
924 | io_delay_init(); | 923 | io_delay_init(); |
@@ -934,23 +933,15 @@ void __init setup_arch(char **cmdline_p) | |||
934 | /* | 933 | /* |
935 | * Parse SRAT to discover nodes. | 934 | * Parse SRAT to discover nodes. |
936 | */ | 935 | */ |
937 | acpi_numa_init(); | 936 | acpi = acpi_numa_init(); |
938 | #endif | 937 | #endif |
939 | 938 | ||
940 | initmem_init(0, max_pfn); | 939 | #ifdef CONFIG_K8_NUMA |
941 | 940 | if (!acpi) | |
942 | #ifdef CONFIG_ACPI_SLEEP | 941 | k8 = !k8_numa_init(0, max_pfn); |
943 | /* | ||
944 | * Reserve low memory region for sleep support. | ||
945 | */ | ||
946 | acpi_reserve_bootmem(); | ||
947 | #endif | 942 | #endif |
948 | /* | ||
949 | * Find and reserve possible boot-time SMP configuration: | ||
950 | */ | ||
951 | find_smp_config(); | ||
952 | 943 | ||
953 | reserve_crashkernel(); | 944 | initmem_init(0, max_pfn, acpi, k8); |
954 | 945 | ||
955 | #ifdef CONFIG_X86_64 | 946 | #ifdef CONFIG_X86_64 |
956 | /* | 947 | /* |
@@ -1024,6 +1015,8 @@ void __init setup_arch(char **cmdline_p) | |||
1024 | #endif | 1015 | #endif |
1025 | #endif | 1016 | #endif |
1026 | x86_init.oem.banner(); | 1017 | x86_init.oem.banner(); |
1018 | |||
1019 | mcheck_init(); | ||
1027 | } | 1020 | } |
1028 | 1021 | ||
1029 | #ifdef CONFIG_X86_32 | 1022 | #ifdef CONFIG_X86_32 |