Skip to content

Commit 8779347

Browse files
committed
Merge tag 'x86_cpu_for_v6.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cpuid updates from Borislav Petkov: - Cache the AMD debug registers in per-CPU variables to avoid MSR writes where possible, when supporting a debug registers swap feature for SEV-ES guests - Add support for AMD's version of eIBRS called Automatic IBRS which is a set-and-forget control of indirect branch restriction speculation resources on privilege change - Add support for a new x86 instruction - LKGS - Load kernel GS which is part of the FRED infrastructure - Reset SPEC_CTRL upon init to accomodate use cases like kexec which rediscover - Other smaller fixes and cleanups * tag 'x86_cpu_for_v6.3_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/amd: Cache debug register values in percpu variables KVM: x86: Propagate the AMD Automatic IBRS feature to the guest x86/cpu: Support AMD Automatic IBRS x86/cpu, kvm: Add the SMM_CTL MSR not present feature x86/cpu, kvm: Add the Null Selector Clears Base feature x86/cpu, kvm: Move X86_FEATURE_LFENCE_RDTSC to its native leaf x86/cpu, kvm: Add the NO_NESTED_DATA_BP feature KVM: x86: Move open-coded CPUID leaf 0x80000021 EAX bit propagation code x86/cpu, kvm: Add support for CPUID_80000021_EAX x86/gsseg: Add the new <asm/gsseg.h> header to <asm/asm-prototypes.h> x86/gsseg: Use the LKGS instruction if available for load_gs_index() x86/gsseg: Move load_gs_index() to its own new header file x86/gsseg: Make asm_load_gs_index() take an u16 x86/opcode: Add the LKGS instruction to x86-opcode-map x86/cpufeature: Add the CPU feature bit for LKGS x86/bugs: Reset speculation control settings on init x86/cpu: Remove redundant extern x86_read_arch_cap_msr()
2 parents 74e19ef + 7914695 commit 8779347

30 files changed

+218
-94
lines changed

Documentation/admin-guide/hw-vuln/spectre.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,9 @@ kernel command line.
610610
retpoline,generic Retpolines
611611
retpoline,lfence LFENCE; indirect branch
612612
retpoline,amd alias for retpoline,lfence
613-
eibrs enhanced IBRS
614-
eibrs,retpoline enhanced IBRS + Retpolines
615-
eibrs,lfence enhanced IBRS + LFENCE
613+
eibrs Enhanced/Auto IBRS
614+
eibrs,retpoline Enhanced/Auto IBRS + Retpolines
615+
eibrs,lfence Enhanced/Auto IBRS + LFENCE
616616
ibrs use IBRS to protect kernel
617617

618618
Not specifying this option is equivalent to

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5740,9 +5740,9 @@
57405740
retpoline,generic - Retpolines
57415741
retpoline,lfence - LFENCE; indirect branch
57425742
retpoline,amd - alias for retpoline,lfence
5743-
eibrs - enhanced IBRS
5744-
eibrs,retpoline - enhanced IBRS + Retpolines
5745-
eibrs,lfence - enhanced IBRS + LFENCE
5743+
eibrs - Enhanced/Auto IBRS
5744+
eibrs,retpoline - Enhanced/Auto IBRS + Retpolines
5745+
eibrs,lfence - Enhanced/Auto IBRS + LFENCE
57465746
ibrs - use IBRS to protect kernel
57475747

57485748
Not specifying this option is equivalent to

arch/x86/entry/entry_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ _ASM_NOKPROBE(common_interrupt_return)
782782

783783
/*
784784
* Reload gs selector with exception handling
785-
* edi: new selector
785+
* di: new selector
786786
*
787787
* Is in entry.text as it shouldn't be instrumented.
788788
*/

arch/x86/include/asm/asm-prototypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/special_insns.h>
1313
#include <asm/preempt.h>
1414
#include <asm/asm.h>
15+
#include <asm/gsseg.h>
1516

1617
#ifndef CONFIG_X86_CMPXCHG64
1718
extern void cmpxchg8b_emu(void);

arch/x86/include/asm/cpufeature.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ enum cpuid_leafs
3232
CPUID_8000_0007_EBX,
3333
CPUID_7_EDX,
3434
CPUID_8000_001F_EAX,
35+
CPUID_8000_0021_EAX,
3536
};
3637

3738
#define X86_CAP_FMT_NUM "%d:%d"
@@ -94,8 +95,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
9495
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \
9596
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
9697
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
98+
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
9799
REQUIRED_MASK_CHECK || \
98-
BUILD_BUG_ON_ZERO(NCAPINTS != 20))
100+
BUILD_BUG_ON_ZERO(NCAPINTS != 21))
99101

100102
#define DISABLED_MASK_BIT_SET(feature_bit) \
101103
( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
@@ -118,8 +120,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
118120
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \
119121
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
120122
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
123+
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
121124
DISABLED_MASK_CHECK || \
122-
BUILD_BUG_ON_ZERO(NCAPINTS != 20))
125+
BUILD_BUG_ON_ZERO(NCAPINTS != 21))
123126

124127
#define cpu_has(c, bit) \
125128
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \

arch/x86/include/asm/cpufeatures.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
/*
1414
* Defines x86 CPU feature bits
1515
*/
16-
#define NCAPINTS 20 /* N 32-bit words worth of info */
16+
#define NCAPINTS 21 /* N 32-bit words worth of info */
1717
#define NBUGINTS 1 /* N 32-bit bug flags */
1818

