aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-03-20 10:07:23 -0400
committerH. Peter Anvin <hpa@zytor.com>2013-04-02 13:12:52 -0400
commit65fc985b37dc241c4db7cd32adcbc989193fe3c8 (patch)
treeb530d4cb1b0a42ad8c220639aa7f9f970e8774df
parent07961ac7c0ee8b546658717034fe692fd12eefa9 (diff)
x86, cpu: Expand cpufeature facility to include cpu bugs
We add another 32-bit vector at the end of the ->x86_capability bitvector which collects bugs present in CPUs. After all, a CPU bug is a kind of a capability, albeit a strange one. Signed-off-by: Borislav Petkov <bp@suse.de> Link: http://lkml.kernel.org/r/1363788448-31325-2-git-send-email-bp@alien8.de Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/x86/include/asm/cpufeature.h13
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/kernel/alternative.c2
-rw-r--r--arch/x86/kernel/cpu/common.c4
4 files changed, 19 insertions, 2 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 93fe929d1cee..16190abd8905 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -9,6 +9,7 @@
9#endif 9#endif
10 10
11#define NCAPINTS 10 /* N 32-bit words worth of info */ 11#define NCAPINTS 10 /* N 32-bit words worth of info */
12#define NBUGINTS 1 /* N 32-bit bug flags */
12 13
13/* 14/*
14 * Note: If the comment begins with a quoted string, that string is used 15 * Note: If the comment begins with a quoted string, that string is used
@@ -216,6 +217,11 @@
216#define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ 217#define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */
217#define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */ 218#define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */
218 219
220/*
221 * BUG word(s)
222 */
223#define X86_BUG(x) (NCAPINTS*32 + (x))
224
219#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 225#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
220 226
221#include <asm/asm.h> 227#include <asm/asm.h>
@@ -401,6 +407,13 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
401#define static_cpu_has(bit) boot_cpu_has(bit) 407#define static_cpu_has(bit) boot_cpu_has(bit)
402#endif 408#endif
403 409
410#define cpu_has_bug(c, bit) cpu_has(c, (bit))
411#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
412#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit));
413
414#define static_cpu_has_bug(bit) static_cpu_has((bit))
415#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
416
404#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ 417#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
405 418
406#endif /* _ASM_X86_CPUFEATURE_H */ 419#endif /* _ASM_X86_CPUFEATURE_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 3270116b1488..23c8081d3870 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -107,7 +107,7 @@ struct cpuinfo_x86 {
107 __u32 extended_cpuid_level; 107 __u32 extended_cpuid_level;
108 /* Maximum supported CPUID level, -1=no CPUID: */ 108 /* Maximum supported CPUID level, -1=no CPUID: */
109 int cpuid_level; 109 int cpuid_level;
110 __u32 x86_capability[NCAPINTS]; 110 __u32 x86_capability[NCAPINTS + NBUGINTS];
111 char x86_vendor_id[16]; 111 char x86_vendor_id[16];
112 char x86_model_id[64]; 112 char x86_model_id[64];
113 /* in KB - valid for CPUS which support this call: */ 113 /* in KB - valid for CPUS which support this call: */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index ef5ccca79a6c..c15cf9a25e27 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -271,7 +271,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
271 replacement = (u8 *)&a->repl_offset + a->repl_offset; 271 replacement = (u8 *)&a->repl_offset + a->repl_offset;
272 BUG_ON(a->replacementlen > a->instrlen); 272 BUG_ON(a->replacementlen > a->instrlen);
273 BUG_ON(a->instrlen > sizeof(insnbuf)); 273 BUG_ON(a->instrlen > sizeof(insnbuf));
274 BUG_ON(a->cpuid >= NCAPINTS*32); 274 BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32);
275 if (!boot_cpu_has(a->cpuid)) 275 if (!boot_cpu_has(a->cpuid))
276 continue; 276 continue;
277 277
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d814772c5bed..22018f70a671 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -920,6 +920,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
920 /* AND the already accumulated flags with these */ 920 /* AND the already accumulated flags with these */
921 for (i = 0; i < NCAPINTS; i++) 921 for (i = 0; i < NCAPINTS; i++)
922 boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; 922 boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
923
924 /* OR, i.e. replicate the bug flags */
925 for (i = NCAPINTS; i < NCAPINTS + NBUGINTS; i++)
926 c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
923 } 927 }
924 928
925 /* Init Machine Check Exception if available. */ 929 /* Init Machine Check Exception if available. */