On Wed, Sep 13, 2017 at 06:49:21PM +0200, Oleg Nesterov wrote: > On 09/13, Dmitry V. Levin wrote: > > > > Before this change, CONFIG_X86_X32=y fastpath behaviour was different > > from slowpath: > > and even with this change they differ if CONFIG_X86_X32=n?
No, I don't think so. > do_syscall_64() does "nr & __SYSCALL_MASK" unconditionally, yes > this clears the upper bits, no? Why? As "nr" is of type "unsigned long" and __SYSCALL_MASK is either (~(__X32_SYSCALL_BIT)) or (~0), that is, an integer with the sign bit set, in "nr & __SYSCALL_MASK" expression __SYSCALL_MASK is sign-extended to unsigned long. When __SYSCALL_MASK is defined to (~0), "nr & __SYSCALL_MASK" is optimized to "nr" at compilation time: $ echo 'unsigned long foo(unsigned long nr) { return nr & (~0); }' | gcc -Wall -O2 -xc -S -o - - | sed -n '/cfi_/,/cfi_/p' .cfi_startproc movq %rdi, %rax ret .cfi_endproc > And why __SYSCALL_MASK is not "unsigned long" ? IOW, why do we want to > silently > ignore the upper bits in $rax ? __SYSCALL_MASK is "int" but it is being sign-extended to unsigned long in all (two) places of arch/x86/entry/common.c where it is used. > Or I am totally confused? The thing looks like it was designed to confuse people. -- ldv
signature.asc
Description: PGP signature