diff options
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r-- | arch/x86/kernel/setup.c | 106 |
1 files changed, 43 insertions, 63 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 82e88cdda9bc..946a311a25c9 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -106,6 +106,7 @@ | |||
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 |
@@ -487,42 +488,11 @@ static void __init reserve_early_setup_data(void) | |||
487 | 488 | ||
488 | #ifdef CONFIG_KEXEC | 489 | #ifdef CONFIG_KEXEC |
489 | 490 | ||
490 | /** | ||
491 | * Reserve @size bytes of crashkernel memory at any suitable offset. | ||
492 | * | ||
493 | * @size: Size of the crashkernel memory to reserve. | ||
494 | * Returns the base address on success, and -1ULL on failure. | ||
495 | */ | ||
496 | static | ||
497 | unsigned long long __init find_and_reserve_crashkernel(unsigned long long size) | ||
498 | { | ||
499 | const unsigned long long alignment = 16<<20; /* 16M */ | ||
500 | unsigned long long start = 0LL; | ||
501 | |||
502 | while (1) { | ||
503 | int ret; | ||
504 | |||
505 | start = find_e820_area(start, ULONG_MAX, size, alignment); | ||
506 | if (start == -1ULL) | ||
507 | return start; | ||
508 | |||
509 | /* try to reserve it */ | ||
510 | ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE); | ||
511 | if (ret >= 0) | ||
512 | return start; | ||
513 | |||
514 | start += alignment; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | static inline unsigned long long get_total_mem(void) | 491 | static inline unsigned long long get_total_mem(void) |
519 | { | 492 | { |
520 | unsigned long long total; | 493 | unsigned long long total; |
521 | 494 | ||
522 | total = max_low_pfn - min_low_pfn; | 495 | total = max_pfn - min_low_pfn; |
523 | #ifdef CONFIG_HIGHMEM | ||
524 | total += highend_pfn - highstart_pfn; | ||
525 | #endif | ||
526 | 496 | ||
527 | return total << PAGE_SHIFT; | 497 | return total << PAGE_SHIFT; |
528 | } | 498 | } |
@@ -542,21 +512,25 @@ static void __init reserve_crashkernel(void) | |||
542 | 512 | ||
543 | /* 0 means: find the address automatically */ | 513 | /* 0 means: find the address automatically */ |
544 | if (crash_base <= 0) { | 514 | if (crash_base <= 0) { |
545 | 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); | ||
546 | if (crash_base == -1ULL) { | 519 | if (crash_base == -1ULL) { |
547 | pr_info("crashkernel reservation failed. " | 520 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
548 | "No suitable area found.\n"); | ||
549 | return; | 521 | return; |
550 | } | 522 | } |
551 | } else { | 523 | } else { |
552 | ret = reserve_bootmem_generic(crash_base, crash_size, | 524 | unsigned long long start; |
553 | BOOTMEM_EXCLUSIVE); | 525 | |
554 | if (ret < 0) { | 526 | start = find_e820_area(crash_base, ULONG_MAX, crash_size, |
555 | pr_info("crashkernel reservation failed - " | 527 | 1<<20); |
556 | "memory is in use\n"); | 528 | if (start != crash_base) { |
529 | pr_info("crashkernel reservation failed - memory is in use.\n"); | ||
557 | return; | 530 | return; |
558 | } | 531 | } |
559 | } | 532 | } |
533 | reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL"); | ||
560 | 534 | ||
561 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | 535 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " |
562 | "for crashkernel (System RAM: %ldMB)\n", | 536 | "for crashkernel (System RAM: %ldMB)\n", |
@@ -699,6 +673,9 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { | |||
699 | 673 | ||
700 | void __init setup_arch(char **cmdline_p) | 674 | void __init setup_arch(char **cmdline_p) |
701 | { | 675 | { |
676 | int acpi = 0; | ||
677 | int k8 = 0; | ||
678 | |||
702 | #ifdef CONFIG_X86_32 | 679 | #ifdef CONFIG_X86_32 |
703 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 680 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
704 | visws_early_detect(); | 681 | visws_early_detect(); |
@@ -791,21 +768,18 @@ void __init setup_arch(char **cmdline_p) | |||
791 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 768 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
792 | *cmdline_p = command_line; | 769 | *cmdline_p = command_line; |
793 | 770 | ||
794 | #ifdef CONFIG_X86_64 | ||
795 | /* | 771 | /* |
796 | * Must call this twice: Once just to detect whether hardware doesn't | 772 | * x86_configure_nx() is called before parse_early_param() to detect |
797 | * 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 |
798 | * call set_fixmap(), and then again after parsing early parameters to | 774 | * console setup can safely call set_fixmap()). It may then be called |
799 | * honor the respective command line option. | 775 | * again from within noexec_setup() during parsing early parameters |
776 | * to honor the respective command line option. | ||
800 | */ | 777 | */ |
801 | check_efer(); | 778 | x86_configure_nx(); |
802 | #endif | ||
803 | 779 | ||
804 | parse_early_param(); | 780 | parse_early_param(); |
805 | 781 | ||
806 | #ifdef CONFIG_X86_64 | 782 | x86_report_nx(); |
807 | check_efer(); | ||
808 | #endif | ||
809 | 783 | ||
810 | /* Must be before kernel pagetables are setup */ | 784 | /* Must be before kernel pagetables are setup */ |
811 | vmi_activate(); | 785 | vmi_activate(); |
@@ -901,6 +875,13 @@ void __init setup_arch(char **cmdline_p) | |||
901 | 875 | ||
902 | reserve_brk(); | 876 | reserve_brk(); |
903 | 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 | ||
904 | init_gbpages(); | 885 | init_gbpages(); |
905 | 886 | ||
906 | /* max_pfn_mapped is updated here */ | 887 | /* max_pfn_mapped is updated here */ |
@@ -927,6 +908,8 @@ void __init setup_arch(char **cmdline_p) | |||
927 | 908 | ||
928 | reserve_initrd(); | 909 | reserve_initrd(); |
929 | 910 | ||
911 | reserve_crashkernel(); | ||
912 | |||
930 | vsmp_init(); | 913 | vsmp_init(); |
931 | 914 | ||
932 | io_delay_init(); | 915 | io_delay_init(); |
@@ -938,27 +921,24 @@ void __init setup_arch(char **cmdline_p) | |||
938 | 921 | ||
939 | early_acpi_boot_init(); | 922 | early_acpi_boot_init(); |
940 | 923 | ||
924 | /* | ||
925 | * Find and reserve possible boot-time SMP configuration: | ||
926 | */ | ||
927 | find_smp_config(); | ||
928 | |||
941 | #ifdef CONFIG_ACPI_NUMA | 929 | #ifdef CONFIG_ACPI_NUMA |
942 | /* | 930 | /* |
943 | * Parse SRAT to discover nodes. | 931 | * Parse SRAT to discover nodes. |
944 | */ | 932 | */ |
945 | acpi_numa_init(); | 933 | acpi = acpi_numa_init(); |
946 | #endif | 934 | #endif |
947 | 935 | ||
948 | initmem_init(0, max_pfn); | 936 | #ifdef CONFIG_K8_NUMA |
949 | 937 | if (!acpi) | |
950 | #ifdef CONFIG_ACPI_SLEEP | 938 | k8 = !k8_numa_init(0, max_pfn); |
951 | /* | ||
952 | * Reserve low memory region for sleep support. | ||
953 | */ | ||
954 | acpi_reserve_bootmem(); | ||
955 | #endif | 939 | #endif |
956 | /* | ||
957 | * Find and reserve possible boot-time SMP configuration: | ||
958 | */ | ||
959 | find_smp_config(); | ||
960 | 940 | ||
961 | reserve_crashkernel(); | 941 | initmem_init(0, max_pfn, acpi, k8); |
962 | 942 | ||
963 | #ifdef CONFIG_X86_64 | 943 | #ifdef CONFIG_X86_64 |
964 | /* | 944 | /* |