Messages in this thread Patch in this message | | | Subject | Re: [PATCH 25/24] x86/traps: Rewrite native_load_gs_index in C code | From | "H. Peter Anvin" <> | Date | Thu, 9 Sep 2021 16:16:50 -0700 |
| |
Come to think about it, I think it would be better if we were to incorporate the X86_BUG_NULL_SEG null segment load in into the main native_load_gs_index() code while we are swapgs'd anyway. This simplifies the code further, and should avoid calling native_load_gs_index() twice if this bug is enabled.
(This is the traps.c code only; removing the now unnecessary instances is left as an exercise for the reader...)
-hpa diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a58800973aed..5de423a24777 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -671,6 +671,48 @@ DEFINE_IDTENTRY_RAW(exc_int3) } #ifdef CONFIG_X86_64 + +/* + * Reload the %gs selector for user space (setting GS_BASE) with + * exception handling: if the selector is invalid, set %gs to NULL. + * + * selector: new selector + * + * This function is noinstr as it must not be instrumented. + */ +noinstr void native_load_gs_index(unsigned int selector) +{ + unsigned long flags; + + local_irq_save(flags); + +again: + native_swapgs(); + + if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { + if (likely(selector <= 3)) + asm volatile("mov %[seg],%%gs" + : : [seg] "rm" (__USER_DS)); + } + + asm_volatile_goto("1: mov %[seg],%%gs\n" + _ASM_EXTABLE(1b, %l[bad_seg]) + : : [seg] "rm" (selector) + : : bad_seg); + + alternative("", "mfence", X86_BUG_SWAPGS_FENCE); + native_swapgs(); + local_irq_restore(flags); + return; + +bad_seg: + /* + * Invalid selector, set %gs to null (0). + */ + selector = 0; + goto again; +} + /* * Help handler running on a per-cpu (IST or entry trampoline) stack * to switch to the normal thread stack if the interrupted code was in | |