diff options
| -rw-r--r-- | arch/x86/include/asm/cpufeature.h | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/scattered.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/tsc.c | 58 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 7 |
5 files changed, 40 insertions, 63 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index c6fbb7b430d1..0450a2842f48 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -152,10 +152,14 @@ | |||
| 152 | #define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */ | 152 | #define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */ |
| 153 | #define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */ | 153 | #define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */ |
| 154 | #define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */ | 154 | #define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */ |
| 155 | #define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */ | 155 | #define X86_FEATURE_XOP (6*32+11) /* extended AVX instructions */ |
| 156 | #define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */ | 156 | #define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */ |
| 157 | #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ | 157 | #define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */ |
| 158 | #define X86_FEATURE_LWP (6*32+15) /* Light Weight Profiling */ | ||
| 159 | #define X86_FEATURE_FMA4 (6*32+16) /* 4 operands MAC instructions */ | ||
| 158 | #define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ | 160 | #define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */ |
| 161 | #define X86_FEATURE_TBM (6*32+21) /* trailing bit manipulations */ | ||
| 162 | #define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */ | ||
| 159 | 163 | ||
| 160 | /* | 164 | /* |
| 161 | * Auxiliary flags: Linux defined - For features scattered in various | 165 | * Auxiliary flags: Linux defined - For features scattered in various |
| @@ -179,6 +183,13 @@ | |||
| 179 | #define X86_FEATURE_LBRV (8*32+ 6) /* AMD LBR Virtualization support */ | 183 | #define X86_FEATURE_LBRV (8*32+ 6) /* AMD LBR Virtualization support */ |
| 180 | #define X86_FEATURE_SVML (8*32+ 7) /* "svm_lock" AMD SVM locking MSR */ | 184 | #define X86_FEATURE_SVML (8*32+ 7) /* "svm_lock" AMD SVM locking MSR */ |
| 181 | #define X86_FEATURE_NRIPS (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */ | 185 | #define X86_FEATURE_NRIPS (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */ |
| 186 | #define X86_FEATURE_TSCRATEMSR (8*32+ 9) /* "tsc_scale" AMD TSC scaling support */ | ||
| 187 | #define X86_FEATURE_VMCBCLEAN (8*32+10) /* "vmcb_clean" AMD VMCB clean bits support */ | ||
| 188 | #define X86_FEATURE_FLUSHBYASID (8*32+11) /* AMD flush-by-ASID support */ | ||
| 189 | #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */ | ||
| 190 | #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */ | ||
| 191 | #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */ | ||
| 192 | |||
| 182 | 193 | ||
| 183 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ | 194 | /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ |
| 184 | #define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ | 195 | #define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index ba5f62f45f01..0f0ace5d7db5 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -412,6 +412,23 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | |||
| 412 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); | 412 | set_cpu_cap(c, X86_FEATURE_EXTD_APICID); |
| 413 | } | 413 | } |
| 414 | #endif | 414 | #endif |
| 415 | |||
| 416 | /* We need to do the following only once */ | ||
| 417 | if (c != &boot_cpu_data) | ||
| 418 | return; | ||
| 419 | |||
| 420 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { | ||
| 421 | |||
| 422 | if (c->x86 > 0x10 || | ||
| 423 | (c->x86 == 0x10 && c->x86_model >= 0x2)) { | ||
| 424 | u64 val; | ||
| 425 | |||
| 426 | rdmsrl(MSR_K7_HWCR, val); | ||
| 427 | if (!(val & BIT(24))) | ||
| 428 | printk(KERN_WARNING FW_BUG "TSC doesn't count " | ||
| 429 | "with P0 frequency!\n"); | ||
| 430 | } | ||
| 431 | } | ||
| 415 | } | 432 | } |
| 416 | 433 | ||
| 417 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 434 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
| @@ -523,7 +540,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 523 | #endif | 540 | #endif |
| 524 | 541 | ||
| 525 | if (c->extended_cpuid_level >= 0x80000006) { | 542 | if (c->extended_cpuid_level >= 0x80000006) { |
| 526 | if ((c->x86 >= 0x0f) && (cpuid_edx(0x80000006) & 0xf000)) | 543 | if (cpuid_edx(0x80000006) & 0xf000) |
| 527 | num_cache_leaves = 4; | 544 | num_cache_leaves = 4; |
| 528 | else | 545 | else |
| 529 | num_cache_leaves = 3; | 546 | num_cache_leaves = 3; |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 34b4dad6f0b8..2c77931473fb 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
| @@ -43,6 +43,12 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
| 43 | { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, | 43 | { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, |
| 44 | { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, | 44 | { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, |
| 45 | { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, | 45 | { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, |
| 46 | { X86_FEATURE_TSCRATEMSR, CR_EDX, 4, 0x8000000a, 0 }, | ||
| 47 | { X86_FEATURE_VMCBCLEAN, CR_EDX, 5, 0x8000000a, 0 }, | ||
| 48 | { X86_FEATURE_FLUSHBYASID, CR_EDX, 6, 0x8000000a, 0 }, | ||
| 49 | { X86_FEATURE_DECODEASSISTS, CR_EDX, 7, 0x8000000a, 0 }, | ||
| 50 | { X86_FEATURE_PAUSEFILTER, CR_EDX,10, 0x8000000a, 0 }, | ||
| 51 | { X86_FEATURE_PFTHRESHOLD, CR_EDX,12, 0x8000000a, 0 }, | ||
| 46 | { 0, 0, 0, 0, 0 } | 52 | { 0, 0, 0, 0, 0 } |
| 47 | }; | 53 | }; |
| 48 | 54 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 26a863a9c2a8..4496315eb224 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
| @@ -892,60 +892,6 @@ static void __init init_tsc_clocksource(void) | |||
| 892 | clocksource_register_khz(&clocksource_tsc, tsc_khz); | 892 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
| 893 | } | 893 | } |
| 894 | 894 | ||
| 895 | #ifdef CONFIG_X86_64 | ||
| 896 | /* | ||
| 897 | * calibrate_cpu is used on systems with fixed rate TSCs to determine | ||
| 898 | * processor frequency | ||
| 899 | */ | ||
| 900 | #define TICK_COUNT 100000000 | ||
| 901 | static unsigned long __init calibrate_cpu(void) | ||
| 902 | { | ||
| 903 | int tsc_start, tsc_now; | ||
| 904 | int i, no_ctr_free; | ||
| 905 | unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0; | ||
| 906 | unsigned long flags; | ||
| 907 | |||
| 908 | for (i = 0; i < 4; i++) | ||
| 909 | if (avail_to_resrv_perfctr_nmi_bit(i)) | ||
| 910 | break; | ||
| 911 | no_ctr_free = (i == 4); | ||
| 912 | if (no_ctr_free) { | ||
| 913 | WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... " | ||
| 914 | "cpu_khz value may be incorrect.\n"); | ||
| 915 | i = 3; | ||
| 916 | rdmsrl(MSR_K7_EVNTSEL3, evntsel3); | ||
| 917 | wrmsrl(MSR_K7_EVNTSEL3, 0); | ||
| 918 | rdmsrl(MSR_K7_PERFCTR3, pmc3); | ||
| 919 | } else { | ||
| 920 | reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
| 921 | reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i); | ||
| 922 | } | ||
| 923 | local_irq_save(flags); | ||
| 924 | /* start measuring cycles, incrementing from 0 */ | ||
| 925 | wrmsrl(MSR_K7_PERFCTR0 + i, 0); | ||
| 926 | wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76); | ||
| 927 | rdtscl(tsc_start); | ||
| 928 | do { | ||
| 929 | rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); | ||
| 930 | tsc_now = get_cycles(); | ||
| 931 | } while ((tsc_now - tsc_start) < TICK_COUNT); | ||
| 932 | |||
| 933 | local_irq_restore(flags); | ||
| 934 | if (no_ctr_free) { | ||
| 935 | wrmsrl(MSR_K7_EVNTSEL3, 0); | ||
| 936 | wrmsrl(MSR_K7_PERFCTR3, pmc3); | ||
| 937 | wrmsrl(MSR_K7_EVNTSEL3, evntsel3); | ||
| 938 | } else { | ||
| 939 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | ||
| 940 | release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); | ||
| 941 | } | ||
| 942 | |||
| 943 | return pmc_now * tsc_khz / (tsc_now - tsc_start); | ||
| 944 | } | ||
| 945 | #else | ||
| 946 | static inline unsigned long calibrate_cpu(void) { return cpu_khz; } | ||
| 947 | #endif | ||
| 948 | |||
| 949 | void __init tsc_init(void) | 895 | void __init tsc_init(void) |
| 950 | { | 896 | { |
| 951 | u64 lpj; | 897 | u64 lpj; |
| @@ -964,10 +910,6 @@ void __init tsc_init(void) | |||
| 964 | return; | 910 | return; |
| 965 | } | 911 | } |
| 966 | 912 | ||
| 967 | if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && | ||
| 968 | (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) | ||
| 969 | cpu_khz = calibrate_cpu(); | ||
| 970 | |||
| 971 | printk("Detected %lu.%03lu MHz processor.\n", | 913 | printk("Detected %lu.%03lu MHz processor.\n", |
| 972 | (unsigned long)cpu_khz / 1000, | 914 | (unsigned long)cpu_khz / 1000, |
| 973 | (unsigned long)cpu_khz % 1000); | 915 | (unsigned long)cpu_khz % 1000); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3a09c625d526..6c2ecf0a806d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -1991,13 +1991,14 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 1991 | 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ | | 1991 | 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ | |
| 1992 | 0 /* Reserved, DCA */ | F(XMM4_1) | | 1992 | 0 /* Reserved, DCA */ | F(XMM4_1) | |
| 1993 | F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) | | 1993 | F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) | |
| 1994 | 0 /* Reserved, AES */ | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX); | 1994 | 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) | |
| 1995 | F(F16C); | ||
| 1995 | /* cpuid 0x80000001.ecx */ | 1996 | /* cpuid 0x80000001.ecx */ |
| 1996 | const u32 kvm_supported_word6_x86_features = | 1997 | const u32 kvm_supported_word6_x86_features = |
| 1997 | F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ | | 1998 | F(LAHF_LM) | F(CMP_LEGACY) | F(SVM) | 0 /* ExtApicSpace */ | |
| 1998 | F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) | | 1999 | F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) | |
| 1999 | F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(SSE5) | | 2000 | F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) | |
| 2000 | 0 /* SKINIT */ | 0 /* WDT */; | 2001 | 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM); |
| 2001 | 2002 | ||
| 2002 | /* all calls to cpuid_count() should be made on the same cpu */ | 2003 | /* all calls to cpuid_count() should be made on the same cpu */ |
| 2003 | get_cpu(); | 2004 | get_cpu(); |
