diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-12-09 01:14:38 -0500 |
commit | bcd6acd51f3d4d1ada201e9bc5c40a31d6d80c71 (patch) | |
tree | 2f6dffd2d3e4dd67355a224de7e7a960335a92fd /arch/x86/kernel/setup.c | |
parent | 11c34c7deaeeebcee342cbc35e1bb2a6711b2431 (diff) | |
parent | 3ff6a468b45b5dfeb0e903e56f4eb27d34b2437c (diff) |
Merge commit 'origin/master' into next
Conflicts:
include/linux/kvm.h
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r-- | arch/x86/kernel/setup.c | 113 |
1 files changed, 48 insertions, 65 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 2a34f9c5be2..946a311a25c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -106,9 +106,11 @@ | |||
106 | #include <asm/percpu.h> | 106 | #include <asm/percpu.h> |
107 | #include <asm/topology.h> | 107 | #include <asm/topology.h> |
108 | #include <asm/apicdef.h> | 108 | #include <asm/apicdef.h> |
109 | #include <asm/k8.h> | ||
109 | #ifdef CONFIG_X86_64 | 110 | #ifdef CONFIG_X86_64 |
110 | #include <asm/numa_64.h> | 111 | #include <asm/numa_64.h> |
111 | #endif | 112 | #endif |
113 | #include <asm/mce.h> | ||
112 | 114 | ||
113 | /* | 115 | /* |
114 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. | 116 | * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries. |
@@ -247,7 +249,7 @@ EXPORT_SYMBOL(edd); | |||
247 | * from boot_params into a safe place. | 249 | * from boot_params into a safe place. |
248 | * | 250 | * |
249 | */ | 251 | */ |
250 | static inline void copy_edd(void) | 252 | static inline void __init copy_edd(void) |
251 | { | 253 | { |
252 | memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer, | 254 | memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer, |
253 | sizeof(edd.mbr_signature)); | 255 | sizeof(edd.mbr_signature)); |
@@ -256,7 +258,7 @@ static inline void copy_edd(void) | |||
256 | edd.edd_info_nr = boot_params.eddbuf_entries; | 258 | edd.edd_info_nr = boot_params.eddbuf_entries; |
257 | } | 259 | } |
258 | #else | 260 | #else |
259 | static inline void copy_edd(void) | 261 | static inline void __init copy_edd(void) |
260 | { | 262 | { |
261 | } | 263 | } |
262 | #endif | 264 | #endif |
@@ -486,42 +488,11 @@ static void __init reserve_early_setup_data(void) | |||
486 | 488 | ||
487 | #ifdef CONFIG_KEXEC | 489 | #ifdef CONFIG_KEXEC |
488 | 490 | ||
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) | 491 | static inline unsigned long long get_total_mem(void) |
518 | { | 492 | { |
519 | unsigned long long total; | 493 | unsigned long long total; |
520 | 494 | ||
521 | total = max_low_pfn - min_low_pfn; | 495 | total = max_pfn - min_low_pfn; |
522 | #ifdef CONFIG_HIGHMEM | ||
523 | total += highend_pfn - highstart_pfn; | ||
524 | #endif | ||
525 | 496 | ||
526 | return total << PAGE_SHIFT; | 497 | return total << PAGE_SHIFT; |
527 | } | 498 | } |
@@ -541,21 +512,25 @@ static void __init reserve_crashkernel(void) | |||
541 | 512 | ||
542 | /* 0 means: find the address automatically */ | 513 | /* 0 means: find the address automatically */ |
543 | if (crash_base <= 0) { | 514 | if (crash_base <= 0) { |
544 | crash_base = find_and_reserve_crashkernel(crash_size); | 515 | const unsigned long long alignment = 16<<20; /* 16M */ |
516 | |||
517 | crash_base = find_e820_area(alignment, ULONG_MAX, crash_size, | ||
518 | alignment); | ||
545 | if (crash_base == -1ULL) { | 519 | if (crash_base == -1ULL) { |
546 | pr_info("crashkernel reservation failed. " | 520 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
547 | "No suitable area found.\n"); | ||
548 | return; | 521 | return; |
549 | } | 522 | } |
550 | } else { | 523 | } else { |
551 | ret = reserve_bootmem_generic(crash_base, crash_size, | 524 | unsigned long long start; |
552 | BOOTMEM_EXCLUSIVE); | 525 | |
553 | if (ret < 0) { | 526 | start = find_e820_area(crash_base, ULONG_MAX, crash_size, |
554 | pr_info("crashkernel reservation failed - " | 527 | 1<<20); |
555 | "memory is in use\n"); | 528 | if (start != crash_base) { |
529 | pr_info("crashkernel reservation failed - memory is in use.\n"); | ||
556 | return; | 530 | return; |
557 | } | 531 | } |
558 | } | 532 | } |
533 | reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL"); | ||
559 | 534 | ||
560 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | 535 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " |
561 | "for crashkernel (System RAM: %ldMB)\n", | 536 | "for crashkernel (System RAM: %ldMB)\n", |
@@ -698,6 +673,9 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { | |||
698 | 673 | ||
699 | void __init setup_arch(char **cmdline_p) | 674 | void __init setup_arch(char **cmdline_p) |
700 | { | 675 | { |
676 | int acpi = 0; | ||
677 | int k8 = 0; | ||
678 | |||
701 | #ifdef CONFIG_X86_32 | 679 | #ifdef CONFIG_X86_32 |
702 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 680 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
703 | visws_early_detect(); | 681 | visws_early_detect(); |
@@ -790,21 +768,18 @@ void __init setup_arch(char **cmdline_p) | |||
790 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 768 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
791 | *cmdline_p = command_line; | 769 | *cmdline_p = command_line; |
792 | 770 | ||
793 | #ifdef CONFIG_X86_64 | ||
794 | /* | 771 | /* |
795 | * Must call this twice: Once just to detect whether hardware doesn't | 772 | * x86_configure_nx() is called before parse_early_param() to detect |
796 | * support NX (so that the early EHCI debug console setup can safely | 773 | * whether hardware doesn't support NX (so that the early EHCI debug |
797 | * call set_fixmap(), and then again after parsing early parameters to | 774 | * console setup can safely call set_fixmap()). It may then be called |
798 | * honor the respective command line option. | 775 | * again from within noexec_setup() during parsing early parameters |
776 | * to honor the respective command line option. | ||
799 | */ | 777 | */ |
800 | check_efer(); | 778 | x86_configure_nx(); |
801 | #endif | ||
802 | 779 | ||
803 | parse_early_param(); | 780 | parse_early_param(); |
804 | 781 | ||
805 | #ifdef CONFIG_X86_64 | 782 | x86_report_nx(); |
806 | check_efer(); | ||
807 | #endif | ||
808 | 783 | ||
809 | /* Must be before kernel pagetables are setup */ | 784 | /* Must be before kernel pagetables are setup */ |
810 | vmi_activate(); | 785 | vmi_activate(); |
@@ -900,6 +875,13 @@ void __init setup_arch(char **cmdline_p) | |||
900 | 875 | ||
901 | reserve_brk(); | 876 | reserve_brk(); |
902 | 877 | ||
878 | #ifdef CONFIG_ACPI_SLEEP | ||
879 | /* | ||
880 | * Reserve low memory region for sleep support. | ||
881 | * even before init_memory_mapping | ||
882 | */ | ||
883 | acpi_reserve_wakeup_memory(); | ||
884 | #endif | ||
903 | init_gbpages(); | 885 | init_gbpages(); |
904 | 886 | ||
905 | /* max_pfn_mapped is updated here */ | 887 | /* max_pfn_mapped is updated here */ |
@@ -926,6 +908,8 @@ void __init setup_arch(char **cmdline_p) | |||
926 | 908 | ||
927 | reserve_initrd(); | 909 | reserve_initrd(); |
928 | 910 | ||
911 | reserve_crashkernel(); | ||
912 | |||
929 | vsmp_init(); | 913 | vsmp_init(); |
930 | 914 | ||
931 | io_delay_init(); | 915 | io_delay_init(); |
@@ -937,27 +921,24 @@ void __init setup_arch(char **cmdline_p) | |||
937 | 921 | ||
938 | early_acpi_boot_init(); | 922 | early_acpi_boot_init(); |
939 | 923 | ||
924 | /* | ||
925 | * Find and reserve possible boot-time SMP configuration: | ||
926 | */ | ||
927 | find_smp_config(); | ||
928 | |||
940 | #ifdef CONFIG_ACPI_NUMA | 929 | #ifdef CONFIG_ACPI_NUMA |
941 | /* | 930 | /* |
942 | * Parse SRAT to discover nodes. | 931 | * Parse SRAT to discover nodes. |
943 | */ | 932 | */ |
944 | acpi_numa_init(); | 933 | acpi = acpi_numa_init(); |
945 | #endif | 934 | #endif |
946 | 935 | ||
947 | initmem_init(0, max_pfn); | 936 | #ifdef CONFIG_K8_NUMA |
948 | 937 | if (!acpi) | |
949 | #ifdef CONFIG_ACPI_SLEEP | 938 | k8 = !k8_numa_init(0, max_pfn); |
950 | /* | ||
951 | * Reserve low memory region for sleep support. | ||
952 | */ | ||
953 | acpi_reserve_bootmem(); | ||
954 | #endif | 939 | #endif |
955 | /* | ||
956 | * Find and reserve possible boot-time SMP configuration: | ||
957 | */ | ||
958 | find_smp_config(); | ||
959 | 940 | ||
960 | reserve_crashkernel(); | 941 | initmem_init(0, max_pfn, acpi, k8); |
961 | 942 | ||
962 | #ifdef CONFIG_X86_64 | 943 | #ifdef CONFIG_X86_64 |
963 | /* | 944 | /* |
@@ -1031,6 +1012,8 @@ void __init setup_arch(char **cmdline_p) | |||
1031 | #endif | 1012 | #endif |
1032 | #endif | 1013 | #endif |
1033 | x86_init.oem.banner(); | 1014 | x86_init.oem.banner(); |
1015 | |||
1016 | mcheck_init(); | ||
1034 | } | 1017 | } |
1035 | 1018 | ||
1036 | #ifdef CONFIG_X86_32 | 1019 | #ifdef CONFIG_X86_32 |