1919
/*
@@ -97,7 +97,7 @@
9797
#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */
9898
#define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */
9999
#define X86_FEATURE_AMD_LBR_V2 ( 3*32+17) /* AMD Last Branch Record Extension Version 2 */
100-
#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */
100+
/* FREE, was #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) "" LFENCE synchronizes RDTSC */
101101
#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
102102
#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
103103
#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
@@ -315,6 +315,7 @@
315315
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */
316316
#define X86_FEATURE_CMPCCXADD (12*32+ 7) /* "" CMPccXADD instructions */
317317
#define X86_FEATURE_ARCH_PERFMON_EXT (12*32+ 8) /* "" Intel Architectural PerfMon Extension */
318+
#define X86_FEATURE_LKGS (12*32+18) /* "" Load "kernel" (userspace) GS */
318319
#define X86_FEATURE_AMX_FP16 (12*32+21) /* "" AMX fp16 Support */
319320
#define X86_FEATURE_AVX_IFMA (12*32+23) /* "" Support for VPMADD52[H,L]UQ */
320321

@@ -429,6 +430,13 @@
429430
#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* "" Virtual TSC_AUX */
430431
#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
431432

433+
/* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */
434+
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* "" No Nested Data Breakpoints */
435+
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* "" LFENCE always serializing / synchronizes RDTSC */
436+
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* "" Null Selector Clears Base */
437+
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
438+
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* "" SMM_CTL MSR is not present */
439+
432440
/*
433441
* BUG word(s)
434442
*/

arch/x86/include/asm/debugreg.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,14 @@ static __always_inline void local_db_restore(unsigned long dr7)
148148
}
149149

150150
#ifdef CONFIG_CPU_SUP_AMD
151-
extern void set_dr_addr_mask(unsigned long mask, int dr);
151+
extern void amd_set_dr_addr_mask(unsigned long mask, unsigned int dr);
152+
extern unsigned long amd_get_dr_addr_mask(unsigned int dr);
152153
#else
153-
static inline void set_dr_addr_mask(unsigned long mask, int dr) { }
154+
static inline void amd_set_dr_addr_mask(unsigned long mask, unsigned int dr) { }
155+
static inline unsigned long amd_get_dr_addr_mask(unsigned int dr)
156+
{
157+
return 0;
158+
}
154159
#endif
155160

156161
#endif /* _ASM_X86_DEBUGREG_H */

arch/x86/include/asm/disabled-features.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
#define DISABLED_MASK17 0
125125
#define DISABLED_MASK18 0
126126
#define DISABLED_MASK19 0
127-
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 20)
127+
#define DISABLED_MASK20 0
128+
#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
128129

129130
#endif /* _ASM_X86_DISABLED_FEATURES_H */

arch/x86/include/asm/gsseg.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef _ASM_X86_GSSEG_H
3+
#define _ASM_X86_GSSEG_H
4+
5+
#include <linux/types.h>
6+
7+
#include <asm/asm.h>
8+
#include <asm/cpufeature.h>
9+
#include <asm/alternative.h>
10+
#include <asm/processor.h>
11+
#include <asm/nops.h>
12+
13+
#ifdef CONFIG_X86_64
14+
15+
extern asmlinkage void asm_load_gs_index(u16 selector);
16+
17+
/* Replace with "lkgs %di" once binutils support LKGS instruction */
18+
#define LKGS_DI _ASM_BYTES(0xf2,0x0f,0x00,0xf7)
19+
20+
static inline void native_lkgs(unsigned int selector)
21+
{
22+
u16 sel = selector;
23+
asm_inline volatile("1: " LKGS_DI
24+
_ASM_EXTABLE_TYPE_REG(1b, 1b, EX_TYPE_ZERO_REG, %k[sel])
25+
: [sel] "+D" (sel));
26+
}
27+
28+
static inline void native_load_gs_index(unsigned int selector)
29+
{
30+
if (cpu_feature_enabled(X86_FEATURE_LKGS)) {
31+
native_lkgs(selector);
32+
} else {
33+
unsigned long flags;
34+
35+
local_irq_save(flags);
36+
asm_load_gs_index(selector);
37+
local_irq_restore(flags);
38+
}
39+
}
40+
41+
#endif /* CONFIG_X86_64 */
42+
43+
static inline void __init lkgs_init(void)
44+
{
45+
#ifdef CONFIG_PARAVIRT_XXL
46+
#ifdef CONFIG_X86_64
47+
if (cpu_feature_enabled(X86_FEATURE_LKGS))
48+
pv_ops.cpu.load_gs_index = native_lkgs;
49+
#endif
50+
#endif
51+
}
52+
53+
#ifndef CONFIG_PARAVIRT_XXL
54+
55+
static inline void load_gs_index(unsigned int selector)
56+
{
57+
#ifdef CONFIG_X86_64
58+
native_load_gs_index(selector);
59+
#else
60+
loadsegment(gs, selector);
61+
#endif
62+
}
63+
64+
#endif /* CONFIG_PARAVIRT_XXL */
65+
66+
#endif /* _ASM_X86_GSSEG_H */

arch/x86/include/asm/mmu_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/tlbflush.h>
1313
#include <asm/paravirt.h>
1414
#include <asm/debugreg.h>
15+
#include <asm/gsseg.h>
1516

1617
extern atomic64_t last_mm_ctx_id;
1718

0 commit comments

Comments
 (0)