diff options
author | Borislav Petkov <bp@suse.de> | 2013-03-20 10:07:23 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2013-04-02 13:12:52 -0400 |
commit | 65fc985b37dc241c4db7cd32adcbc989193fe3c8 (patch) | |
tree | b530d4cb1b0a42ad8c220639aa7f9f970e8774df | |
parent | 07961ac7c0ee8b546658717034fe692fd12eefa9 (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.h | 13 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/alternative.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 4 |
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. */ |