Messages in this thread | | | Subject | Re: [PATCH 25/24] x86/traps: Rewrite native_load_gs_index in C code | From | Lai Jiangshan <> | Date | Wed, 8 Sep 2021 15:12:06 +0800 |
| |
On 2021/9/8 13:00, H. Peter Anvin wrote: > 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.
Hello
Thank you for your review.
>>> >>> 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.
I tried putting all code into a single C function. But I didn't know how to use a C-label in _ASM_EXTABLE and then I split it.
Your code is much better.
Thanks Lai
>>> >>> 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; > }
| |