Commit c8fb42b7 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Greg Kroah-Hartman

x86/uaccess, signal: Fix AC=1 bloat

[ Upstream commit 88e47182 ]

Occasionally GCC is less agressive with inlining and the following is
observed:

  arch/x86/kernel/signal.o: warning: objtool: restore_sigcontext()+0x3cc: call to force_valid_ss.isra.5() with UACCESS enabled
  arch/x86/kernel/signal.o: warning: objtool: do_signal()+0x384: call to frame_uc_flags.isra.0() with UACCESS enabled

Cure this by moving this code out of the AC=1 region, since it really
isn't needed for the user access.
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarAndy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent e07fb7e7
...@@ -129,16 +129,6 @@ static int restore_sigcontext(struct pt_regs *regs, ...@@ -129,16 +129,6 @@ static int restore_sigcontext(struct pt_regs *regs,
COPY_SEG_CPL3(cs); COPY_SEG_CPL3(cs);
COPY_SEG_CPL3(ss); COPY_SEG_CPL3(ss);
#ifdef CONFIG_X86_64
/*
* Fix up SS if needed for the benefit of old DOSEMU and
* CRIU.
*/
if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) &&
user_64bit_mode(regs)))
force_valid_ss(regs);
#endif
get_user_ex(tmpflags, &sc->flags); get_user_ex(tmpflags, &sc->flags);
regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
regs->orig_ax = -1; /* disable syscall checks */ regs->orig_ax = -1; /* disable syscall checks */
...@@ -147,6 +137,15 @@ static int restore_sigcontext(struct pt_regs *regs, ...@@ -147,6 +137,15 @@ static int restore_sigcontext(struct pt_regs *regs,
buf = (void __user *)buf_val; buf = (void __user *)buf_val;
} get_user_catch(err); } get_user_catch(err);
#ifdef CONFIG_X86_64
/*
* Fix up SS if needed for the benefit of old DOSEMU and
* CRIU.
*/
if (unlikely(!(uc_flags & UC_STRICT_RESTORE_SS) && user_64bit_mode(regs)))
force_valid_ss(regs);
#endif
err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32)); err |= fpu__restore_sig(buf, IS_ENABLED(CONFIG_X86_32));
force_iret(); force_iret();
...@@ -458,6 +457,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, ...@@ -458,6 +457,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
{ {
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
void __user *fp = NULL; void __user *fp = NULL;
unsigned long uc_flags;
int err = 0; int err = 0;
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp); frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
...@@ -470,9 +470,11 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig, ...@@ -470,9 +470,11 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
return -EFAULT; return -EFAULT;
} }
uc_flags = frame_uc_flags(regs);
put_user_try { put_user_try {
/* Create the ucontext. */ /* Create the ucontext. */
put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); put_user_ex(uc_flags, &frame->uc.uc_flags);
put_user_ex(0, &frame->uc.uc_link); put_user_ex(0, &frame->uc.uc_link);
save_altstack_ex(&frame->uc.uc_stack, regs->sp); save_altstack_ex(&frame->uc.uc_stack, regs->sp);
...@@ -538,6 +540,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, ...@@ -538,6 +540,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
{ {
#ifdef CONFIG_X86_X32_ABI #ifdef CONFIG_X86_X32_ABI
struct rt_sigframe_x32 __user *frame; struct rt_sigframe_x32 __user *frame;
unsigned long uc_flags;
void __user *restorer; void __user *restorer;
int err = 0; int err = 0;
void __user *fpstate = NULL; void __user *fpstate = NULL;
...@@ -552,9 +555,11 @@ static int x32_setup_rt_frame(struct ksignal *ksig, ...@@ -552,9 +555,11 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
return -EFAULT; return -EFAULT;
} }
uc_flags = frame_uc_flags(regs);
put_user_try { put_user_try {
/* Create the ucontext. */ /* Create the ucontext. */
put_user_ex(frame_uc_flags(regs), &frame->uc.uc_flags); put_user_ex(uc_flags, &frame->uc.uc_flags);
put_user_ex(0, &frame->uc.uc_link); put_user_ex(0, &frame->uc.uc_link);
compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp); compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
put_user_ex(0, &frame->uc.uc__pad0); put_user_ex(0, &frame->uc.uc__pad0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment