#include <linux/bootmem.h>#include <linux/linkage.h>#include <linux/bitops.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/percpu.h>#include <linux/string.h>#include <linux/delay.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/kgdb.h>#include <linux/smp.h>#include <linux/io.h> #include <asm/stackprotector.h>#include <asm/perf_event.h>#include <asm/mmu_context.h>#include <asm/archrandom.h>#include <asm/hypervisor.h>#include <asm/processor.h>#include <asm/debugreg.h>#include <asm/sections.h>#include <linux/topology.h>#include <linux/cpumask.h>#include <asm/pgtable.h>#include <linux/atomic.h>#include <asm/proto.h>#include <asm/setup.h>#include <asm/apic.h>#include <asm/desc.h>#include <asm/i387.h>#include <asm/fpu-internal.h>#include <asm/mtrr.h>#include <linux/numa.h>#include <asm/asm.h>#include <asm/cpu.h>#include <asm/mce.h>#include <asm/msr.h>#include <asm/pat.h>#include <asm/microcode.h>#include <asm/microcode_intel.h> #ifdef CONFIG_X86_LOCAL_APIC#include <asm/uv/uv.h>#endif #include "cpu.h" /* all of these masks are initialized in setup_cpu_local_masks() */cpumask_var_t cpu_initialized_mask;cpumask_var_t cpu_callout_mask;cpumask_var_t cpu_callin_mask; /* representing cpus for which sibling maps can be computed */cpumask_var_t cpu_sibling_setup_mask; /* correctly size the local cpu masks */void __init setup_cpu_local_masks(void){ alloc_bootmem_cpumask_var(&cpu_initialized_mask); alloc_bootmem_cpumask_var(&cpu_callin_mask); alloc_bootmem_cpumask_var(&cpu_callout_mask); alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);} static void default_init(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_64 cpu_detect_cache_sizes(c);#else /* Not much we can do here... */ /* Check if at least it has cpuid */ if (c->cpuid_level == -1) { /* No cpuid. It must be an ancient CPU */ if (c->x86 == 4) strcpy(c->x86_model_id, "486"); else if (c->x86 == 3) strcpy(c->x86_model_id, "386"); }#endif} static const struct cpu_dev default_cpu = { .c_init = default_init, .c_vendor = "Unknown", .c_x86_vendor = X86_VENDOR_UNKNOWN,}; static const struct cpu_dev *this_cpu = &default_cpu; DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {#ifdef CONFIG_X86_64 /* * We need valid kernel segments for data and code in long mode too * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout * * TLS descriptors are currently at a different place compared to i386. * Hopefully nobody expects them at a fixed place (Wine?) */ [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),#else [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff), /* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ /* 32-bit code */ [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), /* 16-bit code */ [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0), /* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ /* 32-bit code */ [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), /* 16-bit code */ [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), /* data */ [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff), [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), GDT_STACK_CANARY_INIT#endif} };EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); static int __init x86_xsave_setup(char *s){ setup_clear_cpu_cap(X86_FEATURE_XSAVE); setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); setup_clear_cpu_cap(X86_FEATURE_AVX); setup_clear_cpu_cap(X86_FEATURE_AVX2); return 1;}__setup("noxsave", x86_xsave_setup); static int __init x86_xsaveopt_setup(char *s){ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); return 1;}__setup("noxsaveopt", x86_xsaveopt_setup); #ifdef CONFIG_X86_32static int cachesize_override = -1;static int disable_x86_serial_nr = 1; static int __init cachesize_setup(char *str){ get_option(&str, &cachesize_override); return 1;}__setup("cachesize=", cachesize_setup); static int __init x86_fxsr_setup(char *s){ setup_clear_cpu_cap(X86_FEATURE_FXSR); setup_clear_cpu_cap(X86_FEATURE_XMM); return 1;}__setup("nofxsr", x86_fxsr_setup); static int __init x86_sep_setup(char *s){ setup_clear_cpu_cap(X86_FEATURE_SEP); return 1;}__setup("nosep", x86_sep_setup); /* Standard macro to see if a specific flag is changeable */static inline int flag_is_changeable_p(u32 flag){ u32 f1, f2; /* * Cyrix and IDT cpus allow disabling of CPUID * so the code below may return different results * when it is executed before and after enabling * the CPUID. Add "volatile" to not allow gcc to * optimize the subsequent calls to this function. */ asm volatile ("pushfl \n\t" "pushfl \n\t" "popl %0 \n\t" "movl %0, %1 \n\t" "xorl %2, %0 \n\t" "pushl %0 \n\t" "popfl \n\t" "pushfl \n\t" "popl %0 \n\t" "popfl \n\t" : "=&r" (f1), "=&r" (f2) : "ir" (flag)); return ((f1^f2) & flag) != 0;} /* Probe for the CPUID instruction */int have_cpuid_p(void){ return flag_is_changeable_p(X86_EFLAGS_ID);} static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c){ unsigned long lo, hi; if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr) return; /* Disable processor serial number: */ rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi); lo |= 0x200000; wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi); printk(KERN_NOTICE "CPU serial number disabled.\n"); clear_cpu_cap(c, X86_FEATURE_PN); /* Disabling the serial number may affect the cpuid level */ c->cpuid_level = cpuid_eax(0);} static int __init x86_serial_nr_setup(char *s){ disable_x86_serial_nr = 0; return 1;}__setup("serialnumber", x86_serial_nr_setup);#elsestatic inline int flag_is_changeable_p(u32 flag){ return 1;}static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c){}#endif static __init int setup_disable_smep(char *arg){ setup_clear_cpu_cap(X86_FEATURE_SMEP); return 1;}__setup("nosmep", setup_disable_smep); static __always_inline void setup_smep(struct cpuinfo_x86 *c){ if (cpu_has(c, X86_FEATURE_SMEP)) set_in_cr4(X86_CR4_SMEP);} static __init int setup_disable_smap(char *arg){ setup_clear_cpu_cap(X86_FEATURE_SMAP); return 1;}__setup("nosmap", setup_disable_smap); static __always_inline void setup_smap(struct cpuinfo_x86 *c){ unsigned long eflags; /* This should have been cleared long ago */ raw_local_save_flags(eflags); BUG_ON(eflags & X86_EFLAGS_AC); if (cpu_has(c, X86_FEATURE_SMAP)) set_in_cr4(X86_CR4_SMAP);} /* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization * software. Add those features to this table to auto-disable them. */struct cpuid_dependent_feature { u32 feature; u32 level;}; static const struct cpuid_dependent_featurecpuid_dependent_features[] = { { X86_FEATURE_MWAIT, 0x00000005 }, { X86_FEATURE_DCA, 0x00000009 }, { X86_FEATURE_XSAVE, 0x0000000d }, { 0, 0 }}; static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn){ const struct cpuid_dependent_feature *df; for (df = cpuid_dependent_features; df->feature; df++) { if (!cpu_has(c, df->feature)) continue; /* * Note: cpuid_level is set to -1 if unavailable, but * extended_extended_level is set to 0 if unavailable * and the legitimate extended levels are all negative * when signed; hence the weird messing around with * signs here... */ if (!((s32)df->level < 0 ? (u32)df->level > (u32)c->extended_cpuid_level : (s32)df->level > (s32)c->cpuid_level)) continue; clear_cpu_cap(c, df->feature); if (!warn) continue; printk(KERN_WARNING "CPU: CPU feature %s disabled, no CPUID level 0x%x\n", x86_cap_flags[df->feature], df->level); }} /* * Naming convention should be: <Name> [(<Codename>)] * This table only is used unless init_<vendor>() below doesn't set it; * in particular, if CPUID levels 0x80000002..4 are supported, this * isn't used */ /* Look up CPU names by table lookup. */static const char *table_lookup_model(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_32 const struct legacy_cpu_model_info *info; if (c->x86_model >= 16) return NULL; /* Range check */ if (!this_cpu) return NULL; info = this_cpu->legacy_models; while (info->family) { if (info->family == c->x86) return info->model_names[c->x86_model]; info++; }#endif return NULL; /* Not found */} __u32 cpu_caps_cleared[NCAPINTS];__u32 cpu_caps_set[NCAPINTS]; void load_percpu_segment(int cpu){#ifdef CONFIG_X86_32 loadsegment(fs, __KERNEL_PERCPU);#else loadsegment(gs, 0); wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));#endif load_stack_canary_segment();} /* * Current gdt points %fs at the "master" per-cpu area: after this, * it's on the real one. */void switch_to_new_gdt(int cpu){ struct desc_ptr gdt_descr; gdt_descr.address = (long)get_cpu_gdt_table(cpu); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); /* Reload the per-cpu base */ load_percpu_segment(cpu);} static const struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; static void get_model_name(struct cpuinfo_x86 *c){ unsigned int *v; char *p, *q; if (c->extended_cpuid_level < 0x80000004) return; v = (unsigned int *)c->x86_model_id; cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); c->x86_model_id[48] = 0; /* * Intel chips right-justify this string for some dumb reason; * undo that brain damage: */ p = q = &c->x86_model_id[0]; while (*p == ' ') p++; if (p != q) { while (*p) *q++ = *p++; while (q <= &c->x86_model_id[48]) *q++ = '\0'; /* Zero-pad the rest */ }} void cpu_detect_cache_sizes(struct cpuinfo_x86 *c){ unsigned int n, dummy, ebx, ecx, edx, l2size; n = c->extended_cpuid_level; if (n >= 0x80000005) { cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); c->x86_cache_size = (ecx>>24) + (edx>>24);#ifdef CONFIG_X86_64 /* On K8 L1 TLB is inclusive, so don't count it */ c->x86_tlbsize = 0;#endif } if (n < 0x80000006) /* Some chips just has a large L1. */ return; cpuid(0x80000006, &dummy, &ebx, &ecx, &edx); l2size = ecx >> 16; #ifdef CONFIG_X86_64 c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);#else /* do processor-specific cache resizing */ if (this_cpu->legacy_cache_size) l2size = this_cpu->legacy_cache_size(c, l2size); /* Allow user to override all this if necessary. */ if (cachesize_override != -1) l2size = cachesize_override; if (l2size == 0) return; /* Again, no L2 cache is possible */#endif c->x86_cache_size = l2size;} u16 __read_mostly tlb_lli_4k[NR_INFO];u16 __read_mostly tlb_lli_2m[NR_INFO];u16 __read_mostly tlb_lli_4m[NR_INFO];u16 __read_mostly tlb_lld_4k[NR_INFO];u16 __read_mostly tlb_lld_2m[NR_INFO];u16 __read_mostly tlb_lld_4m[NR_INFO]; /* * tlb_flushall_shift shows the balance point in replacing cr3 write * with multiple 'invlpg'. It will do this replacement when * flush_tlb_lines <= active_lines/2^tlb_flushall_shift. * If tlb_flushall_shift is -1, means the replacement will be disabled. */s8 __read_mostly tlb_flushall_shift = -1; void cpu_detect_tlb(struct cpuinfo_x86 *c){ if (this_cpu->c_detect_tlb) this_cpu->c_detect_tlb(c); printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ "tlb_flushall_shift: %d\n", tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], tlb_flushall_shift);} void detect_ht(struct cpuinfo_x86 *c){#ifdef CONFIG_X86_HTLines 1–500 of 1387. Load more
#include <linux/bootmem.h> #include <linux/linkage.h> #include <linux/bitops.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/percpu.h> #include <linux/string.h> #include <linux/delay.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/kgdb.h> #include <linux/smp.h> #include <linux/io.h> #include <asm/stackprotector.h> #include <asm/perf_event.h> #include <asm/mmu_context.h> #include <asm/archrandom.h> #include <asm/hypervisor.h> #include <asm/processor.h> #include <asm/debugreg.h> #include <asm/sections.h> #include <linux/topology.h> #include <linux/cpumask.h> #include <asm/pgtable.h> #include <linux/atomic.h> #include <asm/proto.h> #include <asm/setup.h> #include <asm/apic.h> #include <asm/desc.h> #include <asm/i387.h> #include <asm/fpu-internal.h> #include <asm/mtrr.h> #include <linux/numa.h> #include <asm/asm.h> #include <asm/cpu.h> #include <asm/mce.h> #include <asm/msr.h> #include <asm/pat.h> #include <asm/microcode.h> #include <asm/microcode_intel.h> #ifdef CONFIG_X86_LOCAL_APIC #include <asm/uv/uv.h> #endif #include "cpu.h" /* all of these masks are initialized in setup_cpu_local_masks() */ cpumask_var_t cpu_initialized_mask; cpumask_var_t cpu_callout_mask; cpumask_var_t cpu_callin_mask; /* representing cpus for which sibling maps can be computed */ cpumask_var_t cpu_sibling_setup_mask; /* correctly size the local cpu masks */ void __init setup_cpu_local_masks(void) { alloc_bootmem_cpumask_var(&cpu_initialized_mask); alloc_bootmem_cpumask_var(&cpu_callin_mask); alloc_bootmem_cpumask_var(&cpu_callout_mask); alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask); } static void default_init(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_64 cpu_detect_cache_sizes(c); #else /* Not much we can do here... */ /* Check if at least it has cpuid */ if (c->cpuid_level == -1) { /* No cpuid. It must be an ancient CPU */ if (c->x86 == 4) strcpy(c->x86_model_id, "486"); else if (c->x86 == 3) strcpy(c->x86_model_id, "386"); } #endif } static const struct cpu_dev default_cpu = { .c_init = default_init, .c_vendor = "Unknown", .c_x86_vendor = X86_VENDOR_UNKNOWN, }; static const struct cpu_dev *this_cpu = &default_cpu; DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { #ifdef CONFIG_X86_64 /* * We need valid kernel segments for data and code in long mode too * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout * * TLS descriptors are currently at a different place compared to i386. * Hopefully nobody expects them at a fixed place (Wine?) */ [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff), #else [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff), /* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ /* 32-bit code */ [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), /* 16-bit code */ [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0), /* 16-bit data */ [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0), /* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ /* 32-bit code */ [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), /* 16-bit code */ [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), /* data */ [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff), [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), GDT_STACK_CANARY_INIT #endif } }; EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); static int __init x86_xsave_setup(char *s) { setup_clear_cpu_cap(X86_FEATURE_XSAVE); setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); setup_clear_cpu_cap(X86_FEATURE_AVX); setup_clear_cpu_cap(X86_FEATURE_AVX2); return 1; } __setup("noxsave", x86_xsave_setup); static int __init x86_xsaveopt_setup(char *s) { setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); return 1; } __setup("noxsaveopt", x86_xsaveopt_setup); #ifdef CONFIG_X86_32 static int cachesize_override = -1; static int disable_x86_serial_nr = 1; static int __init cachesize_setup(char *str) { get_option(&str, &cachesize_override); return 1; } __setup("cachesize=", cachesize_setup); static int __init x86_fxsr_setup(char *s) { setup_clear_cpu_cap(X86_FEATURE_FXSR); setup_clear_cpu_cap(X86_FEATURE_XMM); return 1; } __setup("nofxsr", x86_fxsr_setup); static int __init x86_sep_setup(char *s) { setup_clear_cpu_cap(X86_FEATURE_SEP); return 1; } __setup("nosep", x86_sep_setup); /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(u32 flag) { u32 f1, f2; /* * Cyrix and IDT cpus allow disabling of CPUID * so the code below may return different results * when it is executed before and after enabling * the CPUID. Add "volatile" to not allow gcc to * optimize the subsequent calls to this function. */ asm volatile ("pushfl \n\t" "pushfl \n\t" "popl %0 \n\t" "movl %0, %1 \n\t" "xorl %2, %0 \n\t" "pushl %0 \n\t" "popfl \n\t" "pushfl \n\t" "popl %0 \n\t" "popfl \n\t" : "=&r" (f1), "=&r" (f2) : "ir" (flag)); return ((f1^f2) & flag) != 0; } /* Probe for the CPUID instruction */ int have_cpuid_p(void) { return flag_is_changeable_p(X86_EFLAGS_ID); } static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { unsigned long lo, hi; if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr) return; /* Disable processor serial number: */ rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi); lo |= 0x200000; wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi); printk(KERN_NOTICE "CPU serial number disabled.\n"); clear_cpu_cap(c, X86_FEATURE_PN); /* Disabling the serial number may affect the cpuid level */ c->cpuid_level = cpuid_eax(0); } static int __init x86_serial_nr_setup(char *s) { disable_x86_serial_nr = 0; return 1; } __setup("serialnumber", x86_serial_nr_setup); #else static inline int flag_is_changeable_p(u32 flag) { return 1; } static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { } #endif static __init int setup_disable_smep(char *arg) { setup_clear_cpu_cap(X86_FEATURE_SMEP); return 1; } __setup("nosmep", setup_disable_smep); static __always_inline void setup_smep(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_SMEP)) set_in_cr4(X86_CR4_SMEP); } static __init int setup_disable_smap(char *arg) { setup_clear_cpu_cap(X86_FEATURE_SMAP); return 1; } __setup("nosmap", setup_disable_smap); static __always_inline void setup_smap(struct cpuinfo_x86 *c) { unsigned long eflags; /* This should have been cleared long ago */ raw_local_save_flags(eflags); BUG_ON(eflags & X86_EFLAGS_AC); if (cpu_has(c, X86_FEATURE_SMAP)) set_in_cr4(X86_CR4_SMAP); } /* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization * software. Add those features to this table to auto-disable them. */ struct cpuid_dependent_feature { u32 feature; u32 level; }; static const struct cpuid_dependent_feature cpuid_dependent_features[] = { { X86_FEATURE_MWAIT, 0x00000005 }, { X86_FEATURE_DCA, 0x00000009 }, { X86_FEATURE_XSAVE, 0x0000000d }, { 0, 0 } }; static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) { const struct cpuid_dependent_feature *df; for (df = cpuid_dependent_features; df->feature; df++) { if (!cpu_has(c, df->feature)) continue; /* * Note: cpuid_level is set to -1 if unavailable, but * extended_extended_level is set to 0 if unavailable * and the legitimate extended levels are all negative * when signed; hence the weird messing around with * signs here... */ if (!((s32)df->level < 0 ? (u32)df->level > (u32)c->extended_cpuid_level : (s32)df->level > (s32)c->cpuid_level)) continue; clear_cpu_cap(c, df->feature); if (!warn) continue; printk(KERN_WARNING "CPU: CPU feature %s disabled, no CPUID level 0x%x\n", x86_cap_flags[df->feature], df->level); } } /* * Naming convention should be: <Name> [(<Codename>)] * This table only is used unless init_<vendor>() below doesn't set it; * in particular, if CPUID levels 0x80000002..4 are supported, this * isn't used */ /* Look up CPU names by table lookup. */ static const char *table_lookup_model(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_32 const struct legacy_cpu_model_info *info; if (c->x86_model >= 16) return NULL; /* Range check */ if (!this_cpu) return NULL; info = this_cpu->legacy_models; while (info->family) { if (info->family == c->x86) return info->model_names[c->x86_model]; info++; } #endif return NULL; /* Not found */ } __u32 cpu_caps_cleared[NCAPINTS]; __u32 cpu_caps_set[NCAPINTS]; void load_percpu_segment(int cpu) { #ifdef CONFIG_X86_32 loadsegment(fs, __KERNEL_PERCPU); #else loadsegment(gs, 0); wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu)); #endif load_stack_canary_segment(); } /* * Current gdt points %fs at the "master" per-cpu area: after this, * it's on the real one. */ void switch_to_new_gdt(int cpu) { struct desc_ptr gdt_descr; gdt_descr.address = (long)get_cpu_gdt_table(cpu); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); /* Reload the per-cpu base */ load_percpu_segment(cpu); } static const struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; static void get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; char *p, *q; if (c->extended_cpuid_level < 0x80000004) return; v = (unsigned int *)c->x86_model_id; cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); c->x86_model_id[48] = 0; /* * Intel chips right-justify this string for some dumb reason; * undo that brain damage: */ p = q = &c->x86_model_id[0]; while (*p == ' ') p++; if (p != q) { while (*p) *q++ = *p++; while (q <= &c->x86_model_id[48]) *q++ = '\0'; /* Zero-pad the rest */ } } void cpu_detect_cache_sizes(struct cpuinfo_x86 *c) { unsigned int n, dummy, ebx, ecx, edx, l2size; n = c->extended_cpuid_level; if (n >= 0x80000005) { cpuid(0x80000005, &dummy, &ebx, &ecx, &edx); c->x86_cache_size = (ecx>>24) + (edx>>24); #ifdef CONFIG_X86_64 /* On K8 L1 TLB is inclusive, so don't count it */ c->x86_tlbsize = 0; #endif } if (n < 0x80000006) /* Some chips just has a large L1. */ return; cpuid(0x80000006, &dummy, &ebx, &ecx, &edx); l2size = ecx >> 16; #ifdef CONFIG_X86_64 c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff); #else /* do processor-specific cache resizing */ if (this_cpu->legacy_cache_size) l2size = this_cpu->legacy_cache_size(c, l2size); /* Allow user to override all this if necessary. */ if (cachesize_override != -1) l2size = cachesize_override; if (l2size == 0) return; /* Again, no L2 cache is possible */ #endif c->x86_cache_size = l2size; } u16 __read_mostly tlb_lli_4k[NR_INFO]; u16 __read_mostly tlb_lli_2m[NR_INFO]; u16 __read_mostly tlb_lli_4m[NR_INFO]; u16 __read_mostly tlb_lld_4k[NR_INFO]; u16 __read_mostly tlb_lld_2m[NR_INFO]; u16 __read_mostly tlb_lld_4m[NR_INFO]; /* * tlb_flushall_shift shows the balance point in replacing cr3 write * with multiple 'invlpg'. It will do this replacement when * flush_tlb_lines <= active_lines/2^tlb_flushall_shift. * If tlb_flushall_shift is -1, means the replacement will be disabled. */ s8 __read_mostly tlb_flushall_shift = -1; void cpu_detect_tlb(struct cpuinfo_x86 *c) { if (this_cpu->c_detect_tlb) this_cpu->c_detect_tlb(c); printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ "tlb_flushall_shift: %d\n", tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], tlb_flushall_shift); } void detect_ht(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_HT