x86/mm: Add the 'nopcid' boot option to turn off PCID
[pandora-kernel.git] / arch / x86 / kernel / cpu / common.c
index aa003b1..d0619ad 100644 (file)
@@ -140,6 +140,8 @@ EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
 static int __init x86_xsave_setup(char *s)
 {
+       if (strlen(s))
+               return 0;
        setup_clear_cpu_cap(X86_FEATURE_XSAVE);
        setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
        return 1;
@@ -153,6 +155,40 @@ static int __init x86_xsaveopt_setup(char *s)
 }
 __setup("noxsaveopt", x86_xsaveopt_setup);
 
+#ifdef CONFIG_X86_64
+static int __init x86_pcid_setup(char *s)
+{
+       /* require an exact match without trailing characters */
+       if (strlen(s))
+               return 0;
+
+       /* do not emit a message if the feature is not present */
+       if (!boot_cpu_has(X86_FEATURE_PCID))
+               return 1;
+
+       setup_clear_cpu_cap(X86_FEATURE_PCID);
+       pr_info("nopcid: PCID feature disabled\n");
+       return 1;
+}
+__setup("nopcid", x86_pcid_setup);
+#endif
+
+static int __init x86_noinvpcid_setup(char *s)
+{
+       /* noinvpcid doesn't accept parameters */
+       if (s)
+               return -EINVAL;
+
+       /* do not emit a message if the feature is not present */
+       if (!boot_cpu_has(X86_FEATURE_INVPCID))
+               return 0;
+
+       setup_clear_cpu_cap(X86_FEATURE_INVPCID);
+       pr_info("noinvpcid: INVPCID feature disabled\n");
+       return 0;
+}
+early_param("noinvpcid", x86_noinvpcid_setup);
+
 #ifdef CONFIG_X86_32
 static int cachesize_override __cpuinitdata = -1;
 static int disable_x86_serial_nr __cpuinitdata = 1;
@@ -676,9 +712,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
        if (this_cpu->c_early_init)
                this_cpu->c_early_init(c);
 
-#ifdef CONFIG_SMP
        c->cpu_index = 0;
-#endif
        filter_cpuid_features(c, false);
 
        setup_smep(c);
@@ -764,10 +798,7 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
                c->apicid = c->initial_apicid;
 # endif
 #endif
-
-#ifdef CONFIG_X86_HT
                c->phys_proc_id = c->initial_apicid;
-#endif
        }
 
        setup_smep(c);
@@ -921,6 +952,11 @@ void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
        BUG_ON(c == &boot_cpu_data);
        identify_cpu(c);
 #ifdef CONFIG_X86_32
+       /*
+        * Regardless of whether PCID is enumerated, the SDM says
+        * that it can't be enabled in 32-bit mode.
+        */
+       clear_cpu_cap(c, X86_FEATURE_PCID);
        enable_sep_cpu();
 #endif
        mtrr_ap_init();
@@ -1015,7 +1051,7 @@ static __init int setup_disablecpuid(char *arg)
 {
        int bit;
 
-       if (get_option(&arg, &bit) && bit < NCAPINTS*32)
+       if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
                setup_clear_cpu_cap(bit);
        else
                return 0;
@@ -1228,7 +1264,7 @@ void __cpuinit cpu_init(void)
        load_sp0(t, &current->thread);
        set_tss_desc(cpu, t);
        load_TR_desc();
-       load_LDT(&init_mm.context);
+       load_mm_ldt(&init_mm);
 
        clear_all_debug_regs();
        dbg_restore_debug_regs();
@@ -1276,7 +1312,7 @@ void __cpuinit cpu_init(void)
        load_sp0(t, thread);
        set_tss_desc(cpu, t);
        load_TR_desc();
-       load_LDT(&init_mm.context);
+       load_mm_ldt(&init_mm);
 
        t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);