Commit 0f477dd0851bdcee82923da66a7fc4a44cb1bc3d
Exists in
master
and in
7 other branches
Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: Fix keeping track of AMD C1E x86, cpu: Package Level Thermal Control, Power Limit Notification definitions x86, cpu: Export AMD errata definitions x86, cpu: Use AMD errata checking framework for erratum 383 x86, cpu: Clean up AMD erratum 400 workaround x86, cpu: AMD errata checking framework x86, cpu: Split addon_cpuid_features.c x86, cpu: Clean up formatting in cpufeature.h, remove override x86, cpu: Enumerate xsaveopt x86, cpu: Add xsaveopt cpufeature x86, cpu: Make init_scattered_cpuid_features() consider cpuid subleaves x86, cpu: Support the features flags in new CPUID leaf 7 x86, cpu: Add CPU flags for F16C and RDRND x86: Look for IA32_ENERGY_PERF_BIAS support x86, AMD: Extend support to future families x86, cacheinfo: Carve out L3 cache slot accessors x86, xsave: Cleanup return codes in check_for_xstate()
Showing 16 changed files Side-by-side Diff
- arch/x86/include/asm/acpi.h
- arch/x86/include/asm/cpufeature.h
- arch/x86/include/asm/msr-index.h
- arch/x86/include/asm/processor.h
- arch/x86/include/asm/required-features.h
- arch/x86/kernel/cpu/Makefile
- arch/x86/kernel/cpu/addon_cpuid_features.c
- arch/x86/kernel/cpu/amd.c
- arch/x86/kernel/cpu/common.c
- arch/x86/kernel/cpu/intel_cacheinfo.c
- arch/x86/kernel/cpu/scattered.c
- arch/x86/kernel/cpu/topology.c
- arch/x86/kernel/process.c
- arch/x86/kernel/xsave.c
- arch/x86/kvm/svm.c
- drivers/acpi/processor_idle.c
arch/x86/include/asm/acpi.h
arch/x86/include/asm/cpufeature.h
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | |
7 | 7 | #include <asm/required-features.h> |
8 | 8 | |
9 | -#define NCAPINTS 9 /* N 32-bit words worth of info */ | |
9 | +#define NCAPINTS 10 /* N 32-bit words worth of info */ | |
10 | 10 | |
11 | 11 | /* |
12 | 12 | * Note: If the comment begins with a quoted string, that string is used |
... | ... | @@ -89,7 +89,7 @@ |
89 | 89 | #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* "" Lfence synchronizes RDTSC */ |
90 | 90 | #define X86_FEATURE_11AP (3*32+19) /* "" Bad local APIC aka 11AP */ |
91 | 91 | #define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */ |
92 | -#define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */ | |
92 | + /* 21 available, was AMD_C1E */ | |
93 | 93 | #define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */ |
94 | 94 | #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */ |
95 | 95 | #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ |
... | ... | @@ -124,6 +124,8 @@ |
124 | 124 | #define X86_FEATURE_XSAVE (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ |
125 | 125 | #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ |
126 | 126 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ |
127 | +#define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ | |
128 | +#define X86_FEATURE_RDRND (4*32+30) /* The RDRAND instruction */ | |
127 | 129 | #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ |
128 | 130 | |
129 | 131 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ |
130 | 132 | |
131 | 133 | |
132 | 134 | |
133 | 135 | |
... | ... | @@ -157,23 +159,30 @@ |
157 | 159 | |
158 | 160 | /* |
159 | 161 | * Auxiliary flags: Linux defined - For features scattered in various |
160 | - * CPUID levels like 0x6, 0xA etc | |
162 | + * CPUID levels like 0x6, 0xA etc, word 7 | |
161 | 163 | */ |
162 | 164 | #define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ |
163 | 165 | #define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */ |
164 | 166 | #define X86_FEATURE_CPB (7*32+ 2) /* AMD Core Performance Boost */ |
167 | +#define X86_FEATURE_EPB (7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ | |
168 | +#define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ | |
169 | +#define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ | |
170 | +#define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ | |
165 | 171 | |
166 | -/* Virtualization flags: Linux defined */ | |
172 | +/* Virtualization flags: Linux defined, word 8 */ | |
167 | 173 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ |
168 | 174 | #define X86_FEATURE_VNMI (8*32+ 1) /* Intel Virtual NMI */ |
169 | 175 | #define X86_FEATURE_FLEXPRIORITY (8*32+ 2) /* Intel FlexPriority */ |
170 | 176 | #define X86_FEATURE_EPT (8*32+ 3) /* Intel Extended Page Table */ |
171 | 177 | #define X86_FEATURE_VPID (8*32+ 4) /* Intel Virtual Processor ID */ |
172 | -#define X86_FEATURE_NPT (8*32+5) /* AMD Nested Page Table support */ | |
173 | -#define X86_FEATURE_LBRV (8*32+6) /* AMD LBR Virtualization support */ | |
174 | -#define X86_FEATURE_SVML (8*32+7) /* "svm_lock" AMD SVM locking MSR */ | |
175 | -#define X86_FEATURE_NRIPS (8*32+8) /* "nrip_save" AMD SVM next_rip save */ | |
178 | +#define X86_FEATURE_NPT (8*32+ 5) /* AMD Nested Page Table support */ | |
179 | +#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 */ | |
181 | +#define X86_FEATURE_NRIPS (8*32+ 8) /* "nrip_save" AMD SVM next_rip save */ | |
176 | 182 | |
183 | +/* 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*/ | |
185 | + | |
177 | 186 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
178 | 187 | |
179 | 188 | #include <asm/asm.h> |
... | ... | @@ -194,7 +203,9 @@ |
194 | 203 | (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \ |
195 | 204 | (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \ |
196 | 205 | (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ |
197 | - (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \ | |
206 | + (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) || \ | |
207 | + (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) || \ | |
208 | + (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) ) \ | |
198 | 209 | ? 1 : \ |
199 | 210 | test_cpu_cap(c, bit)) |
200 | 211 |
arch/x86/include/asm/msr-index.h
... | ... | @@ -226,12 +226,14 @@ |
226 | 226 | #define MSR_IA32_THERM_CONTROL 0x0000019a |
227 | 227 | #define MSR_IA32_THERM_INTERRUPT 0x0000019b |
228 | 228 | |
229 | -#define THERM_INT_LOW_ENABLE (1 << 0) | |
230 | -#define THERM_INT_HIGH_ENABLE (1 << 1) | |
229 | +#define THERM_INT_HIGH_ENABLE (1 << 0) | |
230 | +#define THERM_INT_LOW_ENABLE (1 << 1) | |
231 | +#define THERM_INT_PLN_ENABLE (1 << 24) | |
231 | 232 | |
232 | 233 | #define MSR_IA32_THERM_STATUS 0x0000019c |
233 | 234 | |
234 | 235 | #define THERM_STATUS_PROCHOT (1 << 0) |
236 | +#define THERM_STATUS_POWER_LIMIT (1 << 10) | |
235 | 237 | |
236 | 238 | #define MSR_THERM2_CTL 0x0000019d |
237 | 239 | |
... | ... | @@ -240,6 +242,19 @@ |
240 | 242 | #define MSR_IA32_MISC_ENABLE 0x000001a0 |
241 | 243 | |
242 | 244 | #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 |
245 | + | |
246 | +#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 | |
247 | + | |
248 | +#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 | |
249 | + | |
250 | +#define PACKAGE_THERM_STATUS_PROCHOT (1 << 0) | |
251 | +#define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10) | |
252 | + | |
253 | +#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2 | |
254 | + | |
255 | +#define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0) | |
256 | +#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1) | |
257 | +#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24) | |
243 | 258 | |
244 | 259 | /* MISC_ENABLE bits: architectural */ |
245 | 260 | #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) |
arch/x86/include/asm/processor.h
... | ... | @@ -762,6 +762,7 @@ |
762 | 762 | extern unsigned long boot_option_idle_override; |
763 | 763 | extern unsigned long idle_halt; |
764 | 764 | extern unsigned long idle_nomwait; |
765 | +extern bool c1e_detected; | |
765 | 766 | |
766 | 767 | /* |
767 | 768 | * on systems with caches, caches must be flashed as the absolute |
... | ... | @@ -1024,6 +1025,26 @@ |
1024 | 1025 | |
1025 | 1026 | return ratio; |
1026 | 1027 | } |
1028 | + | |
1029 | +/* | |
1030 | + * AMD errata checking | |
1031 | + */ | |
1032 | +#ifdef CONFIG_CPU_SUP_AMD | |
1033 | +extern const int amd_erratum_383[]; | |
1034 | +extern const int amd_erratum_400[]; | |
1035 | +extern bool cpu_has_amd_erratum(const int *); | |
1036 | + | |
1037 | +#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } | |
1038 | +#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } | |
1039 | +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ | |
1040 | + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) | |
1041 | +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) | |
1042 | +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) | |
1043 | +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) | |
1044 | + | |
1045 | +#else | |
1046 | +#define cpu_has_amd_erratum(x) (false) | |
1047 | +#endif /* CONFIG_CPU_SUP_AMD */ | |
1027 | 1048 | |
1028 | 1049 | #endif /* _ASM_X86_PROCESSOR_H */ |
arch/x86/include/asm/required-features.h
arch/x86/kernel/cpu/Makefile
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | nostackp := $(call cc-option, -fno-stack-protector) |
13 | 13 | CFLAGS_common.o := $(nostackp) |
14 | 14 | |
15 | -obj-y := intel_cacheinfo.o addon_cpuid_features.o | |
15 | +obj-y := intel_cacheinfo.o scattered.o topology.o | |
16 | 16 | obj-y += proc.o capflags.o powerflags.o common.o |
17 | 17 | obj-y += vmware.o hypervisor.o sched.o mshyperv.o |
18 | 18 |
arch/x86/kernel/cpu/addon_cpuid_features.c
1 | -/* | |
2 | - * Routines to indentify additional cpu features that are scattered in | |
3 | - * cpuid space. | |
4 | - */ | |
5 | -#include <linux/cpu.h> | |
6 | - | |
7 | -#include <asm/pat.h> | |
8 | -#include <asm/processor.h> | |
9 | - | |
10 | -#include <asm/apic.h> | |
11 | - | |
12 | -struct cpuid_bit { | |
13 | - u16 feature; | |
14 | - u8 reg; | |
15 | - u8 bit; | |
16 | - u32 level; | |
17 | -}; | |
18 | - | |
19 | -enum cpuid_regs { | |
20 | - CR_EAX = 0, | |
21 | - CR_ECX, | |
22 | - CR_EDX, | |
23 | - CR_EBX | |
24 | -}; | |
25 | - | |
26 | -void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |
27 | -{ | |
28 | - u32 max_level; | |
29 | - u32 regs[4]; | |
30 | - const struct cpuid_bit *cb; | |
31 | - | |
32 | - static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | |
33 | - { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 }, | |
34 | - { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 }, | |
35 | - { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006 }, | |
36 | - { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007 }, | |
37 | - { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a }, | |
38 | - { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a }, | |
39 | - { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a }, | |
40 | - { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a }, | |
41 | - { 0, 0, 0, 0 } | |
42 | - }; | |
43 | - | |
44 | - for (cb = cpuid_bits; cb->feature; cb++) { | |
45 | - | |
46 | - /* Verify that the level is valid */ | |
47 | - max_level = cpuid_eax(cb->level & 0xffff0000); | |
48 | - if (max_level < cb->level || | |
49 | - max_level > (cb->level | 0xffff)) | |
50 | - continue; | |
51 | - | |
52 | - cpuid(cb->level, ®s[CR_EAX], ®s[CR_EBX], | |
53 | - ®s[CR_ECX], ®s[CR_EDX]); | |
54 | - | |
55 | - if (regs[cb->reg] & (1 << cb->bit)) | |
56 | - set_cpu_cap(c, cb->feature); | |
57 | - } | |
58 | -} | |
59 | - | |
60 | -/* leaf 0xb SMT level */ | |
61 | -#define SMT_LEVEL 0 | |
62 | - | |
63 | -/* leaf 0xb sub-leaf types */ | |
64 | -#define INVALID_TYPE 0 | |
65 | -#define SMT_TYPE 1 | |
66 | -#define CORE_TYPE 2 | |
67 | - | |
68 | -#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff) | |
69 | -#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) | |
70 | -#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) | |
71 | - | |
72 | -/* | |
73 | - * Check for extended topology enumeration cpuid leaf 0xb and if it | |
74 | - * exists, use it for populating initial_apicid and cpu topology | |
75 | - * detection. | |
76 | - */ | |
77 | -void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c) | |
78 | -{ | |
79 | -#ifdef CONFIG_SMP | |
80 | - unsigned int eax, ebx, ecx, edx, sub_index; | |
81 | - unsigned int ht_mask_width, core_plus_mask_width; | |
82 | - unsigned int core_select_mask, core_level_siblings; | |
83 | - static bool printed; | |
84 | - | |
85 | - if (c->cpuid_level < 0xb) | |
86 | - return; | |
87 | - | |
88 | - cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); | |
89 | - | |
90 | - /* | |
91 | - * check if the cpuid leaf 0xb is actually implemented. | |
92 | - */ | |
93 | - if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) | |
94 | - return; | |
95 | - | |
96 | - set_cpu_cap(c, X86_FEATURE_XTOPOLOGY); | |
97 | - | |
98 | - /* | |
99 | - * initial apic id, which also represents 32-bit extended x2apic id. | |
100 | - */ | |
101 | - c->initial_apicid = edx; | |
102 | - | |
103 | - /* | |
104 | - * Populate HT related information from sub-leaf level 0. | |
105 | - */ | |
106 | - core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); | |
107 | - core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | |
108 | - | |
109 | - sub_index = 1; | |
110 | - do { | |
111 | - cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx); | |
112 | - | |
113 | - /* | |
114 | - * Check for the Core type in the implemented sub leaves. | |
115 | - */ | |
116 | - if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) { | |
117 | - core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); | |
118 | - core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | |
119 | - break; | |
120 | - } | |
121 | - | |
122 | - sub_index++; | |
123 | - } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); | |
124 | - | |
125 | - core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; | |
126 | - | |
127 | - c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width) | |
128 | - & core_select_mask; | |
129 | - c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width); | |
130 | - /* | |
131 | - * Reinit the apicid, now that we have extended initial_apicid. | |
132 | - */ | |
133 | - c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); | |
134 | - | |
135 | - c->x86_max_cores = (core_level_siblings / smp_num_siblings); | |
136 | - | |
137 | - if (!printed) { | |
138 | - printk(KERN_INFO "CPU: Physical Processor ID: %d\n", | |
139 | - c->phys_proc_id); | |
140 | - if (c->x86_max_cores > 1) | |
141 | - printk(KERN_INFO "CPU: Processor Core ID: %d\n", | |
142 | - c->cpu_core_id); | |
143 | - printed = 1; | |
144 | - } | |
145 | - return; | |
146 | -#endif | |
147 | -} |
arch/x86/kernel/cpu/amd.c
... | ... | @@ -466,7 +466,7 @@ |
466 | 466 | } |
467 | 467 | |
468 | 468 | } |
469 | - if (c->x86 == 0x10 || c->x86 == 0x11) | |
469 | + if (c->x86 >= 0x10) | |
470 | 470 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); |
471 | 471 | |
472 | 472 | /* get apicid instead of initial apic id from cpuid */ |
... | ... | @@ -529,7 +529,7 @@ |
529 | 529 | num_cache_leaves = 3; |
530 | 530 | } |
531 | 531 | |
532 | - if (c->x86 >= 0xf && c->x86 <= 0x11) | |
532 | + if (c->x86 >= 0xf) | |
533 | 533 | set_cpu_cap(c, X86_FEATURE_K8); |
534 | 534 | |
535 | 535 | if (cpu_has_xmm2) { |
... | ... | @@ -546,7 +546,7 @@ |
546 | 546 | fam10h_check_enable_mmcfg(); |
547 | 547 | } |
548 | 548 | |
549 | - if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) { | |
549 | + if (c == &boot_cpu_data && c->x86 >= 0xf) { | |
550 | 550 | unsigned long long tseg; |
551 | 551 | |
552 | 552 | /* |
... | ... | @@ -609,4 +609,75 @@ |
609 | 609 | }; |
610 | 610 | |
611 | 611 | cpu_dev_register(amd_cpu_dev); |
612 | + | |
613 | +/* | |
614 | + * AMD errata checking | |
615 | + * | |
616 | + * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or | |
617 | + * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that | |
618 | + * have an OSVW id assigned, which it takes as first argument. Both take a | |
619 | + * variable number of family-specific model-stepping ranges created by | |
620 | + * AMD_MODEL_RANGE(). Each erratum also has to be declared as extern const | |
621 | + * int[] in arch/x86/include/asm/processor.h. | |
622 | + * | |
623 | + * Example: | |
624 | + * | |
625 | + * const int amd_erratum_319[] = | |
626 | + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), | |
627 | + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), | |
628 | + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); | |
629 | + */ | |
630 | + | |
631 | +const int amd_erratum_400[] = | |
632 | + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), | |
633 | + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); | |
634 | +EXPORT_SYMBOL_GPL(amd_erratum_400); | |
635 | + | |
636 | +const int amd_erratum_383[] = | |
637 | + AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); | |
638 | +EXPORT_SYMBOL_GPL(amd_erratum_383); | |
639 | + | |
640 | +bool cpu_has_amd_erratum(const int *erratum) | |
641 | +{ | |
642 | + struct cpuinfo_x86 *cpu = ¤t_cpu_data; | |
643 | + int osvw_id = *erratum++; | |
644 | + u32 range; | |
645 | + u32 ms; | |
646 | + | |
647 | + /* | |
648 | + * If called early enough that current_cpu_data hasn't been initialized | |
649 | + * yet, fall back to boot_cpu_data. | |
650 | + */ | |
651 | + if (cpu->x86 == 0) | |
652 | + cpu = &boot_cpu_data; | |
653 | + | |
654 | + if (cpu->x86_vendor != X86_VENDOR_AMD) | |
655 | + return false; | |
656 | + | |
657 | + if (osvw_id >= 0 && osvw_id < 65536 && | |
658 | + cpu_has(cpu, X86_FEATURE_OSVW)) { | |
659 | + u64 osvw_len; | |
660 | + | |
661 | + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); | |
662 | + if (osvw_id < osvw_len) { | |
663 | + u64 osvw_bits; | |
664 | + | |
665 | + rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), | |
666 | + osvw_bits); | |
667 | + return osvw_bits & (1ULL << (osvw_id & 0x3f)); | |
668 | + } | |
669 | + } | |
670 | + | |
671 | + /* OSVW unavailable or ID unknown, match family-model-stepping range */ | |
672 | + ms = (cpu->x86_model << 8) | cpu->x86_mask; | |
673 | + while ((range = *erratum++)) | |
674 | + if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && | |
675 | + (ms >= AMD_MODEL_RANGE_START(range)) && | |
676 | + (ms <= AMD_MODEL_RANGE_END(range))) | |
677 | + return true; | |
678 | + | |
679 | + return false; | |
680 | +} | |
681 | + | |
682 | +EXPORT_SYMBOL_GPL(cpu_has_amd_erratum); |
arch/x86/kernel/cpu/common.c
... | ... | @@ -551,6 +551,16 @@ |
551 | 551 | c->x86_capability[4] = excap; |
552 | 552 | } |
553 | 553 | |
554 | + /* Additional Intel-defined flags: level 0x00000007 */ | |
555 | + if (c->cpuid_level >= 0x00000007) { | |
556 | + u32 eax, ebx, ecx, edx; | |
557 | + | |
558 | + cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx); | |
559 | + | |
560 | + if (eax > 0) | |
561 | + c->x86_capability[9] = ebx; | |
562 | + } | |
563 | + | |
554 | 564 | /* AMD-defined flags: level 0x80000001 */ |
555 | 565 | xlvl = cpuid_eax(0x80000000); |
556 | 566 | c->extended_cpuid_level = xlvl; |
arch/x86/kernel/cpu/intel_cacheinfo.c
... | ... | @@ -347,8 +347,8 @@ |
347 | 347 | return l3; |
348 | 348 | } |
349 | 349 | |
350 | -static void __cpuinit | |
351 | -amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) | |
350 | +static void __cpuinit amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf, | |
351 | + int index) | |
352 | 352 | { |
353 | 353 | int node; |
354 | 354 | |
355 | 355 | |
356 | 356 | |
357 | 357 | |
... | ... | @@ -396,20 +396,39 @@ |
396 | 396 | this_leaf->l3 = l3_caches[node]; |
397 | 397 | } |
398 | 398 | |
399 | +/* | |
400 | + * check whether a slot used for disabling an L3 index is occupied. | |
401 | + * @l3: L3 cache descriptor | |
402 | + * @slot: slot number (0..1) | |
403 | + * | |
404 | + * @returns: the disabled index if used or negative value if slot free. | |
405 | + */ | |
406 | +int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot) | |
407 | +{ | |
408 | + unsigned int reg = 0; | |
409 | + | |
410 | + pci_read_config_dword(l3->dev, 0x1BC + slot * 4, ®); | |
411 | + | |
412 | + /* check whether this slot is activated already */ | |
413 | + if (reg & (3UL << 30)) | |
414 | + return reg & 0xfff; | |
415 | + | |
416 | + return -1; | |
417 | +} | |
418 | + | |
399 | 419 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, |
400 | 420 | unsigned int slot) |
401 | 421 | { |
402 | - struct pci_dev *dev = this_leaf->l3->dev; | |
403 | - unsigned int reg = 0; | |
422 | + int index; | |
404 | 423 | |
405 | 424 | if (!this_leaf->l3 || !this_leaf->l3->can_disable) |
406 | 425 | return -EINVAL; |
407 | 426 | |
408 | - if (!dev) | |
409 | - return -EINVAL; | |
427 | + index = amd_get_l3_disable_slot(this_leaf->l3, slot); | |
428 | + if (index >= 0) | |
429 | + return sprintf(buf, "%d\n", index); | |
410 | 430 | |
411 | - pci_read_config_dword(dev, 0x1BC + slot * 4, ®); | |
412 | - return sprintf(buf, "0x%08x\n", reg); | |
431 | + return sprintf(buf, "FREE\n"); | |
413 | 432 | } |
414 | 433 | |
415 | 434 | #define SHOW_CACHE_DISABLE(slot) \ |
416 | 435 | |
417 | 436 | |
418 | 437 | |
419 | 438 | |
420 | 439 | |
421 | 440 | |
... | ... | @@ -451,37 +470,74 @@ |
451 | 470 | } |
452 | 471 | } |
453 | 472 | |
454 | - | |
455 | -static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, | |
456 | - const char *buf, size_t count, | |
457 | - unsigned int slot) | |
473 | +/* | |
474 | + * disable a L3 cache index by using a disable-slot | |
475 | + * | |
476 | + * @l3: L3 cache descriptor | |
477 | + * @cpu: A CPU on the node containing the L3 cache | |
478 | + * @slot: slot number (0..1) | |
479 | + * @index: index to disable | |
480 | + * | |
481 | + * @return: 0 on success, error status on failure | |
482 | + */ | |
483 | +int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot, | |
484 | + unsigned long index) | |
458 | 485 | { |
459 | - struct pci_dev *dev = this_leaf->l3->dev; | |
460 | - int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); | |
461 | - unsigned long val = 0; | |
486 | + int ret = 0; | |
462 | 487 | |
463 | 488 | #define SUBCACHE_MASK (3UL << 20) |
464 | 489 | #define SUBCACHE_INDEX 0xfff |
465 | 490 | |
466 | - if (!this_leaf->l3 || !this_leaf->l3->can_disable) | |
491 | + /* | |
492 | + * check whether this slot is already used or | |
493 | + * the index is already disabled | |
494 | + */ | |
495 | + ret = amd_get_l3_disable_slot(l3, slot); | |
496 | + if (ret >= 0) | |
467 | 497 | return -EINVAL; |
468 | 498 | |
499 | + /* | |
500 | + * check whether the other slot has disabled the | |
501 | + * same index already | |
502 | + */ | |
503 | + if (index == amd_get_l3_disable_slot(l3, !slot)) | |
504 | + return -EINVAL; | |
505 | + | |
506 | + /* do not allow writes outside of allowed bits */ | |
507 | + if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || | |
508 | + ((index & SUBCACHE_INDEX) > l3->indices)) | |
509 | + return -EINVAL; | |
510 | + | |
511 | + amd_l3_disable_index(l3, cpu, slot, index); | |
512 | + | |
513 | + return 0; | |
514 | +} | |
515 | + | |
516 | +static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, | |
517 | + const char *buf, size_t count, | |
518 | + unsigned int slot) | |
519 | +{ | |
520 | + unsigned long val = 0; | |
521 | + int cpu, err = 0; | |
522 | + | |
469 | 523 | if (!capable(CAP_SYS_ADMIN)) |
470 | 524 | return -EPERM; |
471 | 525 | |
472 | - if (!dev) | |
526 | + if (!this_leaf->l3 || !this_leaf->l3->can_disable) | |
473 | 527 | return -EINVAL; |
474 | 528 | |
529 | + cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); | |
530 | + | |
475 | 531 | if (strict_strtoul(buf, 10, &val) < 0) |
476 | 532 | return -EINVAL; |
477 | 533 | |
478 | - /* do not allow writes outside of allowed bits */ | |
479 | - if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || | |
480 | - ((val & SUBCACHE_INDEX) > this_leaf->l3->indices)) | |
481 | - return -EINVAL; | |
482 | - | |
483 | - amd_l3_disable_index(this_leaf->l3, cpu, slot, val); | |
484 | - | |
534 | + err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val); | |
535 | + if (err) { | |
536 | + if (err == -EEXIST) | |
537 | + printk(KERN_WARNING "L3 disable slot %d in use!\n", | |
538 | + slot); | |
539 | + return err; | |
540 | + } | |
485 | 541 | return count; |
486 | 542 | } |
487 | 543 | |
... | ... | @@ -502,7 +558,7 @@ |
502 | 558 | |
503 | 559 | #else /* CONFIG_CPU_SUP_AMD */ |
504 | 560 | static void __cpuinit |
505 | -amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) | |
561 | +amd_check_l3_disable(struct _cpuid4_info_regs *this_leaf, int index) | |
506 | 562 | { |
507 | 563 | }; |
508 | 564 | #endif /* CONFIG_CPU_SUP_AMD */ |
... | ... | @@ -518,7 +574,7 @@ |
518 | 574 | |
519 | 575 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { |
520 | 576 | amd_cpuid4(index, &eax, &ebx, &ecx); |
521 | - amd_check_l3_disable(index, this_leaf); | |
577 | + amd_check_l3_disable(this_leaf, index); | |
522 | 578 | } else { |
523 | 579 | cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); |
524 | 580 | } |
arch/x86/kernel/cpu/scattered.c
1 | +/* | |
2 | + * Routines to indentify additional cpu features that are scattered in | |
3 | + * cpuid space. | |
4 | + */ | |
5 | +#include <linux/cpu.h> | |
6 | + | |
7 | +#include <asm/pat.h> | |
8 | +#include <asm/processor.h> | |
9 | + | |
10 | +#include <asm/apic.h> | |
11 | + | |
12 | +struct cpuid_bit { | |
13 | + u16 feature; | |
14 | + u8 reg; | |
15 | + u8 bit; | |
16 | + u32 level; | |
17 | + u32 sub_leaf; | |
18 | +}; | |
19 | + | |
20 | +enum cpuid_regs { | |
21 | + CR_EAX = 0, | |
22 | + CR_ECX, | |
23 | + CR_EDX, | |
24 | + CR_EBX | |
25 | +}; | |
26 | + | |
27 | +void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |
28 | +{ | |
29 | + u32 max_level; | |
30 | + u32 regs[4]; | |
31 | + const struct cpuid_bit *cb; | |
32 | + | |
33 | + static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | |
34 | + { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, | |
35 | + { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | |
36 | + { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, | |
37 | + { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, | |
38 | + { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, | |
39 | + { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, | |
40 | + { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 }, | |
41 | + { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, | |
42 | + { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, | |
43 | + { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, | |
44 | + { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, | |
45 | + { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, | |
46 | + { 0, 0, 0, 0, 0 } | |
47 | + }; | |
48 | + | |
49 | + for (cb = cpuid_bits; cb->feature; cb++) { | |
50 | + | |
51 | + /* Verify that the level is valid */ | |
52 | + max_level = cpuid_eax(cb->level & 0xffff0000); | |
53 | + if (max_level < cb->level || | |
54 | + max_level > (cb->level | 0xffff)) | |
55 | + continue; | |
56 | + | |
57 | + cpuid_count(cb->level, cb->sub_leaf, ®s[CR_EAX], | |
58 | + ®s[CR_EBX], ®s[CR_ECX], ®s[CR_EDX]); | |
59 | + | |
60 | + if (regs[cb->reg] & (1 << cb->bit)) | |
61 | + set_cpu_cap(c, cb->feature); | |
62 | + } | |
63 | +} |
arch/x86/kernel/cpu/topology.c
1 | +/* | |
2 | + * Check for extended topology enumeration cpuid leaf 0xb and if it | |
3 | + * exists, use it for populating initial_apicid and cpu topology | |
4 | + * detection. | |
5 | + */ | |
6 | + | |
7 | +#include <linux/cpu.h> | |
8 | +#include <asm/apic.h> | |
9 | +#include <asm/pat.h> | |
10 | +#include <asm/processor.h> | |
11 | + | |
12 | +/* leaf 0xb SMT level */ | |
13 | +#define SMT_LEVEL 0 | |
14 | + | |
15 | +/* leaf 0xb sub-leaf types */ | |
16 | +#define INVALID_TYPE 0 | |
17 | +#define SMT_TYPE 1 | |
18 | +#define CORE_TYPE 2 | |
19 | + | |
20 | +#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff) | |
21 | +#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) | |
22 | +#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) | |
23 | + | |
24 | +/* | |
25 | + * Check for extended topology enumeration cpuid leaf 0xb and if it | |
26 | + * exists, use it for populating initial_apicid and cpu topology | |
27 | + * detection. | |
28 | + */ | |
29 | +void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c) | |
30 | +{ | |
31 | +#ifdef CONFIG_SMP | |
32 | + unsigned int eax, ebx, ecx, edx, sub_index; | |
33 | + unsigned int ht_mask_width, core_plus_mask_width; | |
34 | + unsigned int core_select_mask, core_level_siblings; | |
35 | + static bool printed; | |
36 | + | |
37 | + if (c->cpuid_level < 0xb) | |
38 | + return; | |
39 | + | |
40 | + cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); | |
41 | + | |
42 | + /* | |
43 | + * check if the cpuid leaf 0xb is actually implemented. | |
44 | + */ | |
45 | + if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) | |
46 | + return; | |
47 | + | |
48 | + set_cpu_cap(c, X86_FEATURE_XTOPOLOGY); | |
49 | + | |
50 | + /* | |
51 | + * initial apic id, which also represents 32-bit extended x2apic id. | |
52 | + */ | |
53 | + c->initial_apicid = edx; | |
54 | + | |
55 | + /* | |
56 | + * Populate HT related information from sub-leaf level 0. | |
57 | + */ | |
58 | + core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); | |
59 | + core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | |
60 | + | |
61 | + sub_index = 1; | |
62 | + do { | |
63 | + cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx); | |
64 | + | |
65 | + /* | |
66 | + * Check for the Core type in the implemented sub leaves. | |
67 | + */ | |
68 | + if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) { | |
69 | + core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); | |
70 | + core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | |
71 | + break; | |
72 | + } | |
73 | + | |
74 | + sub_index++; | |
75 | + } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); | |
76 | + | |
77 | + core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; | |
78 | + | |
79 | + c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width) | |
80 | + & core_select_mask; | |
81 | + c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width); | |
82 | + /* | |
83 | + * Reinit the apicid, now that we have extended initial_apicid. | |
84 | + */ | |
85 | + c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); | |
86 | + | |
87 | + c->x86_max_cores = (core_level_siblings / smp_num_siblings); | |
88 | + | |
89 | + if (!printed) { | |
90 | + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", | |
91 | + c->phys_proc_id); | |
92 | + if (c->x86_max_cores > 1) | |
93 | + printk(KERN_INFO "CPU: Processor Core ID: %d\n", | |
94 | + c->cpu_core_id); | |
95 | + printed = 1; | |
96 | + } | |
97 | + return; | |
98 | +#endif | |
99 | +} |
arch/x86/kernel/process.c
... | ... | @@ -526,44 +526,10 @@ |
526 | 526 | return (edx & MWAIT_EDX_C1); |
527 | 527 | } |
528 | 528 | |
529 | -/* | |
530 | - * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e. | |
531 | - * For more information see | |
532 | - * - Erratum #400 for NPT family 0xf and family 0x10 CPUs | |
533 | - * - Erratum #365 for family 0x11 (not affected because C1e not in use) | |
534 | - */ | |
535 | -static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | |
536 | -{ | |
537 | - u64 val; | |
538 | - if (c->x86_vendor != X86_VENDOR_AMD) | |
539 | - goto no_c1e_idle; | |
529 | +bool c1e_detected; | |
530 | +EXPORT_SYMBOL(c1e_detected); | |
540 | 531 | |
541 | - /* Family 0x0f models < rev F do not have C1E */ | |
542 | - if (c->x86 == 0x0F && c->x86_model >= 0x40) | |
543 | - return 1; | |
544 | - | |
545 | - if (c->x86 == 0x10) { | |
546 | - /* | |
547 | - * check OSVW bit for CPUs that are not affected | |
548 | - * by erratum #400 | |
549 | - */ | |
550 | - if (cpu_has(c, X86_FEATURE_OSVW)) { | |
551 | - rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); | |
552 | - if (val >= 2) { | |
553 | - rdmsrl(MSR_AMD64_OSVW_STATUS, val); | |
554 | - if (!(val & BIT(1))) | |
555 | - goto no_c1e_idle; | |
556 | - } | |
557 | - } | |
558 | - return 1; | |
559 | - } | |
560 | - | |
561 | -no_c1e_idle: | |
562 | - return 0; | |
563 | -} | |
564 | - | |
565 | 532 | static cpumask_var_t c1e_mask; |
566 | -static int c1e_detected; | |
567 | 533 | |
568 | 534 | void c1e_remove_cpu(int cpu) |
569 | 535 | { |
570 | 536 | |
571 | 537 | |
... | ... | @@ -585,12 +551,12 @@ |
585 | 551 | u32 lo, hi; |
586 | 552 | |
587 | 553 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); |
554 | + | |
588 | 555 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { |
589 | - c1e_detected = 1; | |
556 | + c1e_detected = true; | |
590 | 557 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
591 | 558 | mark_tsc_unstable("TSC halt in AMD C1E"); |
592 | 559 | printk(KERN_INFO "System has AMD C1E enabled\n"); |
593 | - set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E); | |
594 | 560 | } |
595 | 561 | } |
596 | 562 | |
... | ... | @@ -639,7 +605,8 @@ |
639 | 605 | */ |
640 | 606 | printk(KERN_INFO "using mwait in idle threads.\n"); |
641 | 607 | pm_idle = mwait_idle; |
642 | - } else if (check_c1e_idle(c)) { | |
608 | + } else if (cpu_has_amd_erratum(amd_erratum_400)) { | |
609 | + /* E400: APIC timer interrupt does not wake up CPU from C1e */ | |
643 | 610 | printk(KERN_INFO "using C1E aware idle routine\n"); |
644 | 611 | pm_idle = c1e_idle; |
645 | 612 | } else |
arch/x86/kernel/xsave.c
... | ... | @@ -36,15 +36,14 @@ |
36 | 36 | |
37 | 37 | err = __copy_from_user(fx_sw_user, &buf->sw_reserved[0], |
38 | 38 | sizeof(struct _fpx_sw_bytes)); |
39 | - | |
40 | 39 | if (err) |
41 | - return err; | |
40 | + return -EFAULT; | |
42 | 41 | |
43 | 42 | /* |
44 | 43 | * First Magic check failed. |
45 | 44 | */ |
46 | 45 | if (fx_sw_user->magic1 != FP_XSTATE_MAGIC1) |
47 | - return -1; | |
46 | + return -EINVAL; | |
48 | 47 | |
49 | 48 | /* |
50 | 49 | * Check for error scenarios. |
51 | 50 | |
52 | 51 | |
... | ... | @@ -52,19 +51,21 @@ |
52 | 51 | if (fx_sw_user->xstate_size < min_xstate_size || |
53 | 52 | fx_sw_user->xstate_size > xstate_size || |
54 | 53 | fx_sw_user->xstate_size > fx_sw_user->extended_size) |
55 | - return -1; | |
54 | + return -EINVAL; | |
56 | 55 | |
57 | 56 | err = __get_user(magic2, (__u32 *) (((void *)fpstate) + |
58 | 57 | fx_sw_user->extended_size - |
59 | 58 | FP_XSTATE_MAGIC2_SIZE)); |
59 | + if (err) | |
60 | + return err; | |
60 | 61 | /* |
61 | 62 | * Check for the presence of second magic word at the end of memory |
62 | 63 | * layout. This detects the case where the user just copied the legacy |
63 | 64 | * fpstate layout with out copying the extended state information |
64 | 65 | * in the memory layout. |
65 | 66 | */ |
66 | - if (err || magic2 != FP_XSTATE_MAGIC2) | |
67 | - return -1; | |
67 | + if (magic2 != FP_XSTATE_MAGIC2) | |
68 | + return -EFAULT; | |
68 | 69 | |
69 | 70 | return 0; |
70 | 71 | } |
arch/x86/kvm/svm.c