diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-21 15:43:15 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-21 15:45:27 -0400 |
commit | 5e88353d8b5f483bc1c873ad24ac2b59a6b66c73 (patch) | |
tree | f5651873e535e4feabea0da5d253d0326b4bd029 /arch/x86/ia32 | |
parent | 40d3cd6695014bf3c44e2ca66b610b18acaf923d (diff) |
x86, smap: Reduce the SMAP overhead for signal handling
Signal handling contains a bunch of accesses to individual user space
items, which causes an excessive number of STAC and CLAC
instructions. Instead, let get/put_user_try ... get/put_user_catch()
contain the STAC and CLAC instructions.
This means that get/put_user_try no longer nests, and furthermore that
it is no longer legal to use user space access functions other than
__get/put_user_ex() inside those blocks. However, these macros are
x86-specific anyway and are only used in the signal-handling paths; a
simple reordering of moving the larger subroutine calls out of the
try...catch blocks resolves that problem.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1348256595-29119-12-git-send-email-hpa@linux.intel.com
Diffstat (limited to 'arch/x86/ia32')
-rw-r--r-- | arch/x86/ia32/ia32_signal.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 673ac9b63d6b..05e62a312bd9 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c | |||
@@ -250,11 +250,12 @@ static int ia32_restore_sigcontext(struct pt_regs *regs, | |||
250 | 250 | ||
251 | get_user_ex(tmp, &sc->fpstate); | 251 | get_user_ex(tmp, &sc->fpstate); |
252 | buf = compat_ptr(tmp); | 252 | buf = compat_ptr(tmp); |
253 | err |= restore_i387_xstate_ia32(buf); | ||
254 | 253 | ||
255 | get_user_ex(*pax, &sc->ax); | 254 | get_user_ex(*pax, &sc->ax); |
256 | } get_user_catch(err); | 255 | } get_user_catch(err); |
257 | 256 | ||
257 | err |= restore_i387_xstate_ia32(buf); | ||
258 | |||
258 | return err; | 259 | return err; |
259 | } | 260 | } |
260 | 261 | ||
@@ -502,7 +503,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
502 | put_user_ex(sig, &frame->sig); | 503 | put_user_ex(sig, &frame->sig); |
503 | put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo); | 504 | put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo); |
504 | put_user_ex(ptr_to_compat(&frame->uc), &frame->puc); | 505 | put_user_ex(ptr_to_compat(&frame->uc), &frame->puc); |
505 | err |= copy_siginfo_to_user32(&frame->info, info); | ||
506 | 506 | ||
507 | /* Create the ucontext. */ | 507 | /* Create the ucontext. */ |
508 | if (cpu_has_xsave) | 508 | if (cpu_has_xsave) |
@@ -514,9 +514,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
514 | put_user_ex(sas_ss_flags(regs->sp), | 514 | put_user_ex(sas_ss_flags(regs->sp), |
515 | &frame->uc.uc_stack.ss_flags); | 515 | &frame->uc.uc_stack.ss_flags); |
516 | put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | 516 | put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
517 | err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate, | ||
518 | regs, set->sig[0]); | ||
519 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
520 | 517 | ||
521 | if (ka->sa.sa_flags & SA_RESTORER) | 518 | if (ka->sa.sa_flags & SA_RESTORER) |
522 | restorer = ka->sa.sa_restorer; | 519 | restorer = ka->sa.sa_restorer; |
@@ -532,6 +529,11 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
532 | put_user_ex(*((u64 *)&code), (u64 *)frame->retcode); | 529 | put_user_ex(*((u64 *)&code), (u64 *)frame->retcode); |
533 | } put_user_catch(err); | 530 | } put_user_catch(err); |
534 | 531 | ||
532 | err |= copy_siginfo_to_user32(&frame->info, info); | ||
533 | err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate, | ||
534 | regs, set->sig[0]); | ||
535 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
536 | |||
535 | if (err) | 537 | if (err) |
536 | return -EFAULT; | 538 | return -EFAULT; |
537 | 539 | ||