diff options
author | Borislav Petkov <bp@suse.de> | 2014-06-24 07:25:03 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-07-14 15:21:39 -0400 |
commit | 80a208bd3948aceddf0429bd9f9b4cd858d526df (patch) | |
tree | 06bd3dd2f9f6d73ce63da9852ca7d8d57f9599c6 /arch | |
parent | 9b13a93df267af681a66a6a738bf1af10102da7d (diff) |
x86/cpufeature: Add bug flags to /proc/cpuinfo
Dump the flags which denote we have detected and/or have applied bug
workarounds to the CPU we're executing on, in a similar manner to the
feature flags.
The advantage is that those are not accumulating over time like the CPU
features.
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1403609105-8332-2-git-send-email-bp@alien8.de
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mkcapflags.sh | 51 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/proc.c | 8 |
3 files changed, 53 insertions, 16 deletions
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 52df22bde0dd..327a061f32df 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -239,8 +239,8 @@ | |||
239 | #define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ | 239 | #define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ |
240 | #define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ | 240 | #define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ |
241 | #define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ | 241 | #define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ |
242 | #define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* AMD Erratum 383 */ | 242 | #define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ |
243 | #define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* AMD Erratum 400 */ | 243 | #define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ |
244 | #define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ | 244 | #define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ |
245 | #define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ | 245 | #define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ |
246 | #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ | 246 | #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ |
@@ -253,6 +253,12 @@ | |||
253 | extern const char * const x86_cap_flags[NCAPINTS*32]; | 253 | extern const char * const x86_cap_flags[NCAPINTS*32]; |
254 | extern const char * const x86_power_flags[32]; | 254 | extern const char * const x86_power_flags[32]; |
255 | 255 | ||
256 | /* | ||
257 | * In order to save room, we index into this array by doing | ||
258 | * X86_BUG_<name> - NCAPINTS*32. | ||
259 | */ | ||
260 | extern const char * const x86_bug_flags[NBUGINTS*32]; | ||
261 | |||
256 | #define test_cpu_cap(c, bit) \ | 262 | #define test_cpu_cap(c, bit) \ |
257 | test_bit(bit, (unsigned long *)((c)->x86_capability)) | 263 | test_bit(bit, (unsigned long *)((c)->x86_capability)) |
258 | 264 | ||
diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index 2bf616505499..e2b22df964cd 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh | |||
@@ -1,23 +1,25 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # | 2 | # |
3 | # Generate the x86_cap_flags[] array from include/asm/cpufeature.h | 3 | # Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h |
4 | # | 4 | # |
5 | 5 | ||
6 | IN=$1 | 6 | IN=$1 |
7 | OUT=$2 | 7 | OUT=$2 |
8 | 8 | ||
9 | TABS="$(printf '\t\t\t\t\t')" | 9 | function dump_array() |
10 | trap 'rm "$OUT"' EXIT | 10 | { |
11 | ARRAY=$1 | ||
12 | SIZE=$2 | ||
13 | PFX=$3 | ||
14 | POSTFIX=$4 | ||
11 | 15 | ||
12 | ( | 16 | PFX_SZ=$(echo $PFX | wc -c) |
13 | echo "#ifndef _ASM_X86_CPUFEATURE_H" | 17 | TABS="$(printf '\t\t\t\t\t')" |
14 | echo "#include <asm/cpufeature.h>" | 18 | |
15 | echo "#endif" | 19 | echo "const char * const $ARRAY[$SIZE] = {" |
16 | echo "" | ||
17 | echo "const char * const x86_cap_flags[NCAPINTS*32] = {" | ||
18 | 20 | ||
19 | # Iterate through any input lines starting with #define X86_FEATURE_ | 21 | # Iterate through any input lines starting with #define $PFX |
20 | sed -n -e 's/\t/ /g' -e 's/^ *# *define *X86_FEATURE_//p' $IN | | 22 | sed -n -e 's/\t/ /g' -e "s/^ *# *define *$PFX//p" $IN | |
21 | while read i | 23 | while read i |
22 | do | 24 | do |
23 | # Name is everything up to the first whitespace | 25 | # Name is everything up to the first whitespace |
@@ -31,11 +33,32 @@ trap 'rm "$OUT"' EXIT | |||
31 | # Name is uppercase, VALUE is all lowercase | 33 | # Name is uppercase, VALUE is all lowercase |
32 | VALUE="$(echo "$VALUE" | tr A-Z a-z)" | 34 | VALUE="$(echo "$VALUE" | tr A-Z a-z)" |
33 | 35 | ||
34 | TABCOUNT=$(( ( 5*8 - 14 - $(echo "$NAME" | wc -c) ) / 8 )) | 36 | if [ -n "$POSTFIX" ]; then |
35 | printf "\t[%s]%.*s = %s,\n" \ | 37 | T=$(( $PFX_SZ + $(echo $POSTFIX | wc -c) + 2 )) |
36 | "X86_FEATURE_$NAME" "$TABCOUNT" "$TABS" "$VALUE" | 38 | TABS="$(printf '\t\t\t\t\t\t')" |
39 | TABCOUNT=$(( ( 6*8 - ($T + 1) - $(echo "$NAME" | wc -c) ) / 8 )) | ||
40 | printf "\t[%s - %s]%.*s = %s,\n" "$PFX$NAME" "$POSTFIX" "$TABCOUNT" "$TABS" "$VALUE" | ||
41 | else | ||
42 | TABCOUNT=$(( ( 5*8 - ($PFX_SZ + 1) - $(echo "$NAME" | wc -c) ) / 8 )) | ||
43 | printf "\t[%s]%.*s = %s,\n" "$PFX$NAME" "$TABCOUNT" "$TABS" "$VALUE" | ||
44 | fi | ||
37 | done | 45 | done |
38 | echo "};" | 46 | echo "};" |
47 | } | ||
48 | |||
49 | trap 'rm "$OUT"' EXIT | ||
50 | |||
51 | ( | ||
52 | echo "#ifndef _ASM_X86_CPUFEATURE_H" | ||
53 | echo "#include <asm/cpufeature.h>" | ||
54 | echo "#endif" | ||
55 | echo "" | ||
56 | |||
57 | dump_array "x86_cap_flags" "NCAPINTS*32" "X86_FEATURE_" "" | ||
58 | echo "" | ||
59 | |||
60 | dump_array "x86_bug_flags" "NBUGINTS*32" "X86_BUG_" "NCAPINTS*32" | ||
61 | |||
39 | ) > $OUT | 62 | ) > $OUT |
40 | 63 | ||
41 | trap - EXIT | 64 | trap - EXIT |
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 06fe3ed8b851..5433658e598d 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
@@ -97,6 +97,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
97 | if (cpu_has(c, i) && x86_cap_flags[i] != NULL) | 97 | if (cpu_has(c, i) && x86_cap_flags[i] != NULL) |
98 | seq_printf(m, " %s", x86_cap_flags[i]); | 98 | seq_printf(m, " %s", x86_cap_flags[i]); |
99 | 99 | ||
100 | seq_printf(m, "\nbugs\t\t:"); | ||
101 | for (i = 0; i < 32*NBUGINTS; i++) { | ||
102 | unsigned int bug_bit = 32*NCAPINTS + i; | ||
103 | |||
104 | if (cpu_has_bug(c, bug_bit) && x86_bug_flags[i]) | ||
105 | seq_printf(m, " %s", x86_bug_flags[i]); | ||
106 | } | ||
107 | |||
100 | seq_printf(m, "\nbogomips\t: %lu.%02lu\n", | 108 | seq_printf(m, "\nbogomips\t: %lu.%02lu\n", |
101 | c->loops_per_jiffy/(500000/HZ), | 109 | c->loops_per_jiffy/(500000/HZ), |
102 | (c->loops_per_jiffy/(5000/HZ)) % 100); | 110 | (c->loops_per_jiffy/(5000/HZ)) % 100); |