]> Pileus Git - ~andy/linux/blobdiff - arch/x86_64/kernel/setup.c
[PATCH] x86_64: Fix the additional_cpus=.. option
[~andy/linux] / arch / x86_64 / kernel / setup.c
index ee3a5cd7d8d9d48d8825a0268d279fb679b7635a..5de7eaf5d97cd678025e520cb5d5b2a3041508b5 100644 (file)
@@ -44,6 +44,8 @@
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
 #include <linux/cpufreq.h>
+#include <linux/dmi.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -62,7 +64,9 @@
 #include <asm/setup.h>
 #include <asm/mach_apic.h>
 #include <asm/numa.h>
+#include <asm/swiotlb.h>
 #include <asm/sections.h>
+#include <asm/gart-mapping.h>
 
 /*
  * Machine setup..
@@ -87,15 +91,9 @@ int bootloader_type;
 
 unsigned long saved_video_mode;
 
-#ifdef CONFIG_SWIOTLB
-int swiotlb;
-EXPORT_SYMBOL(swiotlb);
-#endif
-
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 struct sys_desc_table_struct {
        unsigned short length;
@@ -278,10 +276,6 @@ static __init void parse_cmdline_early (char ** cmdline_p)
        int len = 0;
        int userdef = 0;
 
-       /* Save unparsed command line copy for /proc/cmdline */
-       memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
-       saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
        for (;;) {
                if (c != ' ') 
                        goto next_char; 
@@ -348,10 +342,14 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                    !memcmp(from, "disableapic", 11))
                        disable_apic = 1;
 
-               if (!memcmp(from, "noapic", 6)) 
+               /* Don't confuse with noapictimer */
+               if (!memcmp(from, "noapic", 6) &&
+                       (from[6] == ' ' || from[6] == 0))
                        skip_ioapic_setup = 1;
 
-               if (!memcmp(from, "apic", 4)) { 
+               /* Make sure to not confuse with apic= */
+               if (!memcmp(from, "apic", 4) &&
+                       (from[4] == ' ' || from[4] == 0)) {
                        skip_ioapic_setup = 0;
                        ioapic_force = 1;
                }
@@ -386,11 +384,9 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                        numa_setup(from+5); 
 #endif
 
-#ifdef CONFIG_GART_IOMMU 
                if (!memcmp(from,"iommu=",6)) { 
                        iommu_setup(from+6); 
                }
-#endif
 
                if (!memcmp(from,"oops=panic", 10))
                        panic_on_oops = 1;
@@ -427,6 +423,12 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                else if(!memcmp(from, "elfcorehdr=", 11))
                        elfcorehdr_addr = memparse(from+11, &from);
 #endif
+
+#ifdef CONFIG_SMP
+               else if (!memcmp(from, "additional_cpus=", 16))
+                       setup_additional_cpus(from+16);
+#endif
+
        next_char:
                c = *(from++);
                if (!c)
@@ -479,6 +481,8 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
      k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 }; 
 
+extern char __vsyscall_0;
+
 /* Replace instructions with better alternatives for this CPU type.
 
    This runs before SMP is initialized to avoid SMP problems with
@@ -490,11 +494,17 @@ void apply_alternatives(void *start, void *end)
        struct alt_instr *a; 
        int diff, i, k;
        for (a = start; (void *)a < end; a++) { 
+               u8 *instr;
+
                if (!boot_cpu_has(a->cpuid))
                        continue;
 
                BUG_ON(a->replacementlen > a->instrlen); 
-               __inline_memcpy(a->instr, a->replacement, a->replacementlen); 
+               instr = a->instr;
+               /* vsyscall code is not mapped yet. resolve it manually. */
+               if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END)
+                       instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0));
+               __inline_memcpy(instr, a->replacement, a->replacementlen);
                diff = a->instrlen - a->replacementlen; 
 
                /* Pad the rest with nops */
@@ -502,7 +512,7 @@ void apply_alternatives(void *start, void *end)
                        k = diff;
                        if (k > ASM_NOP_MAX)
                                k = ASM_NOP_MAX;
-                       __inline_memcpy(a->instr + i, k8_nops[k], k); 
+                       __inline_memcpy(instr + i, k8_nops[k], k);
                } 
        }
 } 
@@ -567,7 +577,6 @@ void __init setup_arch(char **cmdline_p)
        unsigned long kernel_end;
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-       drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
        edid_info = EDID_INFO;
        saved_video_mode = SAVED_VIDEO_MODE;
@@ -706,6 +715,8 @@ void __init setup_arch(char **cmdline_p)
        acpi_boot_init();
 #endif
 
+       init_cpu_to_node();
+
 #ifdef CONFIG_X86_LOCAL_APIC
        /*
         * get boot-time SMP configuration:
@@ -734,7 +745,7 @@ void __init setup_arch(char **cmdline_p)
        e820_setup_gap();
 
 #ifdef CONFIG_GART_IOMMU
-       iommu_hole_init();
+       iommu_hole_init();
 #endif
 
 #ifdef CONFIG_VT
@@ -870,7 +881,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
        int r;
-       int level;
+       unsigned level;
 
 #ifdef CONFIG_SMP
        unsigned long value;
@@ -893,10 +904,10 @@ static int __init init_amd(struct cpuinfo_x86 *c)
           3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
        clear_bit(0*32+31, &c->x86_capability);
        
-       /* C-stepping K8? */
+       /* On C+ stepping K8 rep microcode works well for copy/memset */
        level = cpuid_eax(1);
-       if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
-               set_bit(X86_FEATURE_K8_C, &c->x86_capability);
+       if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
+               set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
 
        r = get_model_name(c);
        if (!r) { 
@@ -1035,6 +1046,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
        if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
            (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
+       set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
        c->x86_max_cores = intel_num_cpu_cores(c);
 
        srat_detect_node();
@@ -1390,3 +1402,11 @@ struct seq_operations cpuinfo_op = {
        .stop = c_stop,
        .show = show_cpuinfo,
 };
+
+static int __init run_dmi_scan(void)
+{
+       dmi_scan_machine();
+       return 0;
+}
+core_initcall(run_dmi_scan);
+