Messages in this thread | | | Subject | Re: [PATCH 25/24] x86/traps: Rewrite native_load_gs_index in C code | From | "H. Peter Anvin" <> | Date | Tue, 7 Sep 2021 21:42:43 -0700 |
| |
On 9/7/21 6:38 PM, H. Peter Anvin wrote: > On 9/2/21 3:50 AM, Lai Jiangshan wrote: >> From: Lai Jiangshan <laijs@linux.alibaba.com> >> >> There is no constrain/limition to force native_load_gs_index() to be in >> ASM code. > > Hi, > > First of all, let me say I really like your patchset, and I will try to > review it in detail ASAP (most of the initial read pass looks very sane > to me. > > However, I would like to object in part this specific patch. It adds a > fair bit of extra code to the exception path, and adds jumps between > files which makes the code much harder to read. > > You end up doing one swapgs in assembly and one in C, which would seem > to be a very good indication that really isn't an improvement. > > Note that this entire sequence is scheduled to be obsoleted by a single > atomic hardware instruction, LKGS, which will replace ALL of > native_load_gs_index(); it will no longer be necessary even to disable > interrupts as there is no non-atomic state. In that sense, doing this as > an out-of-line C function (with some inline assembly) is great, because > it makes it far easier to use LKGS as an alternative; the only (small) > disadvantage is that it ends up clobbering a lot of registers > unnecessarily (in assembly it can be implemented clobbering only two > registers; one if one uses pushf/popf to save the interrupt flag.) >
OK, here is a version which actually compiles:
(It makes me wonder if it would be useful to have an _ASM_EXTABLE_GOTO() macro to highlight the use of an asm goto C label.)
noinstr void native_load_gs_index(unsigned int selector) { unsigned long flags;
local_irq_save(flags); native_swapgs();
do_mov_gs: asm_volatile_goto("1: mov %[seg],%%gs\n" "2:\n" _ASM_EXTABLE(1b,%l[bad_seg]) : : [seg] "r" (selector) : : bad_seg);
alternative("", "mfence", X86_BUG_SWAPGS_FENCE); native_swapgs(); local_irq_restore(flags); return;
bad_seg: selector = 0;
/* The exception dispatch will have restored kernel GS */ native_swapgs();
if (static_cpu_has_bug(X86_BUG_NULL_SEG)) asm volatile("mov %[seg],%%gs" : : [seg] "r" (__USER_DS)); goto do_mov_gs; }
| |