On Fri, Oct 27, 2023 at 07:38:40AM -0700, Pawan Gupta wrote: > MDS mitigation requires clearing the CPU buffers before returning to > user. This needs to be done late in the exit-to-user path. Current > location of VERW leaves a possibility of kernel data ending up in CPU > buffers for memory accesses done after VERW such as: > > 1. Kernel data accessed by an NMI between VERW and return-to-user can > remain in CPU buffers ( since NMI returning to kernel does not Some leftover '(' > execute VERW to clear CPU buffers. > 2. Alyssa reported that after VERW is executed, > CONFIG_GCC_PLUGIN_STACKLEAK=y scrubs the stack used by a system > call. Memory accesses during stack scrubbing can move kernel stack > contents into CPU buffers. > 3. When caller saved registers are restored after a return from > function executing VERW, the kernel stack accesses can remain in > CPU buffers(since they occur after VERW). > > To fix this VERW needs to be moved very late in exit-to-user path. > > In preparation for moving VERW to entry/exit asm code, create macros > that can be used in asm. Also make them depend on a new feature flag > X86_FEATURE_CLEAR_CPU_BUF. The macros don't depend on the feature flag - VERW patching is done based on it. > @@ -20,3 +23,17 @@ SYM_FUNC_END(entry_ibpb) > EXPORT_SYMBOL_GPL(entry_ibpb); > > .popsection > + > +.pushsection .entry.text, "ax" > + > +.align L1_CACHE_BYTES, 0xcc > +SYM_CODE_START_NOALIGN(mds_verw_sel) That weird thing needs a comment explaining what it is for. > + UNWIND_HINT_UNDEFINED > + ANNOTATE_NOENDBR > + .word __KERNEL_DS > +.align L1_CACHE_BYTES, 0xcc > +SYM_CODE_END(mds_verw_sel); > +/* For KVM */ > +EXPORT_SYMBOL_GPL(mds_verw_sel); > + > +.popsection > diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h > index 58cb9495e40f..f21fc0f12737 100644 > --- a/arch/x86/include/asm/cpufeatures.h > +++ b/arch/x86/include/asm/cpufeatures.h > @@ -308,10 +308,10 @@ > #define X86_FEATURE_SMBA (11*32+21) /* "" Slow Memory Bandwidth Allocation */ > #define X86_FEATURE_BMEC (11*32+22) /* "" Bandwidth Monitoring Event Configuration */ > #define X86_FEATURE_USER_SHSTK (11*32+23) /* Shadow stack support for user mode applications */ > - > #define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */ > #define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */ > #define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */ > +#define X86_FEATURE_CLEAR_CPU_BUF (11*32+27) /* "" Clear CPU buffers */ ... using VERW > > /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ > #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ > diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h > index c55cc243592e..005e69f93115 100644 > --- a/arch/x86/include/asm/nospec-branch.h > +++ b/arch/x86/include/asm/nospec-branch.h > @@ -329,6 +329,21 @@ > #endif > .endm > > +/* > + * Macros to execute VERW instruction that mitigate transient data sampling > + * attacks such as MDS. On affected systems a microcode update overloaded VERW > + * instruction to also clear the CPU buffers. VERW clobbers CFLAGS.ZF. > + * > + * Note: Only the memory operand variant of VERW clears the CPU buffers. > + */ > +.macro EXEC_VERW > + verw _ASM_RIP(mds_verw_sel) > +.endm > + > +.macro CLEAR_CPU_BUFFERS > + ALTERNATIVE "", __stringify(EXEC_VERW), X86_FEATURE_CLEAR_CPU_BUF > +.endm Why can't this simply be: .macro CLEAR_CPU_BUFFERS ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF .endm without that silly EXEC_VERW macro? -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette