summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r--arch/arm/kernel/signal.c100
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);