[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170914202114.GA16764@altlinux.org>
Date: Thu, 14 Sep 2017 23:21:14 +0300
From: "Dmitry V. Levin" <ldv@...linux.org>
To: Oleg Nesterov <oleg@...hat.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
"H. Peter Anvin" <hpa@...or.com>, x86@...nel.org,
Andy Lutomirski <luto@...nel.org>,
Eugene Syromyatnikov <evgsyr@...il.com>,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] x86/asm/64: do not clear high 32 bits of syscall number
when CONFIG_X86_X32=y
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
Download attachment "signature.asc" of type "application/pgp-signature" (802 bytes)
Powered by blists - more mailing lists