diff options
Diffstat (limited to 'arch/arm/kernel/signal.c')
| -rw-r--r-- | arch/arm/kernel/signal.c | 100 |
1 files changed, 45 insertions, 55 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index a3a38d0a4c85..79a6730fa0eb 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -9,7 +9,7 @@ #include <linux/signal.h> #include <linux/personality.h> #include <linux/uaccess.h> -#include <linux/tracehook.h> +#include <linux/resume_user_mode.h> #include <linux/uprobes.h> #include <linux/syscalls.h> @@ -18,6 +18,7 @@ #include <asm/traps.h> #include <asm/unistd.h> #include <asm/vfp.h> +#include <asm/syscalls.h> #include "signal.h" @@ -25,40 +26,6 @@ extern const unsigned long sigreturn_codes[17]; static unsigned long signal_return_offset; -#ifdef CONFIG_CRUNCH -static int preserve_crunch_context(struct crunch_sigframe __user *frame) -{ - char kbuf[sizeof(*frame) + 8]; - struct crunch_sigframe *kframe; - - /* the crunch context must be 64 bit aligned */ - kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); - kframe->magic = CRUNCH_MAGIC; - kframe->size = CRUNCH_STORAGE_SIZE; - crunch_task_copy(current_thread_info(), &kframe->storage); - return __copy_to_user(frame, kframe, sizeof(*frame)); -} - -static int restore_crunch_context(char __user **auxp) -{ - struct crunch_sigframe __user *frame = - (struct crunch_sigframe __user *)*auxp; - char kbuf[sizeof(*frame) + 8]; - struct crunch_sigframe *kframe; - - /* the crunch context must be 64 bit aligned */ - kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); - if (__copy_from_user(kframe, frame, sizeof(*frame))) - return -1; - if (kframe->magic != CRUNCH_MAGIC || - kframe->size != CRUNCH_STORAGE_SIZE) - return -1; - *auxp += CRUNCH_STORAGE_SIZE; - crunch_task_restore(current_thread_info(), &kframe->storage); - return 0; -} -#endif - #ifdef CONFIG_IWMMXT static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame) @@ -205,10 +172,6 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= !valid_user_regs(regs); aux = (char __user *) sf->uc.uc_regspace; -#ifdef CONFIG_CRUNCH - if (err == 0) - err |= restore_crunch_context(&aux); -#endif #ifdef CONFIG_IWMMXT if (err == 0) err |= restore_iwmmxt_context(&aux); @@ -321,10 +284,6 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; -#ifdef CONFIG_CRUNCH - if (err == 0) - err |= preserve_crunch_context(&aux->crunch); -#endif #ifdef CONFIG_IWMMXT if (err == 0) err |= preserve_iwmmxt_context(&aux->iwmmxt); @@ -669,12 +628,11 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) } else if (thread_flags & _TIF_UPROBE) { uprobe_notify_resume(regs); } else { - tracehook_notify_resume(regs); - rseq_handle_notify_resume(NULL, regs); + resume_user_mode_work(regs); } } local_irq_disable(); - thread_flags = current_thread_info()->flags; + thread_flags = read_thread_flags(); } while (thread_flags & _TIF_WORK_MASK); return 0; } @@ -698,7 +656,7 @@ struct page *get_signal_page(void) PAGE_SIZE / sizeof(u32)); /* Give the signal return code some randomness */ - offset = 0x200 + (get_random_int() & 0x7fc); + offset = 0x200 + (get_random_u16() & 0x7fc); signal_return_offset = offset; /* Copy signal return handlers into the page */ @@ -711,17 +669,49 @@ struct page *get_signal_page(void) return page; } -/* Defer to generic check */ -asmlinkage void addr_limit_check_failed(void) -{ -#ifdef CONFIG_MMU - addr_limit_user_check(); -#endif -} - #ifdef CONFIG_DEBUG_RSEQ asmlinkage void do_rseq_syscall(struct pt_regs *regs) { rseq_syscall(regs); } #endif + +/* + * Compile-time assertions for siginfo_t offsets. Check NSIG* as well, as + * changes likely come with new fields that should be added below. + */ +static_assert(NSIGILL == 11); +static_assert(NSIGFPE == 15); +static_assert(NSIGSEGV == 10); +static_assert(NSIGBUS == 5); +static_assert(NSIGTRAP == 6); +static_assert(NSIGCHLD == 6); +static_assert(NSIGSYS == 2); +static_assert(sizeof(siginfo_t) == 128); +static_assert(__alignof__(siginfo_t) == 4); +static_assert(offsetof(siginfo_t, si_signo) == 0x00); +static_assert(offsetof(siginfo_t, si_errno) == 0x04); +static_assert(offsetof(siginfo_t, si_code) == 0x08); +static_assert(offsetof(siginfo_t, si_pid) == 0x0c); +static_assert(offsetof(siginfo_t, si_uid) == 0x10); +static_assert(offsetof(siginfo_t, si_tid) == 0x0c); +static_assert(offsetof(siginfo_t, si_overrun) == 0x10); +static_assert(offsetof(siginfo_t, si_status) == 0x14); +static_assert(offsetof(siginfo_t, si_utime) == 0x18); +static_assert(offsetof(siginfo_t, si_stime) == 0x1c); +static_assert(offsetof(siginfo_t, si_value) == 0x14); +static_assert(offsetof(siginfo_t, si_int) == 0x14); +static_assert(offsetof(siginfo_t, si_ptr) == 0x14); +static_assert(offsetof(siginfo_t, si_addr) == 0x0c); +static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x10); +static_assert(offsetof(siginfo_t, si_lower) == 0x14); +static_assert(offsetof(siginfo_t, si_upper) == 0x18); +static_assert(offsetof(siginfo_t, si_pkey) == 0x14); +static_assert(offsetof(siginfo_t, si_perf_data) == 0x10); +static_assert(offsetof(siginfo_t, si_perf_type) == 0x14); +static_assert(offsetof(siginfo_t, si_perf_flags) == 0x18); +static_assert(offsetof(siginfo_t, si_band) == 0x0c); +static_assert(offsetof(siginfo_t, si_fd) == 0x10); +static_assert(offsetof(siginfo_t, si_call_addr) == 0x0c); +static_assert(offsetof(siginfo_t, si_syscall) == 0x10); +static_assert(offsetof(siginfo_t, si_arch) == 0x14); |
