x86/signal: fix restart_syscall number for x32 tasks
[not real reply because I'm using a bad internet connection right now and I'm not set up with my usual Gmane reply hack right now]
The new code is (whitespace-damaged):
static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) {
#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64)
return __NR_restart_syscall;
#else /* !CONFIG_X86_32 && CONFIG_X86_64 */
return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall :
__NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */
}
This is IMO awful. This use of TIF_IA32 is wrong, and this is otherwise gross. Can we do it for real:
if (is_ia32_task())
return __NR_ia32_restart_syscall;
else
return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
/* preserve x32 bit */
I'd send the patch myself, but you apparently have a good test case for this, and I don't.
(this isn't a regression, and I'm not suggesting any change for 4.4 or for stable. But for 4.5, can we do it right, please?)
And yes, I'll send a patch to rename is_ia32_task, but that's orthogonal.
--Andy
P.S. I'm still hoping to kill TIF_IA32 entirely some time soon.
Quoted 18 lines · Andy Lutomirski
[not real reply because I'm using a bad internet connection right now and I'm not set up with my usual Gmane reply hack right now]
The new code is (whitespace-damaged):
static inline unsigned long
get_nr_restart_syscall(const struct pt_regs *regs){
#ifdefined(CONFIG_X86_32)|| !defined(CONFIG_X86_64)
return__NR_restart_syscall;
#else /* !CONFIG_X86_32 &&CONFIG_X86_64*/
returntest_thread_flag(TIF_IA32)?__NR_ia32_restart_syscall:
__NR_restart_syscall| (regs->orig_ax&__X32_SYSCALL_BIT);
#endif /*CONFIG_X86_32|| !CONFIG_X86_64 */
}This is IMO awful. This use of
TIF_IA32is wrong, and this is otherwise gross. Can we do it for real:
Quoted 8 lines
if (
is_ia32_task())
return__NR_ia32_restart_syscall;
else
return__NR_restart_syscall| (regs->orig_ax&__X32_SYSCALL_BIT);
/* preserve x32 bit */I'd send the patch myself, but you apparently have a good test case for this, and I don't.
Unfortunately, this won't compile on CONFIG_X86_32 because __NR_ia32_restart_syscall is defined for CONFIG_X86_64 only.
Something like this should work:
static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) {
#ifdef CONFIG_X86_64 if (is_ia32_task()) return __NR_ia32_restart_syscall; # ifdef CONFIG_X86_X32_ABI if (regs->orig_ax & __X32_SYSCALL_BIT) return __NR_restart_syscall | __X32_SYSCALL_BIT; # endif #endif return __NR_restart_syscall; }
I don't see any way to avoid ifdefs here, sorry.
Signature · 1 line
ldv
Quoted 35 lines · Dmitry V. Levin
Quoted 18 lines · Andy Lutomirski
[not real reply because I'm using a bad internet connection right now and I'm not set up with my usual Gmane reply hack right now]
The new code is (whitespace-damaged):
static inline unsigned long
get_nr_restart_syscall(const struct pt_regs *regs){
#ifdefined(CONFIG_X86_32)|| !defined(CONFIG_X86_64)
return__NR_restart_syscall;
#else /* !CONFIG_X86_32 &&CONFIG_X86_64*/
returntest_thread_flag(TIF_IA32)?__NR_ia32_restart_syscall:
__NR_restart_syscall| (regs->orig_ax&__X32_SYSCALL_BIT);
#endif /*CONFIG_X86_32|| !CONFIG_X86_64 */
}This is IMO awful. This use of
TIF_IA32is wrong, and this is otherwise gross. Can we do it for real:Quoted 8 lines
if (
is_ia32_task())
return__NR_ia32_restart_syscall;
else
return__NR_restart_syscall| (regs->orig_ax&__X32_SYSCALL_BIT);
/* preserve x32 bit */I'd send the patch myself, but you apparently have a good test case for this, and I don't.
Unfortunately, this won't compile on
CONFIG_X86_32because__NR_ia32_restart_syscallis defined forCONFIG_X86_64only.Something like this should work:
static inline unsigned long
get_nr_restart_syscall(const struct pt_regs *regs){
Quoted 10 lines
#ifdef CONFIG_X86_64
if (is_ia32_task())
return __NR_ia32_restart_syscall;
# ifdef CONFIG_X86_X32_ABI
if (regs->orig_ax & __X32_SYSCALL_BIT)
return __NR_restart_syscall | __X32_SYSCALL_BIT;
# endif
#endif
return __NR_restart_syscall;
}Looks good to me. Want to send a patch?
--Andy
PATCH 1/1 x86/signal: Cleanup get_nr_restart_syscall
Check for TS_COMPAT instead of TIF_IA32 to distinguish ia32 tasks from 64-bit tasks.
Check for __X32_SYSCALL_BIT only if CONFIG_X86_X32_ABI is defined.
--- arch/x86/kernel/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/kernel/signal.c +8 -5
@@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)static inline unsigned long get_nr_restart_syscall (const struct pt_regs *regs) { -#if defined(CONFIG_X86_32 ) || !defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_64 +if (is_ia32_task ()) +return __NR_ia32_restart_syscall; +# ifdef CONFIG_X86_X32_ABI +if (regs->orig_ax & __X32_SYSCALL_BIT) +return __NR_restart_syscall | __X32_SYSCALL_BIT; +# endif +#endif return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ -return test_thread_flag (TIF_IA32 ) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ }/*
Signature · 1 line
ldv
H. Peter Anvin
reviewerRe: [PATCH] x86/signal: Cleanup get_nr_restart_syscall
Quoted 27 lines · Dmitry V. Levin
Check for
TS_COMPATinstead ofTIF_IA32to distinguish ia32 tasks from 64-bit tasks.
Check for__X32_SYSCALL_BITonly ifCONFIG_X86_X32_ABIis defined.Signed-off-by Dmitry V. Levin <[email protected]>Cc Elvira Khabirova <[email protected]>Cc Andy Lutomirski <[email protected]>--- arch/x86/kernel/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)arch/x86/kernel/signal.c +6
-1@@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)static inline unsigned long get_nr_restart_syscall (const struct pt_regs *regs) { -#if defined(CONFIG_X86_32 ) || !defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_64 +if (is_ia32_task ()) +return __NR_ia32_restart_syscall; +# ifdef CONFIG_X86_X32_ABI +if (regs->orig_ax & __X32_SYSCALL_BIT) +return __NR_restart_syscall | __X32_SYSCALL_BIT;
arch/x86/kernel/signal.c handle_signal(struct ksignal *ksig, struct pt_regs *regs) · line 706
Quoted 10 lines
arch/x86/kernel/signal.c +2
-4+# endif +#endif return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ -return test_thread_flag (TIF_IA32 ) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ }/*
I bet you actually made the code slower.
-hpa
PATCH v2 1/1 x86/signal: Cleanup get_nr_restart_syscall
Check for TS_COMPAT instead of TIF_IA32 to distinguish ia32 tasks from 64-bit tasks.
Check for __X32_SYSCALL_BIT iff CONFIG_X86_X32_ABI is defined.
---
v2: reintroduced __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT)
arch/x86/kernel/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/kernel/signal.c +8 -5
@@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)static inline unsigned long get_nr_restart_syscall (const struct pt_regs *regs) { -#if defined(CONFIG_X86_32 ) || !defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_64 +if (is_ia32_task ()) +return __NR_ia32_restart_syscall; +#endif +#ifdef CONFIG_X86_X32_ABI +return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); +#else return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ -return test_thread_flag (TIF_IA32 ) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ +#endif }/*
Signature · 1 line
ldv
Re: [PATCH v2] x86/signal: Cleanup get_nr_restart_syscall
Quoted 3 lines · Dmitry V. Levin
Check for
TS_COMPATinstead ofTIF_IA32to distinguish ia32 tasks from 64-bit tasks.
Check for__X32_SYSCALL_BITiffCONFIG_X86_X32_ABIis defined.
LGTM.
--Andy
PATCH RESEND v2 1/1 x86/signal: Cleanup get_nr_restart_syscall
Date: Thu Dec 17 23:56:52 2015 +0000
Check for TS_COMPAT instead of TIF_IA32 to distinguish ia32 tasks from 64-bit tasks.
Check for __X32_SYSCALL_BIT iff CONFIG_X86_X32_ABI is defined.
---
v2: reintroduced __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT)
arch/x86/kernel/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/kernel/signal.c +8 -5
@@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)static inline unsigned long get_nr_restart_syscall (const struct pt_regs *regs) { -#if defined(CONFIG_X86_32 ) || !defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_64 +if (is_ia32_task ()) +return __NR_ia32_restart_syscall; +#endif +#ifdef CONFIG_X86_X32_ABI +return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); +#else return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ -return test_thread_flag (TIF_IA32 ) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ +#endif }/*
Signature · 1 line
ldv
tip-bot for Dmitry V. Levin
merge bot[tip:x86/asm] x86/signal: Cleanup get_nr_restart_syscall()
x86/signal: Cleanup get_nr_restart_syscall()
Commit-ID: 95d97adb2bb85d964bae4538e0574e742e522dda Gitweb: http://git.kernel.org/tip/95d97adb2bb85d964bae4538e0574e742e522dda Author: Dmitry V. Levin <[email protected]> AuthorDate: Thu, 17 Dec 2015 23:56:52 +0000 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 19 Jan 2016 12:55:47 +0100
x86/signal: Cleanup get_nr_restart_syscall()
Check for TS_COMPAT instead of TIF_IA32 to distinguish ia32 tasks from 64-bit tasks.
Check for __X32_SYSCALL_BIT iff CONFIG_X86_X32_ABI is defined.
--- arch/x86/kernel/signal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/kernel/signal.c +8 -5
@@ -692,12 +692,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)static inline unsigned long get_nr_restart_syscall (const struct pt_regs *regs) { -#if defined(CONFIG_X86_32 ) || !defined(CONFIG_X86_64 ) +#ifdef CONFIG_X86_64 +if (is_ia32_task ()) +return __NR_ia32_restart_syscall; +#endif +#ifdef CONFIG_X86_X32_ABI +return __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); +#else return __NR_restart_syscall; -#else /* !CONFIG_X86_32 && CONFIG_X86_64 */ -return test_thread_flag (TIF_IA32 ) ? __NR_ia32_restart_syscall : - __NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT); -#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */ +#endif }/*