On Wed, Mar 11, 2015 at 4:35 AM, Andy Lutomirski <l...@amacapital.net> wrote: >>> Comparison of object code: >>> Old: >>> 1e6: 8b 44 24 38 mov 0x38(%esp),%eax >>> 1ea: 8a 64 24 40 mov 0x40(%esp),%ah >>> 1ee: 8a 44 24 34 mov 0x34(%esp),%al >>> 1f2: 25 03 04 02 00 and $0x20403,%eax >>> 1f7: 3d 03 04 00 00 cmp $0x403,%eax >>> 1fc: 74 0f je 20d <ldt_ss> >>> New: >>> 1e6: f6 44 24 3a 02 testb $0x2,0x3a(%esp) >>> 1eb: 75 0e jne 1fb <restore_nocheck> >>> 1ed: f6 44 24 34 03 testb $0x3,0x34(%esp) >>> 1f2: 74 07 je 1fb <restore_nocheck> >>> 1f4: f6 44 24 40 04 testb $0x4,0x40(%esp) >>> 1f9: 75 0f jne 20a <ldt_ss> >> >> Please do some benchmarking of this: a tight loop of getpid or getppid >> syscalls ought to be enough to be able to time this accurately. > > Before you benchmark, I think you should reorder it: check CS, then > OLDSS, then EFLAGS. The case where CS & 3 == 0, OLDSS & 4 == 4, and > EFLAGS & VM == VM should be *extremely* rare. > > I'm going to hold off on resending my sp0/sp1/ss cleanups until we > resolve this -- if it turns out that your code is the same or faster > and therefore gets merged, then I think that all the -8 crap can just > be deleted instead of being fixed.
I thought that I got NAKed by Linus on this change? Basically, he wants to retain that padding because it guards against _future_ bugs_ where someone would touch pt_regs->ss and it will fail, very rarely. I think it's a sound reason to retain the padding. Anyway, since you ask. I benchmarked current code against this patch: restore_all_notrace: #ifdef CONFIG_X86_ESPFIX32 - movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS - # Warning: PT_OLDSS(%esp) contains the wrong/random values if we - # are returning to the kernel. - # See comments in process.c:copy_thread() for details. - movb PT_OLDSS(%esp), %ah - movb PT_CS(%esp), %al - andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax - cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax CFI_REMEMBER_STATE - je ldt_ss # returning to user-space with LDT SS + testb $3, PT_CS(%esp) + jz restore_nocheck # CPL0, not it +#ifdef CONFIG_VM86 + testb $2, (PT_EFLAGS+2)(%esp) + jnz restore_nocheck # EFLAGS.VM set, not it +#endif + # Note: we access PT_OLDSS only when we know it exists. + # If PT_CS is from CPL0, it does not exist. + testb $SEGMENT_LDT, PT_OLDSS(%esp) + jnz ldt_ss # returning to user-space with LDT SS #endif This code only gets executed on int80 path, not on sysenter. The test was to run 10 million getpids. The numbers I've got are *the same* before and after the patch: 227.99 ns per getpid(). I double-checked my test setup by adding a few PAUSE insns in this code - which, as expected, was seen easily in the test run. I did not forget to enable ESPFIX32 and VM86 in the .config. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/