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 22:00:25 -0700 |
| |
On 9/7/21 9:42 PM, H. Peter Anvin wrote: > > > 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: >
... slightly shorter and minimally better compiled code ...
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: /* The exception dispatch will have restored kernel GS */ native_swapgs(); alternative_input("", "mov %[seg],%%gs", X86_BUG_NULL_SEG, [seg] "r" (__USER_DS)); selector = 0; goto do_mov_gs; }
| |