Messages in this thread | | | Date | Mon, 10 Oct 2022 21:20:58 -0700 | From | "H. Peter Anvin" <> | Subject | Re: [PATCH v2 6/6] x86/gsseg: use the LKGS instruction if available for load gs index() |
| |
On October 10, 2022 8:51:33 PM PDT, Brian Gerst <brgerst@gmail.com> wrote: >On Mon, Oct 10, 2022 at 3:46 PM Xin Li <xin3.li@intel.com> wrote: >> >> From: "H. Peter Anvin (Intel)" <hpa@zytor.com> >> >> The LKGS instruction atomically loads a segment descriptor into the >> %gs descriptor registers, *except* that %gs.base is unchanged, and the >> base is instead loaded into MSR_IA32_KERNEL_GS_BASE, which is exactly >> what we want this function to do. >> >> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> >> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> >> Signed-off-by: Xin Li <xin3.li@intel.com> >> link: https://lkml.org/lkml/2022/10/7/352 >> link: https://lkml.org/lkml/2022/10/7/373 >> --- >> arch/x86/include/asm/gsseg.h | 27 ++++++++++++++++++++++++++- >> 1 file changed, 26 insertions(+), 1 deletion(-) >> >> diff --git a/arch/x86/include/asm/gsseg.h b/arch/x86/include/asm/gsseg.h >> index 5e3b56a17098..4aaef7a1d68f 100644 >> --- a/arch/x86/include/asm/gsseg.h >> +++ b/arch/x86/include/asm/gsseg.h >> @@ -3,15 +3,40 @@ >> #define _ASM_X86_GSSEG_H >> >> #include <linux/types.h> >> + >> +#include <asm/asm.h> >> +#include <asm/cpufeature.h> >> +#include <asm/alternative.h> >> #include <asm/processor.h> >> +#include <asm/nops.h> >> >> #ifdef CONFIG_X86_64 >> >> extern asmlinkage void asm_load_gs_index(u16 selector); >> >> +/* Replace with "lkgs %di" once binutils support LKGS instruction */ >> +#define LKGS_DI _ASM_BYTES(0xf2,0x0f,0x00,0xf7) >> + >> static inline void native_load_gs_index(unsigned int selector) >> { >> - asm_load_gs_index(selector); >> + u16 sel = selector; >> + >> + /* >> + * Note: the fixup is used for the LKGS instruction, but >> + * it needs to be attached to the primary instruction sequence >> + * as it isn't something that gets patched. >> + * >> + * %rax is provided to the assembly routine as a scratch >> + * register. >> + */ >> + asm_inline volatile("1:\n" >> + ALTERNATIVE("call asm_load_gs_index\n", >> + _ASM_BYTES(0x3e) LKGS_DI, >> + X86_FEATURE_LKGS) >> + _ASM_EXTABLE_TYPE_REG(1b, 1b, EX_TYPE_ZERO_REG, %k[sel]) >> + : ASM_CALL_CONSTRAINT >> + : [sel] "D" (sel) > >DI needs to be marked as input and output (+D), since the exception >handler modifies it. > >> + : "memory", _ASM_AX); > >_ASM_AX is only needed for code that is used by both 32 and 64-bit. >Since this is 64-bit only, "rax" would be appropriate. > >-- >Brian Gerst
The practice seems to have been to prefer the macros for consistency.
| |