[PATCH 3.2 032/104] x86, cpu: Expand cpufeature facility to include cpu bugs

From: Ben Hutchings
Date: Sun Mar 11 2018 - 23:44:23 EST


3.2.101-rc1 review patch. If anyone has any objections, please let me know.

------------------

From: Borislav Petkov <bp@xxxxxxx>

commit 65fc985b37dc241c4db7cd32adcbc989193fe3c8 upstream.

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@xxxxxxx>
Link: http://lkml.kernel.org/r/1363788448-31325-2-git-send-email-bp@xxxxxxxxx
Signed-off-by: H. Peter Anvin <hpa@xxxxxxxxx>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
---
arch/x86/include/asm/cpufeature.h | 13 +++++++++++++
arch/x86/include/asm/processor.h | 2 +-
arch/x86/kernel/alternative.c | 2 +-
arch/x86/kernel/cpu/common.c | 4 ++++
4 files changed, 19 insertions(+), 2 deletions(-)

--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -7,6 +7,7 @@
#include <asm/required-features.h>

#define NCAPINTS 10 /* N 32-bit words worth of info */
+#define NBUGINTS 1 /* N 32-bit bug flags */

/*
* Note: If the comment begins with a quoted string, that string is used
@@ -208,6 +209,11 @@
#define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */
#define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */

+/*
+ * BUG word(s)
+ */
+#define X86_BUG(x) (NCAPINTS*32 + (x))
+
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)

#include <asm/asm.h>
@@ -397,6 +403,13 @@ static __always_inline __pure bool __sta
#define static_cpu_has(bit) boot_cpu_has(bit)
#endif

+#define cpu_has_bug(c, bit) cpu_has(c, (bit))
+#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
+#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit));
+
+#define static_cpu_has_bug(bit) static_cpu_has((bit))
+#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
+
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */

#endif /* _ASM_X86_CPUFEATURE_H */
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -86,7 +86,7 @@ struct cpuinfo_x86 {
__u32 extended_cpuid_level;
/* Maximum supported CPUID level, -1=no CPUID: */
int cpuid_level;
- __u32 x86_capability[NCAPINTS];
+ __u32 x86_capability[NCAPINTS + NBUGINTS];
char x86_vendor_id[16];
char x86_model_id[64];
/* in KB - valid for CPUS which support this call: */
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -359,7 +359,7 @@ void __init_or_module apply_alternatives
instr = (u8 *)&a->instr_offset + a->instr_offset;
replacement = (u8 *)&a->repl_offset + a->repl_offset;
BUG_ON(a->instrlen > sizeof(insnbuf));
- BUG_ON(a->cpuid >= NCAPINTS*32);
+ BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32);
if (!boot_cpu_has(a->cpuid)) {
if (a->padlen > 1)
optimize_nops(a, instr);
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -954,6 +954,10 @@ static void __cpuinit identify_cpu(struc
/* AND the already accumulated flags with these */
for (i = 0; i < NCAPINTS; i++)
boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
+
+ /* OR, i.e. replicate the bug flags */
+ for (i = NCAPINTS; i < NCAPINTS + NBUGINTS; i++)
+ c->x86_capability[i] |= boot_cpu_data.x86_capability[i];
}

/* Init Machine Check Exception if available. */