summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/include/asm/arcregs.h2
-rw-r--r--arch/arc/include/asm/irq.h4
-rw-r--r--arch/arc/include/asm/irqflags.h18
-rw-r--r--arch/arc/kernel/irq.c53
-rw-r--r--arch/arc/kernel/signal.c47
-rw-r--r--arch/arc/kernel/smp.c23
-rw-r--r--arch/arc/kernel/time.c28
-rw-r--r--arch/arc/mm/cache_arc700.c168
-rw-r--r--arch/arc/mm/fault.c1
-rw-r--r--arch/arc/mm/tlbex.S4
-rw-r--r--arch/arc/plat-arcfpga/Makefile2
-rw-r--r--arch/arc/plat-arcfpga/include/plat/irq.h2
-rw-r--r--arch/arc/plat-arcfpga/irq.c25
-rw-r--r--arch/arc/plat-arcfpga/platform.c3
-rw-r--r--arch/arm/include/asm/unistd.h2
-rw-r--r--arch/arm/include/uapi/asm/unistd.h2
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/kernel/smp.c70
-rw-r--r--arch/arm/mm/proc-v7-3level.S7
-rw-r--r--arch/arm64/include/asm/signal32.h11
-rw-r--r--arch/arm64/kernel/signal.c58
-rw-r--r--arch/arm64/kernel/signal32.c24
-rw-r--r--arch/arm64/kernel/smp.c65
-rw-r--r--arch/avr32/kernel/signal.c50
-rw-r--r--arch/blackfin/kernel/signal.c51
-rw-r--r--arch/c6x/kernel/signal.c53
-rw-r--r--arch/cris/arch-v10/kernel/signal.c89
-rw-r--r--arch/cris/arch-v32/kernel/signal.c89
-rw-r--r--arch/frv/kernel/signal.c112
-rw-r--r--arch/hexagon/kernel/signal.c57
-rw-r--r--arch/ia64/include/asm/unistd.h2
-rw-r--r--arch/ia64/include/uapi/asm/unistd.h1
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/ia64/kernel/signal.c46
-rw-r--r--arch/m32r/kernel/signal.c57
-rw-r--r--arch/m68k/kernel/signal.c75
-rw-r--r--arch/metag/kernel/signal.c10
-rw-r--r--arch/microblaze/kernel/signal.c55
-rw-r--r--arch/mips/include/asm/abi.h10
-rw-r--r--arch/mips/kernel/signal-common.h2
-rw-r--r--arch/mips/kernel/signal.c72
-rw-r--r--arch/mips/kernel/signal32.c39
-rw-r--r--arch/mips/kernel/signal_n32.c20
-rw-r--r--arch/mn10300/kernel/signal.c102
-rw-r--r--arch/openrisc/kernel/signal.c20
-rw-r--r--arch/parisc/kernel/signal.c58
-rw-r--r--arch/powerpc/kernel/signal.c41
-rw-r--r--arch/powerpc/kernel/signal.h14
-rw-r--r--arch/powerpc/kernel/signal_32.c36
-rw-r--r--arch/powerpc/kernel/signal_64.c28
-rw-r--r--arch/s390/kernel/compat_signal.c79
-rw-r--r--arch/s390/kernel/entry.h4
-rw-r--r--arch/s390/kernel/signal.c78
-rw-r--r--arch/score/kernel/signal.c43
-rw-r--r--arch/sh/kernel/signal_32.c79
-rw-r--r--arch/sh/kernel/signal_64.c82
-rw-r--r--arch/tile/include/asm/compat.h3
-rw-r--r--arch/tile/kernel/compat_signal.c29
-rw-r--r--arch/tile/kernel/signal.c54
-rw-r--r--arch/um/include/shared/frame_kern.h12
-rw-r--r--arch/um/kernel/signal.c27
-rw-r--r--arch/unicore32/kernel/signal.c48
-rw-r--r--arch/x86/um/signal.c45
-rw-r--r--arch/xtensa/kernel/signal.c43
64 files changed, 1013 insertions, 1424 deletions
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 355cb470c2a4..372466b371bf 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -296,7 +296,7 @@ struct cpuinfo_arc_mmu {
};
struct cpuinfo_arc_cache {
- unsigned int sz, line_len, assoc, ver;
+ unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6;
};
struct cpuinfo_arc_ccm {
diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index fb4efb648971..f38652fb2ed7 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,9 +16,13 @@
#define TIMER0_IRQ 3
#define TIMER1_IRQ 4
+#include <linux/interrupt.h>
#include <asm-generic/irq.h>
extern void arc_init_IRQ(void);
void arc_local_timer_setup(void);
+void arc_request_percpu_irq(int irq, int cpu,
+ irqreturn_t (*isr)(int irq, void *dev),
+ const char *irq_nm, void *percpu_dev);
#endif
diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h
index cb7efc29f16f..587df8236e8b 100644
--- a/arch/arc/include/asm/irqflags.h
+++ b/arch/arc/include/asm/irqflags.h
@@ -131,24 +131,6 @@ static inline int arch_irqs_disabled(void)
return arch_irqs_disabled_flags(arch_local_save_flags());
}
-static inline void arch_mask_irq(unsigned int irq)
-{
- unsigned int ienb;
-
- ienb = read_aux_reg(AUX_IENABLE);
- ienb &= ~(1 << irq);
- write_aux_reg(AUX_IENABLE, ienb);
-}
-
-static inline void arch_unmask_irq(unsigned int irq)
-{
- unsigned int ienb;
-
- ienb = read_aux_reg(AUX_IENABLE);
- ienb |= (1 << irq);
- write_aux_reg(AUX_IENABLE, ienb);
-}
-
#else
#ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 7d653c0d0773..620ec2fe32a9 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -19,21 +19,16 @@
/*
* Early Hardware specific Interrupt setup
+ * -Platform independent, needed for each CPU (not foldable into init_IRQ)
* -Called very early (start_kernel -> setup_arch -> setup_processor)
- * -Platform Independent (must for any ARC700)
- * -Needed for each CPU (hence not foldable into init_IRQ)
*
* what it does ?
- * -Disable all IRQs (on CPU side)
* -Optionally, setup the High priority Interrupts as Level 2 IRQs
*/
void arc_init_IRQ(void)
{
int level_mask = 0;
- /* Disable all IRQs: enable them as devices request */
- write_aux_reg(AUX_IENABLE, 0);
-
/* setup any high priority Interrupts (Level2 in ARCompact jargon) */
level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
@@ -60,20 +55,28 @@ void arc_init_IRQ(void)
* below, per IRQ.
*/
-static void arc_mask_irq(struct irq_data *data)
+static void arc_irq_mask(struct irq_data *data)
{
- arch_mask_irq(data->irq);
+ unsigned int ienb;
+
+ ienb = read_aux_reg(AUX_IENABLE);
+ ienb &= ~(1 << data->irq);
+ write_aux_reg(AUX_IENABLE, ienb);
}
-static void arc_unmask_irq(struct irq_data *data)
+static void arc_irq_unmask(struct irq_data *data)
{
- arch_unmask_irq(data->irq);
+ unsigned int ienb;
+
+ ienb = read_aux_reg(AUX_IENABLE);
+ ienb |= (1 << data->irq);
+ write_aux_reg(AUX_IENABLE, ienb);
}
static struct irq_chip onchip_intc = {
.name = "ARC In-core Intc",
- .irq_mask = arc_mask_irq,
- .irq_unmask = arc_unmask_irq,
+ .irq_mask = arc_irq_mask,
+ .irq_unmask = arc_irq_unmask,
};
static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
@@ -150,6 +153,32 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs);
}
+void arc_request_percpu_irq(int irq, int cpu,
+ irqreturn_t (*isr)(int irq, void *dev),
+ const char *irq_nm,
+ void *percpu_dev)
+{
+ /* Boot cpu calls request, all call enable */
+ if (!cpu) {
+ int rc;
+
+ /*
+ * These 2 calls are essential to making percpu IRQ APIs work
+ * Ideally these details could be hidden in irq chip map function
+ * but the issue is IPIs IRQs being static (non-DT) and platform
+ * specific, so we can't identify them there.
+ */
+ irq_set_percpu_devid(irq);
+ irq_modify_status(irq, IRQ_NOAUTOEN, 0); /* @irq, @clr, @set */
+
+ rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
+ if (rc)
+ panic("Percpu IRQ request failed for %d\n", irq);
+ }
+
+ enable_percpu_irq(irq, 0);
+}
+
/*
* arch_local_irq_enable - Enable interrupts.
*
diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
index 7e95e1a86510..cb3142a2d40b 100644
--- a/arch/arc/kernel/signal.c
+++ b/arch/arc/kernel/signal.c
@@ -141,17 +141,13 @@ badframe:
/*
* Determine which stack to use..
*/
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
unsigned long framesize)
{
- unsigned long sp = regs->sp;
+ unsigned long sp = sigsp(regs->sp, ksig);
void __user *frame;
- /* This is the X/Open sanctioned signal stack switching */
- if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
-
/* No matter what happens, 'sp' must be word
* aligned otherwise nasty things could happen
*/
@@ -179,14 +175,13 @@ static inline int map_sig(int sig)
}
static int
-setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *sf;
unsigned int magic = 0;
int err = 0;
- sf = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+ sf = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
if (!sf)
return 1;
@@ -205,8 +200,8 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
* #2: struct siginfo
* #3: struct ucontext (completely populated)
*/
- if (unlikely(ka->sa.sa_flags & SA_SIGINFO)) {
- err |= copy_siginfo_to_user(&sf->info, info);
+ if (unlikely(ksig->ka.sa.sa_flags & SA_SIGINFO)) {
+ err |= copy_siginfo_to_user(&sf->info, &ksig->info);
err |= __put_user(0, &sf->uc.uc_flags);
err |= __put_user(NULL, &sf->uc.uc_link);
err |= __save_altstack(&sf->uc.uc_stack, regs->sp);
@@ -227,16 +222,16 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
return err;
/* #1 arg to the user Signal handler */
- regs->r0 = map_sig(signo);
+ regs->r0 = map_sig(ksig->sig);
/* setup PC of user space signal handler */
- regs->ret = (unsigned long)ka->sa.sa_handler;
+ regs->ret = (unsigned long)ksig->ka.sa.sa_handler;
/*
* handler returns using sigreturn stub provided already by userpsace
*/
- BUG_ON(!(ka->sa.sa_flags & SA_RESTORER));
- regs->blink = (unsigned long)ka->sa.sa_restorer;
+ BUG_ON(!(ksig->ka.sa.sa_flags & SA_RESTORER));
+ regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
/* User Stack for signal handler will be above the frame just carved */
regs->sp = (unsigned long)sf;
@@ -298,38 +293,30 @@ static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs)
* OK, we're invoking a handler
*/
static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* Set up the stack frame */
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = setup_rt_frame(ksig, oldset, regs);
- if (ret)
- force_sigsegv(sig, current);
- else
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
void do_signal(struct pt_regs *regs)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
int restart_scall;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
restart_scall = in_syscall(regs) && syscall_restartable(regs);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
if (restart_scall) {
- arc_restart_syscall(&ka, regs);
+ arc_restart_syscall(&ksig.ka, regs);
syscall_wont_restart(regs); /* No more restarts */
}
- handle_signal(signr, &ka, &info, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index c802bb500602..dcd317c47d09 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -12,23 +12,15 @@
* -- Initial Write (Borrowed heavily from ARM)
*/
-#include <linux/module.h>
-#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/profile.h>
-#include <linux/errno.h>
-#include <linux/err.h>
#include <linux/mm.h>
#include <linux/cpu.h>
-#include <linux/smp.h>
#include <linux/irq.h>
-#include <linux/delay.h>
#include <linux/atomic.h>
-#include <linux/percpu.h>
#include <linux/cpumask.h>
-#include <linux/spinlock_types.h>
#include <linux/reboot.h>
#include <asm/processor.h>
#include <asm/setup.h>
@@ -136,7 +128,7 @@ void start_kernel_secondary(void)
pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
if (machine_desc->init_smp)
- machine_desc->init_smp(smp_processor_id());
+ machine_desc->init_smp(cpu);
arc_local_timer_setup();
@@ -338,18 +330,11 @@ irqreturn_t do_IPI(int irq, void *dev_id)
*/
static DEFINE_PER_CPU(int, ipi_dev);
-static struct irqaction arc_ipi_irq = {
- .name = "IPI Interrupt",
- .flags = IRQF_PERCPU,
- .handler = do_IPI,
-};
-
int smp_ipi_irq_setup(int cpu, int irq)
{
- if (!cpu)
- return setup_irq(irq, &arc_ipi_irq);
- else
- arch_unmask_irq(irq);
+ int *dev = per_cpu_ptr(&ipi_dev, cpu);
+
+ arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev);
return 0;
}
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 36c2aa99436f..dbe74f418019 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -144,12 +144,12 @@ static struct clocksource arc_counter = {
/********** Clock Event Device *********/
/*
- * Arm the timer to interrupt after @limit cycles
+ * Arm the timer to interrupt after @cycles
* The distinction for oneshot/periodic is done in arc_event_timer_ack() below
*/
-static void arc_timer_event_setup(unsigned int limit)
+static void arc_timer_event_setup(unsigned int cycles)
{
- write_aux_reg(ARC_REG_TIMER0_LIMIT, limit);
+ write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */
write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
@@ -168,6 +168,10 @@ static void arc_clkevent_set_mode(enum clock_event_mode mode,
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
+ /*
+ * At X Hz, 1 sec = 1000ms -> X cycles;
+ * 10ms -> X / 100 cycles
+ */
arc_timer_event_setup(arc_get_core_freq() / HZ);
break;
case CLOCK_EVT_MODE_ONESHOT:
@@ -210,12 +214,6 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct irqaction arc_timer_irq = {
- .name = "Timer0 (clock-evt-dev)",
- .flags = IRQF_TIMER | IRQF_PERCPU,
- .handler = timer_irq_handler,
-};
-
/*
* Setup the local event timer for @cpu
*/
@@ -228,15 +226,9 @@ void arc_local_timer_setup()
clockevents_config_and_register(evt, arc_get_core_freq(),
0, ARC_TIMER_MAX);
- /*
- * setup the per-cpu timer IRQ handler - for all cpus
- * For non boot CPU explicitly unmask at intc
- * setup_irq() -> .. -> irq_startup() already does this on boot-cpu
- */
- if (!cpu)
- setup_irq(TIMER0_IRQ, &arc_timer_irq);
- else
- arch_unmask_irq(TIMER0_IRQ);
+ /* setup the per-cpu timer IRQ handler - for all cpus */
+ arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler,
+ "Timer0 (per-cpu-tick)", evt);
}
/*
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index 353b202c37c9..4670afc3b971 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -77,21 +77,19 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
{
int n = 0;
-#define PR_CACHE(p, enb, str) \
-{ \
+#define PR_CACHE(p, cfg, str) \
if (!(p)->ver) \
n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \
else \
n += scnprintf(buf + n, len - n, \
- str"\t\t: (%uK) VIPT, %dway set-asc, %ub Line %s\n", \
- TO_KB((p)->sz), (p)->assoc, (p)->line_len, \
- enb ? "" : "DISABLED (kernel-build)"); \
-}
+ str"\t\t: %uK, %dway/set, %uB Line, %s%s%s\n", \
+ (p)->sz_k, (p)->assoc, (p)->line_len, \
+ (p)->vipt ? "VIPT" : "PIPT", \
+ (p)->alias ? " aliasing" : "", \
+ IS_ENABLED(cfg) ? "" : " (not used)");
- PR_CACHE(&cpuinfo_arc700[c].icache, IS_ENABLED(CONFIG_ARC_HAS_ICACHE),
- "I-Cache");
- PR_CACHE(&cpuinfo_arc700[c].dcache, IS_ENABLED(CONFIG_ARC_HAS_DCACHE),
- "D-Cache");
+ PR_CACHE(&cpuinfo_arc700[c].icache, CONFIG_ARC_HAS_ICACHE, "I-Cache");
+ PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache");
return buf;
}
@@ -116,20 +114,31 @@ void read_decode_cache_bcr(void)
p_ic = &cpuinfo_arc700[cpu].icache;
READ_BCR(ARC_REG_IC_BCR, ibcr);
+ if (!ibcr.ver)
+ goto dc_chk;
+
BUG_ON(ibcr.config != 3);
p_ic->assoc = 2; /* Fixed to 2w set assoc */
p_ic->line_len = 8 << ibcr.line_len;
- p_ic->sz = 0x200 << ibcr.sz;
+ p_ic->sz_k = 1 << (ibcr.sz - 1);
p_ic->ver = ibcr.ver;
+ p_ic->vipt = 1;
+ p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1;
+dc_chk:
p_dc = &cpuinfo_arc700[cpu].dcache;
READ_BCR(ARC_REG_DC_BCR, dbcr);
+ if (!dbcr.ver)
+ return;
+
BUG_ON(dbcr.config != 2);
p_dc->assoc = 4; /* Fixed to 4w set assoc */
p_dc->line_len = 16 << dbcr.line_len;
- p_dc->sz = 0x200 << dbcr.sz;
+ p_dc->sz_k = 1 << (dbcr.sz - 1);
p_dc->ver = dbcr.ver;
+ p_dc->vipt = 1;
+ p_dc->alias = p_dc->sz_k/p_dc->assoc/TO_KB(PAGE_SIZE) > 1;
}
/*
@@ -142,14 +151,16 @@ void read_decode_cache_bcr(void)
void arc_cache_init(void)
{
unsigned int __maybe_unused cpu = smp_processor_id();
- struct cpuinfo_arc_cache __maybe_unused *ic, __maybe_unused *dc;
char str[256];
printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
-#ifdef CONFIG_ARC_HAS_ICACHE
- ic = &cpuinfo_arc700[cpu].icache;
- if (ic->ver) {
+ if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) {
+ struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
+
+ if (!ic->ver)
+ panic("cache support enabled but non-existent cache\n");
+
if (ic->line_len != L1_CACHE_BYTES)
panic("ICache line [%d] != kernel Config [%d]",
ic->line_len, L1_CACHE_BYTES);
@@ -158,26 +169,26 @@ void arc_cache_init(void)
panic("Cache ver [%d] doesn't match MMU ver [%d]\n",
ic->ver, CONFIG_ARC_MMU_VER);
}
-#endif
-#ifdef CONFIG_ARC_HAS_DCACHE
- dc = &cpuinfo_arc700[cpu].dcache;
- if (dc->ver) {
- unsigned int dcache_does_alias;
+ if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) {
+ struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
+ int handled;
+
+ if (!dc->ver)
+ panic("cache support enabled but non-existent cache\n");
if (dc->line_len != L1_CACHE_BYTES)
panic("DCache line [%d] != kernel Config [%d]",
dc->line_len, L1_CACHE_BYTES);
/* check for D-Cache aliasing */
- dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
+ handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
- if (dcache_does_alias && !cache_is_vipt_aliasing())
+ if (dc->alias && !handled)
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
- else if (!dcache_does_alias && cache_is_vipt_aliasing())
+ else if (!dc->alias && handled)
panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
}
-#endif
}
#define OP_INV 0x1
@@ -255,10 +266,32 @@ static inline void __cache_line_loop(unsigned long paddr, unsigned long vaddr,
* Machine specific helpers for Entire D-Cache or Per Line ops
*/
-static inline void wait_for_flush(void)
+static unsigned int __before_dc_op(const int op)
+{
+ unsigned int reg = reg;
+
+ if (op == OP_FLUSH_N_INV) {
+ /* Dcache provides 2 cmd: FLUSH or INV
+ * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
+ * flush-n-inv is achieved by INV cmd but with IM=1
+ * So toggle INV sub-mode depending on op request and default
+ */
+ reg = read_aux_reg(ARC_REG_DC_CTRL);
+ write_aux_reg(ARC_REG_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH)
+ ;
+ }
+
+ return reg;
+}
+
+static void __after_dc_op(const int op, unsigned int reg)
{
- while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
- ;
+ if (op & OP_FLUSH) /* flush / flush-n-inv both wait */
+ while (read_aux_reg(ARC_REG_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
+
+ /* Switch back to default Invalidate mode */
+ if (op == OP_FLUSH_N_INV)
+ write_aux_reg(ARC_REG_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
}
/*
@@ -269,18 +302,10 @@ static inline void wait_for_flush(void)
*/
static inline void __dc_entire_op(const int cacheop)
{
- unsigned int tmp = tmp;
+ unsigned int ctrl_reg;
int aux;
- if (cacheop == OP_FLUSH_N_INV) {
- /* Dcache provides 2 cmd: FLUSH or INV
- * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
- * flush-n-inv is achieved by INV cmd but with IM=1
- * Default INV sub-mode is DISCARD, which needs to be toggled
- */
- tmp = read_aux_reg(ARC_REG_DC_CTRL);
- write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH);
- }
+ ctrl_reg = __before_dc_op(cacheop);
if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */
aux = ARC_REG_DC_IVDC;
@@ -289,12 +314,7 @@ static inline void __dc_entire_op(const int cacheop)
write_aux_reg(aux, 0x1);
- if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */
- wait_for_flush();
-
- /* Switch back the DISCARD ONLY Invalidate mode */
- if (cacheop == OP_FLUSH_N_INV)
- write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
+ __after_dc_op(cacheop, ctrl_reg);
}
/* For kernel mappings cache operation: index is same as paddr */
@@ -306,29 +326,16 @@ static inline void __dc_entire_op(const int cacheop)
static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
unsigned long sz, const int cacheop)
{
- unsigned long flags, tmp = tmp;
+ unsigned long flags;
+ unsigned int ctrl_reg;
local_irq_save(flags);
- if (cacheop == OP_FLUSH_N_INV) {
- /*
- * Dcache provides 2 cmd: FLUSH or INV
- * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
- * flush-n-inv is achieved by INV cmd but with IM=1
- * Default INV sub-mode is DISCARD, which needs to be toggled
- */
- tmp = read_aux_reg(ARC_REG_DC_CTRL);
- write_aux_reg(ARC_REG_DC_CTRL, tmp | DC_CTRL_INV_MODE_FLUSH);
- }
+ ctrl_reg = __before_dc_op(cacheop);
__cache_line_loop(paddr, vaddr, sz, cacheop);
- if (cacheop & OP_FLUSH) /* flush / flush-n-inv both wait */
- wait_for_flush();
-
- /* Switch back the DISCARD ONLY Invalidate mode */
- if (cacheop == OP_FLUSH_N_INV)
- write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
+ __after_dc_op(cacheop, ctrl_reg);
local_irq_restore(flags);
}
@@ -389,8 +396,16 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long vaddr,
/***********************************************************
* Machine specific helper for per line I-Cache invalidate.
*/
-static void __ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
- unsigned long sz)
+
+static inline void __ic_entire_inv(void)
+{
+ write_aux_reg(ARC_REG_IC_IVIC, 1);
+ read_aux_reg(ARC_REG_IC_CTRL); /* blocks */
+}
+
+static inline void
+__ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
+ unsigned long sz)
{
unsigned long flags;
@@ -399,30 +414,39 @@ static void __ic_line_inv_vaddr_local(unsigned long paddr, unsigned long vaddr,
local_irq_restore(flags);
}
-static inline void __ic_entire_inv(void)
-{
- write_aux_reg(ARC_REG_IC_IVIC, 1);
- read_aux_reg(ARC_REG_IC_CTRL); /* blocks */
-}
+#ifndef CONFIG_SMP
+
+#define __ic_line_inv_vaddr(p, v, s) __ic_line_inv_vaddr_local(p, v, s)
-struct ic_line_inv_vaddr_ipi {
+#else
+
+struct ic_inv_args {
unsigned long paddr, vaddr;
int sz;
};
static void __ic_line_inv_vaddr_helper(void *info)
{
- struct ic_line_inv_vaddr_ipi *ic_inv = (struct ic_line_inv_vaddr_ipi*) info;
+ struct ic_inv *ic_inv_args = (struct ic_inv_args *) info;
+
__ic_line_inv_vaddr_local(ic_inv->paddr, ic_inv->vaddr, ic_inv->sz);
}
static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
unsigned long sz)
{
- struct ic_line_inv_vaddr_ipi ic_inv = { paddr, vaddr , sz};
+ struct ic_inv_args ic_inv = {
+ .paddr = paddr,
+ .vaddr = vaddr,
+ .sz = sz
+ };
+
on_each_cpu(__ic_line_inv_vaddr_helper, &ic_inv, 1);
}
-#else
+
+#endif /* CONFIG_SMP */
+
+#else /* !CONFIG_ARC_HAS_ICACHE */
#define __ic_entire_inv()
#define __ic_line_inv_vaddr(pstart, vstart, sz)
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 9c69552350c4..6f7e3a68803a 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -159,7 +159,6 @@ good_area:
return;
}
- /* TBD: switch to pagefault_out_of_memory() */
if (fault & VM_FAULT_OOM)
goto out_of_memory;
else if (fault & VM_FAULT_SIGBUS)
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 79bfc81358c9..d572f1c2c724 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -220,9 +220,9 @@ ex_saved_reg1:
.macro CONV_PTE_TO_TLB
and r3, r0, PTE_BITS_RWX ; r w x
- lsl r2, r3, 3 ; r w x 0 0 0
+ lsl r2, r3, 3 ; r w x 0 0 0 (GLOBAL, kernel only)
and.f 0, r0, _PAGE_GLOBAL
- or.z r2, r2, r3 ; r w x r w x
+ or.z r2, r2, r3 ; r w x r w x (!GLOBAL, user page)
and r3, r0, PTE_BITS_NON_RWX_IN_PD1 ; Extract PFN+cache bits from PTE
or r3, r3, r2
diff --git a/arch/arc/plat-arcfpga/Makefile b/arch/arc/plat-arcfpga/Makefile
index 4d1bddc34b5b..66fd0ecd68b3 100644
--- a/arch/arc/plat-arcfpga/Makefile
+++ b/arch/arc/plat-arcfpga/Makefile
@@ -8,5 +8,5 @@
KBUILD_CFLAGS += -Iarch/arc/plat-arcfpga/include
-obj-y := platform.o irq.o
+obj-y := platform.o
obj-$(CONFIG_ISS_SMP_EXTN) += smp.o
diff --git a/arch/arc/plat-arcfpga/include/plat/irq.h b/arch/arc/plat-arcfpga/include/plat/irq.h
index 6adbc53c3a5b..2c9dea690ac4 100644
--- a/arch/arc/plat-arcfpga/include/plat/irq.h
+++ b/arch/arc/plat-arcfpga/include/plat/irq.h
@@ -24,6 +24,4 @@
#define IDU_INTERRUPT_0 16
#endif
-extern void __init plat_fpga_init_IRQ(void);
-
#endif
diff --git a/arch/arc/plat-arcfpga/irq.c b/arch/arc/plat-arcfpga/irq.c
deleted file mode 100644
index d2215fd889c2..000000000000
--- a/arch/arc/plat-arcfpga/irq.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * ARC FPGA Platform IRQ hookups
- *
- * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/interrupt.h>
-#include <plat/irq.h>
-
-void __init plat_fpga_init_IRQ(void)
-{
- /*
- * SMP Hack because UART IRQ hardwired to cpu0 (boot-cpu) but if the
- * request_irq() comes from any other CPU, the low level IRQ unamsking
- * essential for getting Interrupts won't be enabled on cpu0, locking
- * up the UART state machine.
- */
-#ifdef CONFIG_SMP
- arch_unmask_irq(UART0_IRQ);
-#endif
-}
diff --git a/arch/arc/plat-arcfpga/platform.c b/arch/arc/plat-arcfpga/platform.c
index b8d0d456627f..1038949a99a1 100644
--- a/arch/arc/plat-arcfpga/platform.c
+++ b/arch/arc/plat-arcfpga/platform.c
@@ -57,7 +57,6 @@ MACHINE_START(ANGEL4, "angel4")
.dt_compat = aa4_compat,
.init_early = plat_fpga_early_init,
.init_machine = plat_fpga_populate_dev,
- .init_irq = plat_fpga_init_IRQ,
#ifdef CONFIG_ISS_SMP_EXTN
.init_smp = iss_model_init_smp,
#endif
@@ -72,7 +71,6 @@ MACHINE_START(ML509, "ml509")
.dt_compat = ml509_compat,
.init_early = plat_fpga_early_init,
.init_machine = plat_fpga_populate_dev,
- .init_irq = plat_fpga_init_IRQ,
#ifdef CONFIG_SMP
.init_smp = iss_model_init_smp,
#endif
@@ -87,5 +85,4 @@ MACHINE_START(NSIMOSCI, "nsimosci")
.dt_compat = nsimosci_compat,
.init_early = NULL,
.init_machine = plat_fpga_populate_dev,
- .init_irq = NULL,
MACHINE_END
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 21ca0cebcab0..32640c431a08 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -19,7 +19,7 @@
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
-#define __NR_syscalls (384)
+#define __NR_syscalls (388)
/*
* *NOTE*: This is a ghost syscall private to the kernel. Only the
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index 767ea204334e..3aaa75cae90c 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -410,6 +410,8 @@
#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
#define __NR_seccomp (__NR_SYSCALL_BASE+383)
+#define __NR_getrandom (__NR_SYSCALL_BASE+384)
+#define __NR_memfd_create (__NR_SYSCALL_BASE+385)
/*
* The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index bea85f97f363..9f899d8fdcca 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -393,6 +393,8 @@
CALL(sys_sched_getattr)
CALL(sys_renameat2)
CALL(sys_seccomp)
+ CALL(sys_getrandom)
+/* 385 */ CALL(sys_memfd_create)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7c4fada440f0..9388a3d479e1 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -47,6 +47,9 @@
#include <asm/mach/arch.h>
#include <asm/mpu.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
{
- if (!smp_cross_call)
- smp_cross_call = fn;
-}
-
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
- smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
- smp_cross_call(mask, IPI_WAKEUP);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
- smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+ if (!__smp_cross_call)
+ __smp_cross_call = fn;
}
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
- if (is_smp())
- smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
#define S(x,s) [x] = s
S(IPI_WAKEUP, "CPU wakeup interrupts"),
S(IPI_TIMER, "Timer broadcast interrupts"),
@@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
S(IPI_COMPLETION, "completion interrupts"),
};
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+ trace_ipi_raise(target, ipi_types[ipinr]);
+ __smp_cross_call(target, ipinr);
+}
+
void show_ipi_list(struct seq_file *p, int prec)
{
unsigned int cpu, i;
@@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
return sum;
}
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_WAKEUP);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+ if (is_smp())
+ smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
void tick_broadcast(const struct cpumask *mask)
{
@@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
unsigned int cpu = smp_processor_id();
struct pt_regs *old_regs = set_irq_regs(regs);
- if (ipinr < NR_IPI)
+ if ((unsigned)ipinr < NR_IPI) {
+ trace_ipi_entry(ipi_types[ipinr]);
__inc_irq_stat(cpu, ipi_irqs[ipinr]);
+ }
switch (ipinr) {
case IPI_WAKEUP:
@@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
cpu, ipinr);
break;
}
+
+ if ((unsigned)ipinr < NR_IPI)
+ trace_ipi_exit(ipi_types[ipinr]);
set_irq_regs(old_regs);
}
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index e4c8acfc1323..1a24e9232ec8 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -146,12 +146,11 @@ ENDPROC(cpu_v7_set_pte_ext)
mov \tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits
mov \ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT @ lower bits
addls \ttbr1, \ttbr1, #TTBR1_OFFSET
- mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1
+ adcls \tmp, \tmp, #0
+ mcrr p15, 1, \ttbr1, \tmp, c2 @ load TTBR1
mov \tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits
mov \ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT @ lower bits
- mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0
- mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1
- mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0
+ mcrr p15, 0, \ttbr0, \tmp, c2 @ load TTBR0
.endm
/*
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
index 7c275e3b640f..eeaa97559bab 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -24,22 +24,21 @@
extern const compat_ulong_t aarch32_sigret_code[6];
-int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
+int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
-int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs);
+int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs);
void compat_setup_restart_syscall(struct pt_regs *regs);
#else
-static inline int compat_setup_frame(int usid, struct k_sigaction *ka,
+static inline int compat_setup_frame(int usid, struct ksignal *ksig,
sigset_t *set, struct pt_regs *regs)
{
return -ENOSYS;
}
-static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *set,
+static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
return -ENOSYS;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 6357b9c6c90e..6fa792137eda 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -209,19 +209,13 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
return err;
}
-static struct rt_sigframe __user *get_sigframe(struct k_sigaction *ka,
+static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs)
{
unsigned long sp, sp_top;
struct rt_sigframe __user *frame;
- sp = sp_top = regs->sp;
-
- /*
- * This is the X/Open sanctioned signal stack switching.
- */
- if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
- sp = sp_top = current->sas_ss_sp + current->sas_ss_size;
+ sp = sp_top = sigsp(regs->sp, ksig);
sp = (sp - sizeof(struct rt_sigframe)) & ~15;
frame = (struct rt_sigframe __user *)sp;
@@ -253,13 +247,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
regs->regs[30] = (unsigned long)sigtramp;
}
-static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs);
+ frame = get_sigframe(ksig, regs);
if (!frame)
return 1;
@@ -269,9 +263,9 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
err |= setup_sigframe(frame, regs, set);
if (err == 0) {
- setup_return(regs, ka, frame, usig);
- if (ka->sa.sa_flags & SA_SIGINFO) {
- err |= copy_siginfo_to_user(&frame->info, info);
+ setup_return(regs, &ksig->ka, frame, usig);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
regs->regs[1] = (unsigned long)&frame->info;
regs->regs[2] = (unsigned long)&frame->uc;
}
@@ -291,13 +285,12 @@ static void setup_restart_syscall(struct pt_regs *regs)
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
sigset_t *oldset = sigmask_to_save();
- int usig = sig;
+ int usig = ksig->sig;
int ret;
/*
@@ -310,13 +303,12 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
* Set up the stack frame
*/
if (is_compat_task()) {
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = compat_setup_rt_frame(usig, ka, info, oldset,
- regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
else
- ret = compat_setup_frame(usig, ka, oldset, regs);
+ ret = compat_setup_frame(usig, ksig, oldset, regs);
} else {
- ret = setup_rt_frame(usig, ka, info, oldset, regs);
+ ret = setup_rt_frame(usig, ksig, oldset, regs);
}
/*
@@ -324,18 +316,14 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
ret |= !valid_user_regs(&regs->user_regs);
- if (ret != 0) {
- force_sigsegv(sig, tsk);
- return;
- }
-
/*
* Fast forward the stepping logic so we step into the signal
* handler.
*/
- user_fastforward_single_step(tsk);
+ if (!ret)
+ user_fastforward_single_step(tsk);
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -350,10 +338,9 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
static void do_signal(struct pt_regs *regs)
{
unsigned long continue_addr = 0, restart_addr = 0;
- struct k_sigaction ka;
- siginfo_t info;
- int signr, retval = 0;
+ int retval = 0;
int syscall = (int)regs->syscallno;
+ struct ksignal ksig;
/*
* If we were from a system call, check for system call restarting...
@@ -387,8 +374,7 @@ static void do_signal(struct pt_regs *regs)
* Get the signal to deliver. When running under ptrace, at this point
* the debugger may change all of our registers.
*/
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/*
* Depending on the signal settings, we may need to revert the
* decision to restart the system call, but skip this if a
@@ -398,12 +384,12 @@ static void do_signal(struct pt_regs *regs)
(retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK ||
(retval == -ERESTARTSYS &&
- !(ka.sa.sa_flags & SA_RESTART)))) {
+ !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
regs->regs[0] = -EINTR;
regs->pc = continue_addr;
}
- handle_signal(signr, &ka, &info, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index c5ee208321c3..1b9ad02837cf 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -407,20 +407,14 @@ badframe:
return 0;
}
-static void __user *compat_get_sigframe(struct k_sigaction *ka,
+static void __user *compat_get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
int framesize)
{
- compat_ulong_t sp = regs->compat_sp;
+ compat_ulong_t sp = sigsp(regs->compat_sp, ksig);
void __user *frame;
/*
- * This is the X/Open sanctioned signal stack switching.
- */
- if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
-
- /*
* ATPCS B01 mandates 8-byte alignment
*/
frame = compat_ptr((compat_uptr_t)((sp - framesize) & ~7));
@@ -520,18 +514,18 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
/*
* 32-bit signal handling routines called from signal.c
*/
-int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+int compat_setup_rt_frame(int usig, struct ksignal *ksig,
sigset_t *set, struct pt_regs *regs)
{
struct compat_rt_sigframe __user *frame;
int err = 0;
- frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+ frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame)
return 1;
- err |= copy_siginfo_to_user32(&frame->info, info);
+ err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
__put_user_error(0, &frame->sig.uc.uc_flags, err);
__put_user_error(0, &frame->sig.uc.uc_link, err);
@@ -541,7 +535,7 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
err |= compat_setup_sigframe(&frame->sig, regs, set);
if (err == 0) {
- compat_setup_return(regs, ka, frame->sig.retcode, frame, usig);
+ compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
}
@@ -549,13 +543,13 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
return err;
}
-int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
+int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct compat_sigframe __user *frame;
int err = 0;
- frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+ frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
if (!frame)
return 1;
@@ -564,7 +558,7 @@ int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
err |= compat_setup_sigframe(frame, regs, set);
if (err == 0)
- compat_setup_return(regs, ka, frame->retcode, frame, usig);
+ compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
return err;
}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 3e2f5ebbf63e..474339718105 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -51,6 +51,9 @@
#include <asm/tlbflush.h>
#include <asm/ptrace.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -313,8 +316,6 @@ void __init smp_prepare_boot_cpu(void)
set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
}
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
-
/*
* Enumerate the possible CPU set from the device tree and build the
* cpu logical map array containing MPIDR values related to logical
@@ -469,32 +470,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
}
}
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
{
- smp_cross_call = fn;
+ __smp_cross_call = fn;
}
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
- smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
- smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
-}
-
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
- if (smp_cross_call)
- smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
-#define S(x,s) [x - IPI_RESCHEDULE] = s
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
+#define S(x,s) [x] = s
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
S(IPI_CALL_FUNC, "Function call interrupts"),
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
@@ -503,12 +487,18 @@ static const char *ipi_types[NR_IPI] = {
S(IPI_IRQ_WORK, "IRQ work interrupts"),
};
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+ trace_ipi_raise(target, ipi_types[ipinr]);
+ __smp_cross_call(target, ipinr);
+}
+
void show_ipi_list(struct seq_file *p, int prec)
{
unsigned int cpu, i;
for (i = 0; i < NR_IPI; i++) {
- seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
+ seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
prec >= 4 ? " " : "");
for_each_online_cpu(cpu)
seq_printf(p, "%10u ",
@@ -528,6 +518,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
return sum;
}
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+ if (__smp_cross_call)
+ smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
static DEFINE_RAW_SPINLOCK(stop_lock);
/*
@@ -559,8 +567,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
unsigned int cpu = smp_processor_id();
struct pt_regs *old_regs = set_irq_regs(regs);
- if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
- __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
+ if ((unsigned)ipinr < NR_IPI) {
+ trace_ipi_entry(ipi_types[ipinr]);
+ __inc_irq_stat(cpu, ipi_irqs[ipinr]);
+ }
switch (ipinr) {
case IPI_RESCHEDULE:
@@ -605,6 +615,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
break;
}
+
+ if ((unsigned)ipinr < NR_IPI)
+ trace_ipi_exit(ipi_types[ipinr]);
set_irq_regs(old_regs);
}
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index b80c0b3d2bab..d309fbcc3bd6 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -127,24 +127,20 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
}
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
+get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize)
{
- unsigned long sp = regs->sp;
-
- if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ unsigned long sp = sigsp(regs->sp, ksig);
return (void __user *)((sp - framesize) & ~3);
}
static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
err = -EFAULT;
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto out;
@@ -164,7 +160,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
&frame->retcode);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Set up the ucontext */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -176,12 +172,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (err)
goto out;
- regs->r12 = sig;
+ regs->r12 = ksig->sig;
regs->r11 = (unsigned long) &frame->info;
regs->r10 = (unsigned long) &frame->uc;
regs->sp = (unsigned long) frame;
- if (ka->sa.sa_flags & SA_RESTORER)
- regs->lr = (unsigned long)ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
else {
printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
current->comm, current->pid);
@@ -189,10 +185,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
- current->comm, current->pid, sig, regs->sp,
- regs->pc, ka->sa.sa_handler, regs->lr);
+ current->comm, current->pid, ksig->sig, regs->sp,
+ regs->pc, ksig->ka.sa.sa_handler, regs->lr);
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
out:
return err;
@@ -208,15 +204,14 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
}
static inline void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs *regs, int syscall)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall)
{
int ret;
/*
* Set up the stack frame
*/
- ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
/*
* Check that the resulting registers are sane
@@ -226,10 +221,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
/*
* Block the signal if we were successful.
*/
- if (ret != 0)
- force_sigsegv(sig, current);
- else
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -239,9 +231,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which is why we may in
@@ -251,18 +241,18 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ get_signal(&ksig);
if (syscall) {
switch (regs->r12) {
case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND:
- if (signr > 0) {
+ if (ksig.sig > 0) {
regs->r12 = -EINTR;
break;
}
/* fall through */
case -ERESTARTSYS:
- if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
+ if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->r12 = -EINTR;
break;
}
@@ -272,13 +262,13 @@ static void do_signal(struct pt_regs *regs, int syscall)
}
}
- if (signr == 0) {
+ if (!ksig.sig) {
/* No signal to deliver -- put the saved sigmask back */
restore_saved_sigmask();
return;
}
- handle_signal(signr, &ka, &info, regs, syscall);
+ handle_signal(&ksig, regs, syscall);
}
asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index b022af6c48f8..ef275571d885 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -135,40 +135,31 @@ static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *reg
return err;
}
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static inline void *get_sigframe(struct ksignal *ksig,
size_t frame_size)
{
- unsigned long usp;
+ unsigned long usp = sigsp(rdusp(), ksig);
- /* Default to using normal stack. */
- usp = rdusp();
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!on_sig_stack(usp))
- usp = current->sas_ss_sp + current->sas_ss_size;
- }
return (void *)((usp - frame_size) & -8UL);
}
static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
- sigset_t * set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
err |= __put_user((current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
- && sig < 32
+ && ksig->sig < 32
? current_thread_info()->exec_domain->
- signal_invmap[sig] : sig), &frame->sig);
+ signal_invmap[ksig->sig] : ksig->sig), &frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -183,7 +174,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
/* Set up registers for signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor *) ka->sa.sa_handler;
+ (struct fdpic_func_descriptor *) ksig->ka.sa.sa_handler;
u32 pc, p3;
err |= __get_user(pc, &funcptr->text);
err |= __get_user(p3, &funcptr->GOT);
@@ -192,7 +183,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
regs->pc = pc;
regs->p3 = p3;
} else
- regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
wrusp((unsigned long)frame);
regs->rets = SIGRETURN_STUB;
@@ -237,20 +228,19 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
* OK, we're invoking a handler
*/
static void
-handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
+ int ret;
+
/* are we from a system call? to see pt_regs->orig_p0 */
if (regs->orig_p0 >= 0)
/* If so, check system call restarting.. */
- handle_restart(regs, ka, 1);
+ handle_restart(regs, &ksig->ka, 1);
/* set up the stack frame */
- if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
- force_sigsegv(sig, current);
- else
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
+
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -264,16 +254,13 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/
asmlinkage void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
current->thread.esp0 = (unsigned long)regs;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, &ka, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
index 3998b24e26f2..fe68226f6c4d 100644
--- a/arch/c6x/kernel/signal.c
+++ b/arch/c6x/kernel/signal.c
@@ -127,17 +127,11 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
return err;
}
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
unsigned long framesize)
{
- unsigned long sp = regs->sp;
-
- /*
- * This is the X/Open sanctioned signal stack switching.
- */
- if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
- sp = current->sas_ss_sp + current->sas_ss_size;
+ unsigned long sp = sigsp(regs->sp, ksig);
/*
* No matter what happens, 'sp' must be dword
@@ -146,21 +140,21 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
return (void __user *)((sp - framesize) & ~7);
}
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long __user *retcode;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto segv_and_exit;
+ return -EFAULT;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Clear all the bits of the ucontext we don't use. */
err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -188,7 +182,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
#undef COPY
if (err)
- goto segv_and_exit;
+ return -EFAULT;
flush_icache_range((unsigned long) &frame->retcode,
(unsigned long) &frame->retcode + RETCODE_SIZE);
@@ -198,10 +192,10 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
/* Change user context to branch to signal handler */
regs->sp = (unsigned long) frame - 8;
regs->b3 = (unsigned long) retcode;
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
/* Give the signal number to the handler */
- regs->a4 = signr;
+ regs->a4 = ksig->sig;
/*
* For realtime signals we must also set the second and third
@@ -212,10 +206,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
regs->a6 = (unsigned long)&frame->uc;
return 0;
-
-segv_and_exit:
- force_sigsegv(signr, current);
- return -EFAULT;
}
static inline void
@@ -245,10 +235,11 @@ do_restart:
/*
* handle the actual delivery of a signal to userspace
*/
-static void handle_signal(int sig,
- siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs, int syscall)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
+ int syscall)
{
+ int ret;
+
/* Are we from a system call? */
if (syscall) {
/* If so, check system call restarting.. */
@@ -259,7 +250,7 @@ static void handle_signal(int sig,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->a4 = -EINTR;
break;
}
@@ -272,9 +263,8 @@ static void handle_signal(int sig,
}
/* Set up the stack frame */
- if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
- return;
- signal_delivered(sig, info, ka, regs, 0);
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -282,18 +272,15 @@ static void handle_signal(int sig,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
/* we want the common case to go fast, which is why we may in certain
* cases get here from kernel mode */
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka, regs, syscall);
+ if (get_signal(&ksig)) {
+ handle_signal(&ksig, regs, syscall);
return;
}
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 61ce6273a895..9b32d338838b 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -203,15 +203,9 @@ static int setup_sigcontext(struct sigcontext __user *sc,
* - usually on the stack. */
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
{
- unsigned long sp = rdusp();
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (! on_sig_stack(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
+ unsigned long sp = sigsp(rdusp(), ksig);
/* make sure the frame is dword-aligned */
@@ -228,33 +222,33 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
* user-mode trampoline.
*/
-static int setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct sigframe __user *frame;
unsigned long return_ip;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- return_ip = (unsigned long)ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
} else {
/* trampoline - the desired return ip is the retcode itself */
return_ip = (unsigned long)&frame->retcode;
@@ -265,42 +259,38 @@ static int setup_frame(int sig, struct k_sigaction *ka,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
- regs->irp = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */
+ regs->irp = (unsigned long) ksig->ka.sa.sa_handler; /* what we enter NOW */
regs->srp = return_ip; /* what we enter LATER */
- regs->r10 = sig; /* first argument is signo */
+ regs->r10 = ksig->sig; /* first argument is signo */
/* actually move the usp to reflect the stacked frame */
wrusp((unsigned long)frame);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long return_ip;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Clear all the bits of the ucontext we don't use. */
err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -312,12 +302,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __save_altstack(&frame->uc.uc_stack, rdusp());
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- return_ip = (unsigned long)ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
} else {
/* trampoline - the desired return ip is the retcode itself */
return_ip = (unsigned long)&frame->retcode;
@@ -329,18 +319,18 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* TODO what is the current->exec_domain stuff and invmap ? */
/* Set up registers for signal handler */
/* What we enter NOW */
- regs->irp = (unsigned long) ka->sa.sa_handler;
+ regs->irp = (unsigned long) ksig->ka.sa.sa_handler;
/* What we enter LATER */
regs->srp = return_ip;
/* First argument is signo */
- regs->r10 = sig;
+ regs->r10 = ksig->sig;
/* Second argument is (siginfo_t *) */
regs->r11 = (unsigned long)&frame->info;
/* Third argument is unused */
@@ -350,19 +340,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
wrusp((unsigned long)frame);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
-static inline void handle_signal(int canrestart, unsigned long sig,
- siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs)
+static inline void handle_signal(int canrestart, struct ksignal *ksig,
+ struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -383,7 +368,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
/* ERESTARTSYS means to restart the syscall if
* there is no handler or the handler was
* registered with SA_RESTART */
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r10 = -EINTR;
break;
}
@@ -396,13 +381,12 @@ static inline void handle_signal(int canrestart, unsigned long sig,
}
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
+ ret = setup_frame(ksig, oldset, regs);
- if (ret == 0)
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -419,9 +403,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
void do_signal(int canrestart, struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which
@@ -432,10 +414,9 @@ void do_signal(int canrestart, struct pt_regs *regs)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(canrestart, signr, &info, &ka, regs);
+ handle_signal(canrestart, &ksig, regs);
return;
}
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 01d1375c9004..78ce3b1c9bcb 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -189,17 +189,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
/* Figure out where to put the new signal frame - usually on the stack. */
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
{
- unsigned long sp;
-
- sp = rdusp();
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!on_sig_stack(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
+ unsigned long sp = sigsp(rdusp(), ksig);
/* Make sure the frame is dword-aligned. */
sp &= ~3;
@@ -215,23 +207,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
* trampoline.
*/
static int
-setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
- struct pt_regs * regs)
+setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
int err;
unsigned long return_ip;
struct signal_frame __user *frame;
err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
@@ -239,14 +230,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Set up to return from user-space. If provided, use a stub
* already located in user-space.
*/
- if (ka->sa.sa_flags & SA_RESTORER) {
- return_ip = (unsigned long)ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
} else {
/* Trampoline - the desired return ip is in the signal return page. */
return_ip = cris_signal_return_page;
@@ -264,7 +255,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Set up registers for signal handler.
@@ -273,42 +264,37 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
* Where the code enter later.
* First argument, signo.
*/
- regs->erp = (unsigned long) ka->sa.sa_handler;
+ regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
regs->srp = return_ip;
- regs->r10 = sig;
+ regs->r10 = ksig->sig;
/* Actually move the USP to reflect the stacked frame. */
wrusp((unsigned long)frame);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs * regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
int err;
unsigned long return_ip;
struct rt_signal_frame __user *frame;
err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
/* TODO: what is the current->exec_domain stuff and invmap ? */
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Clear all the bits of the ucontext we don't use. */
err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -317,14 +303,14 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __save_altstack(&frame->uc.uc_stack, rdusp());
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Set up to return from user-space. If provided, use a stub
* already located in user-space.
*/
- if (ka->sa.sa_flags & SA_RESTORER) {
- return_ip = (unsigned long) ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ return_ip = (unsigned long) ksig->ka.sa.sa_restorer;
} else {
/* Trampoline - the desired return ip is in the signal return page. */
return_ip = cris_signal_return_page + 6;
@@ -345,7 +331,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Set up registers for signal handler.
@@ -356,9 +342,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* Second argument is (siginfo_t *).
* Third argument is unused.
*/
- regs->erp = (unsigned long) ka->sa.sa_handler;
+ regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
regs->srp = return_ip;
- regs->r10 = sig;
+ regs->r10 = ksig->sig;
regs->r11 = (unsigned long) &frame->info;
regs->r12 = 0;
@@ -366,17 +352,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
wrusp((unsigned long)frame);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/* Invoke a signal handler to, well, handle the signal. */
static inline void
-handle_signal(int canrestart, unsigned long sig,
- siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs * regs)
+handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -404,7 +384,7 @@ handle_signal(int canrestart, unsigned long sig,
* there is no handler, or the handler
* was registered with SA_RESTART.
*/
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r10 = -EINTR;
break;
}
@@ -423,13 +403,12 @@ handle_signal(int canrestart, unsigned long sig,
}
/* Set up the stack frame. */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
+ ret = setup_frame(ksig, oldset, regs);
- if (ret == 0)
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -446,9 +425,7 @@ handle_signal(int canrestart, unsigned long sig,
void
do_signal(int canrestart, struct pt_regs *regs)
{
- int signr;
- siginfo_t info;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* The common case should go fast, which is why this point is
@@ -458,11 +435,9 @@ do_signal(int canrestart, struct pt_regs *regs)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(canrestart, signr, &info, &ka, regs);
+ handle_signal(canrestart, &ksig, regs);
return;
}
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d822700d4f15..dc3d59de0870 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -158,19 +158,10 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
/*
* Determine which stack to use..
*/
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
size_t frame_size)
{
- unsigned long sp;
-
- /* Default to using normal stack */
- sp = __frame->sp;
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (! sas_ss_flags(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
+ unsigned long sp = sigsp(__frame->sp, ksig);
return (void __user *) ((sp - frame_size) & ~7UL);
@@ -180,17 +171,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
/*
*
*/
-static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
+static int setup_frame(struct ksignal *ksig, sigset_t *set)
{
struct sigframe __user *frame;
- int rsig;
+ int rsig, sig = ksig->sig;
set_fs(USER_DS);
- frame = get_sigframe(ka, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
rsig = sig;
if (sig < 32 &&
@@ -199,22 +190,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
rsig = __current_thread_info->exec_domain->signal_invmap[sig];
if (__put_user(rsig, &frame->sig) < 0)
- goto give_sigsegv;
+ return -EFAULT;
if (setup_sigcontext(&frame->sc, set->sig[0]))
- goto give_sigsegv;
+ return -EFAULT;
if (_NSIG_WORDS > 1) {
if (__copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* Set up to return from userspace. If provided, use a stub
* already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
- goto give_sigsegv;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0)
+ return -EFAULT;
}
else {
/* Set up the following code on the stack:
@@ -224,7 +215,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
- goto give_sigsegv;
+ return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) (frame->retcode + 2));
@@ -233,14 +224,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
/* Set up registers for the signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+ (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
- goto give_sigsegv;
+ return -EFAULT;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
- __frame->pc = (unsigned long) ka->sa.sa_handler;
+ __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
__frame->gr15 = 0;
}
@@ -255,29 +246,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
-
} /* end setup_frame() */
/*****************************************************************************/
/*
*
*/
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set)
{
struct rt_sigframe __user *frame;
- int rsig;
+ int rsig, sig = ksig->sig;
set_fs(USER_DS);
- frame = get_sigframe(ka, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
rsig = sig;
if (sig < 32 &&
@@ -288,28 +273,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user(rsig, &frame->sig) ||
__put_user(&frame->info, &frame->pinfo) ||
__put_user(&frame->uc, &frame->puc))
- goto give_sigsegv;
+ return -EFAULT;
- if (copy_siginfo_to_user(&frame->info, info))
- goto give_sigsegv;
+ if (copy_siginfo_to_user(&frame->info, &ksig->info))
+ return -EFAULT;
/* Create the ucontext. */
if (__put_user(0, &frame->uc.uc_flags) ||
__put_user(NULL, &frame->uc.uc_link) ||
__save_altstack(&frame->uc.uc_stack, __frame->sp))
- goto give_sigsegv;
+ return -EFAULT;
if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
- goto give_sigsegv;
+ return -EFAULT;
if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
* already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
- goto give_sigsegv;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+ return -EFAULT;
}
else {
/* Set up the following code on the stack:
@@ -319,7 +304,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
- goto give_sigsegv;
+ return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) (frame->retcode + 2));
@@ -328,14 +313,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+ (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
- goto give_sigsegv;
+ return -EFAULT;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
- __frame->pc = (unsigned long) ka->sa.sa_handler;
+ __frame->pc = (unsigned long) ksig->ka.sa.sa_handler;
__frame->gr15 = 0;
}
@@ -349,21 +334,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sig, current->comm, current->pid, frame, __frame->pc,
frame->pretcode);
#endif
-
return 0;
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
-
} /* end setup_rt_frame() */
/*****************************************************************************/
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka)
+static void handle_signal(struct ksignal *ksig)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -378,7 +357,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
__frame->gr8 = -EINTR;
break;
}
@@ -392,16 +371,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
}
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset);
else
- ret = setup_frame(sig, ka, oldset);
-
- if (ret)
- return;
+ ret = setup_frame(ksig, oldset);
- signal_delivered(sig, info, ka, __frame,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
} /* end handle_signal() */
/*****************************************************************************/
@@ -412,13 +387,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
*/
static void do_signal(void)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
- signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
- if (signr > 0) {
- handle_signal(signr, &info, &ka);
+ if (get_signal(&ksig)) {
+ handle_signal(&ksig);
return;
}
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index d7c73874b515..eadd70e47e7e 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -36,18 +36,10 @@ struct rt_sigframe {
struct ucontext uc;
};
-static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size)
{
- unsigned long sp = regs->r29;
-
- /* check if we would overflow the alt stack */
- if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
- return (void __user __force *)-1UL;
-
- /* Switch to signal stack if appropriate */
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ unsigned long sp = sigsp(regs->r29, ksig);
return (void __user *)((sp - frame_size) & ~(sizeof(long long) - 1));
}
@@ -112,20 +104,20 @@ static int restore_sigcontext(struct pt_regs *regs,
/*
* Setup signal stack frame with siginfo structure
*/
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
int err = 0;
struct rt_sigframe __user *frame;
struct hexagon_vdso *vdso = current->mm->context.vdso;
- frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+ frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe)))
- goto sigsegv;
+ return -EFAULT;
- if (copy_siginfo_to_user(&frame->info, info))
- goto sigsegv;
+ if (copy_siginfo_to_user(&frame->info, &ksig->info))
+ return -EFAULT;
/* The on-stack signal trampoline is no longer executed;
* however, the libgcc signal frame unwinding code checks for
@@ -137,29 +129,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
if (err)
- goto sigsegv;
+ return -EFAULT;
/* Load r0/r1 pair with signumber/siginfo pointer... */
regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
- | (unsigned long long)signr;
+ | (unsigned long long)ksig->sig;
regs->r02 = (unsigned long) &frame->uc;
regs->r31 = (unsigned long) vdso->rt_signal_trampoline;
pt_psp(regs) = (unsigned long) frame;
- pt_set_elr(regs, (unsigned long)ka->sa.sa_handler);
+ pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler);
return 0;
-
-sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
/*
* Setup invocation of signal handler
*/
-static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
+ int ret;
+
/*
* If we're handling a signal that aborted a system call,
* set up the error return value before adding the signal
@@ -173,7 +162,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
regs->r00 = -EINTR;
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r00 = -EINTR;
break;
}
@@ -193,11 +182,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
* only set up the rt_frame flavor.
*/
/* If there was an error on setup, no signal was delivered. */
- if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
- return;
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -205,17 +192,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
*/
void do_signal(struct pt_regs *regs)
{
- struct k_sigaction sigact;
- siginfo_t info;
- int signo;
+ struct ksignal ksig;
if (!user_mode(regs))
return;
- signo = get_signal_to_deliver(&info, &sigact, regs, NULL);
-
- if (signo > 0) {
- handle_signal(signo, &info, &sigact, regs);
+ if (get_signal(&ksig)) {
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index fb13dc5e8f8c..4254f5d3218c 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -11,7 +11,7 @@
-#define NR_syscalls 315 /* length of syscall table */
+#define NR_syscalls 316 /* length of syscall table */
/*
* The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h
index 7de0a2d65da4..99801c3be914 100644
--- a/arch/ia64/include/uapi/asm/unistd.h
+++ b/arch/ia64/include/uapi/asm/unistd.h
@@ -328,5 +328,6 @@
#define __NR_sched_setattr 1336
#define __NR_sched_getattr 1337
#define __NR_renameat2 1338
+#define __NR_getrandom 1339
#endif /* _UAPI_ASM_IA64_UNISTD_H */
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index ba3d03503e84..4c13837a9269 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1776,6 +1776,7 @@ sys_call_table:
data8 sys_sched_setattr
data8 sys_sched_getattr
data8 sys_renameat2
+ data8 sys_getrandom
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 33cab9a8adff..6d92170be457 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr)
si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current);
- return 0;
+ return 1;
}
static long
-setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
- struct sigscratch *scr)
+setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr)
{
extern char __kernel_sigtramp[];
unsigned long tramp_addr, new_rbs = 0, new_sp;
@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp;
- if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (ksig->ka.sa.sa_flags & SA_ONSTACK) {
int onstack = sas_ss_flags(new_sp);
if (onstack == 0) {
@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
*/
check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
if (!likely(on_sig_stack(check_sp)))
- return force_sigsegv_info(sig, (void __user *)
+ return force_sigsegv_info(ksig->sig, (void __user *)
check_sp);
}
}
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- return force_sigsegv_info(sig, frame);
+ return force_sigsegv_info(ksig->sig, frame);
- err = __put_user(sig, &frame->arg0);
+ err = __put_user(ksig->sig, &frame->arg0);
err |= __put_user(&frame->info, &frame->arg1);
err |= __put_user(&frame->sc, &frame->arg2);
err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */
- err |= __put_user(ka->sa.sa_handler, &frame->handler);
+ err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12);
err |= setup_sigcontext(&frame->sc, set, scr);
if (unlikely(err))
- return force_sigsegv_info(sig, frame);
+ return force_sigsegv_info(ksig->sig, frame);
scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */
scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */
@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
- current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
+ current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
#endif
- return 1;
+ return 0;
}
static long
-handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
- struct sigscratch *scr)
+handle_signal (struct ksignal *ksig, struct sigscratch *scr)
{
- if (!setup_frame(sig, ka, info, sigmask_to_save(), scr))
- return 0;
+ int ret = setup_frame(ksig, sigmask_to_save(), scr);
- signal_delivered(sig, info, ka, &scr->pt,
- test_thread_flag(TIF_SINGLESTEP));
+ if (!ret)
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
- return 1;
+ return ret;
}
/*
@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
void
ia64_do_signal (struct sigscratch *scr, long in_syscall)
{
- struct k_sigaction ka;
- siginfo_t info;
long restart = in_syscall;
long errno = scr->pt.r8;
+ struct ksignal ksig;
/*
* This only loops in the rare cases of handle_signal() failing, in which case we
* need to push through a forced SIGSEGV.
*/
while (1) {
- int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL);
+ get_signal(&ksig);
/*
* get_signal_to_deliver() may have run a debugger (via notify_parent())
@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
*/
restart = 0;
- if (signr <= 0)
+ if (ksig.sig <= 0)
break;
if (unlikely(restart)) {
@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
break;
case ERESTARTSYS:
- if ((ka.sa.sa_flags & SA_RESTART) == 0) {
+ if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
scr->pt.r8 = EINTR;
/* note: scr->pt.r10 is already -1 */
break;
@@ -473,7 +469,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
* Whee! Actually deliver the signal. If the delivery failed, we need to
* continue to iterate in this loop so we can deliver the SIGSEGV...
*/
- if (handle_signal(signr, &ka, &info, scr))
+ if (handle_signal(&ksig, scr))
return;
}
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index d503568cb753..95408b8f130a 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -162,28 +162,22 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
* Determine which stack to use..
*/
static inline void __user *
-get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size)
{
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(sp) == 0)
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
-
- return (void __user *)((sp - frame_size) & -8ul);
+ return (void __user *)((sigsp(sp, ksig) - frame_size) & -8ul);
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int err = 0;
- int signal;
+ int signal, sig = ksig->sig;
- frame = get_sigframe(ka, regs->spu, sizeof(*frame));
+ frame = get_sigframe(ksig, regs->spu, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -193,13 +187,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(signal, &frame->sig);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -208,17 +202,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. */
- regs->lr = (unsigned long)ka->sa.sa_restorer;
+ regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
/* Set up registers for signal handler */
regs->spu = (unsigned long)frame;
regs->r0 = signal; /* Arg for signal handler */
regs->r1 = (unsigned long)&frame->info;
regs->r2 = (unsigned long)&frame->uc;
- regs->bpc = (unsigned long)ka->sa.sa_handler;
+ regs->bpc = (unsigned long)ksig->ka.sa.sa_handler;
set_fs(USER_DS);
@@ -228,10 +222,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
static int prev_insn(struct pt_regs *regs)
@@ -252,9 +242,10 @@ static int prev_insn(struct pt_regs *regs)
*/
static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
+ int ret;
+
/* Are we from a system call? */
if (regs->syscall_nr >= 0) {
/* If so, check system call restarting.. */
@@ -265,7 +256,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->r0 = -EINTR;
break;
}
@@ -278,10 +269,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* Set up the stack frame */
- if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs))
- return;
+ ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -291,9 +281,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which
@@ -304,8 +292,7 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
@@ -313,7 +300,7 @@ static void do_signal(struct pt_regs *regs)
*/
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 57fd286e4b0b..967a8b7e1527 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -835,38 +835,30 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
}
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
{
- unsigned long usp;
-
- /* Default to using normal stack. */
- usp = rdusp();
+ unsigned long usp = sigsp(rdusp(), ksig);
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!sas_ss_flags(usp))
- usp = current->sas_ss_sp + current->sas_ss_size;
- }
return (void __user *)((usp - frame_size) & -8UL);
}
-static int setup_frame (int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct sigframe __user *frame;
int fsize = frame_extra_sizes(regs->format);
struct sigcontext context;
- int err = 0;
+ int err = 0, sig = ksig->sig;
if (fsize < 0) {
#ifdef DEBUG
printk ("setup_frame: Unknown frame format %#x\n",
regs->format);
#endif
- goto give_sigsegv;
+ return -EFAULT;
}
- frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
+ frame = get_sigframe(ksig, sizeof(*frame) + fsize);
if (fsize)
err |= copy_to_user (frame + 1, regs + 1, fsize);
@@ -899,7 +891,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
#endif
if (err)
- goto give_sigsegv;
+ return -EFAULT;
push_cache ((unsigned long) &frame->retcode);
@@ -908,7 +900,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
* to destroy is successfully copied to sigframe.
*/
wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
adjustformat(regs);
/*
@@ -934,28 +926,24 @@ static int setup_frame (int sig, struct k_sigaction *ka,
tregs->sr = regs->sr;
}
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return err;
}
-static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
int fsize = frame_extra_sizes(regs->format);
- int err = 0;
+ int err = 0, sig = ksig->sig;
if (fsize < 0) {
#ifdef DEBUG
printk ("setup_frame: Unknown frame format %#x\n",
regs->format);
#endif
- goto give_sigsegv;
+ return -EFAULT;
}
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, sizeof(*frame));
if (fsize)
err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
@@ -968,7 +956,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
&frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -996,7 +984,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
#endif /* CONFIG_MMU */
if (err)
- goto give_sigsegv;
+ return -EFAULT;
push_cache ((unsigned long) &frame->retcode);
@@ -1005,7 +993,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
* to destroy is successfully copied to sigframe.
*/
wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
adjustformat(regs);
/*
@@ -1031,10 +1019,6 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
tregs->sr = regs->sr;
}
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return err;
}
static inline void
@@ -1074,26 +1058,22 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
* OK, we're invoking a handler
*/
static void
-handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int err;
/* are we from a system call? */
if (regs->orig_d0 >= 0)
/* If so, check system call restarting.. */
- handle_restart(regs, ka, 1);
+ handle_restart(regs, &ksig->ka, 1);
/* set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- err = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ err = setup_rt_frame(ksig, oldset, regs);
else
- err = setup_frame(sig, ka, oldset, regs);
-
- if (err)
- return;
+ err = setup_frame(ksig, oldset, regs);
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(err, ksig, 0);
if (test_thread_flag(TIF_DELAYED_TRACE)) {
regs->sr &= ~0x8000;
@@ -1108,16 +1088,13 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- struct k_sigaction ka;
- int signr;
+ struct ksignal ksig;
current->thread.esp0 = (unsigned long) regs;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/metag/kernel/signal.c b/arch/metag/kernel/signal.c
index b9e4a82d2bd4..0d100d5c1407 100644
--- a/arch/metag/kernel/signal.c
+++ b/arch/metag/kernel/signal.c
@@ -140,13 +140,9 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
/*
* Determine which stack to use..
*/
-static void __user *get_sigframe(struct k_sigaction *ka, unsigned long sp,
- size_t frame_size)
+static void __user *get_sigframe(struct ksignal *ksig, unsigned long sp)
{
- /* Meta stacks grows upwards */
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
- sp = current->sas_ss_sp;
-
+ sp = sigsp(sp, ksig);
sp = (sp + 7) & ~7; /* 8byte align stack */
return (void __user *)sp;
@@ -159,7 +155,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
int err;
unsigned long code;
- frame = get_sigframe(&ksig->ka, regs->REG_SP, sizeof(*frame));
+ frame = get_sigframe(ksig, regs->REG_SP);
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return -EFAULT;
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 49a07a4d76d0..8955a3829cf0 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -145,22 +145,19 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
* Determine which stack to use..
*/
static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size)
{
/* Default to using normal stack */
- unsigned long sp = regs->r1;
-
- if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ unsigned long sp = sigsp(regs->r1, ksig);
return (void __user *)((sp - frame_size) & -8UL);
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
unsigned long address = 0;
#ifdef CONFIG_MMU
@@ -168,10 +165,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
pte_t *ptep;
#endif
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -179,8 +176,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
- if (info)
- err |= copy_siginfo_to_user(&frame->info, info);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -227,7 +224,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
flush_dcache_range(address, address + 8);
#endif
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->r1 = (unsigned long) frame;
@@ -237,7 +234,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
/* Offset to handle microblaze rtid r14, 0 */
- regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
set_fs(USER_DS);
@@ -247,10 +244,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/* Handle restarting system calls */
@@ -283,23 +276,15 @@ do_restart:
*/
static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
- else
- ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
+ ret = setup_rt_frame(ksig, oldset, regs);
- if (ret)
- return;
-
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -313,21 +298,19 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
static void do_signal(struct pt_regs *regs, int in_syscall)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
+
#ifdef DEBUG_SIG
pr_info("do signal: %p %d\n", regs, in_syscall);
pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
regs->r12, current_thread_info()->flags);
#endif
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
if (in_syscall)
- handle_restart(regs, &ka, 1);
- handle_signal(signr, &ka, &info, regs);
+ handle_restart(regs, &ksig.ka, 1);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h
index 909bb6984866..7186bb51b89b 100644
--- a/arch/mips/include/asm/abi.h
+++ b/arch/mips/include/asm/abi.h
@@ -13,13 +13,11 @@
#include <asm/siginfo.h>
struct mips_abi {
- int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr,
- sigset_t *set);
+ int (* const setup_frame)(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set);
const unsigned long signal_return_offset;
- int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr,
- sigset_t *set, siginfo_t *info);
+ int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set);
const unsigned long rt_signal_return_offset;
const unsigned long restart;
};
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index 9c60d09e62a7..06805e09bcd3 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -22,7 +22,7 @@
/*
* Determine which stack to use..
*/
-extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+extern void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size);
/* Check and clear pending FPU exceptions in saved CSR */
extern int fpcsr_pending(unsigned int __user *fpcsr);
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9e60d117e41e..1d57605e4615 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -280,7 +280,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
return err;
}
-void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
size_t frame_size)
{
unsigned long sp;
@@ -295,9 +295,7 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
*/
sp -= 32;
- /* This is the X/Open sanctioned signal stack switching. */
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
- sp = current->sas_ss_sp + current->sas_ss_size;
+ sp = sigsp(sp, ksig);
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
}
@@ -428,20 +426,20 @@ badframe:
}
#ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct sigframe __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto give_sigsegv;
+ return -EFAULT;
err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Arguments to signal handler:
@@ -453,37 +451,32 @@ static int setup_frame(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to the
* struct sigframe.
*/
- regs->regs[ 4] = signr;
+ regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
- regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
#endif
-static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr, sigset_t *set,
- siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto give_sigsegv;
+ return -EFAULT;
/* Create siginfo. */
- err |= copy_siginfo_to_user(&frame->rs_info, info);
+ err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -493,7 +486,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Arguments to signal handler:
@@ -505,22 +498,18 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to
* the struct rt_sigframe.
*/
- regs->regs[ 4] = signr;
+ regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
- regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
struct mips_abi mips_abi = {
@@ -534,8 +523,7 @@ struct mips_abi mips_abi = {
.restart = __NR_restart_syscall
};
-static void handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -557,7 +545,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[2] = EINTR;
break;
case ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[2] = EINTR;
break;
}
@@ -571,29 +559,23 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */
}
- if (sig_uses_siginfo(ka))
+ if (sig_uses_siginfo(&ksig->ka))
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
- ka, regs, sig, oldset, info);
+ ksig, regs, oldset);
else
- ret = abi->setup_frame(vdso + abi->signal_return_offset,
- ka, regs, sig, oldset);
-
- if (ret)
- return;
+ ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
+ regs, oldset);
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
static void do_signal(struct pt_regs *regs)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, &ka, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index bae2e6ee2109..d69179c0d49d 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -490,21 +490,21 @@ badframe:
force_sig(SIGSEGV, current);
}
-static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct sigframe32 __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto give_sigsegv;
+ return -EFAULT;
err |= setup_sigcontext32(regs, &frame->sf_sc);
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Arguments to signal handler:
@@ -516,37 +516,32 @@ static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to the
* struct sigframe.
*/
- regs->regs[ 4] = signr;
+ regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
- regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
-static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr, sigset_t *set,
- siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe32 __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto give_sigsegv;
+ return -EFAULT;
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
- err |= copy_siginfo_to_user32(&frame->rs_info, info);
+ err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -556,7 +551,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Arguments to signal handler:
@@ -568,22 +563,18 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to
* the struct rt_sigframe32.
*/
- regs->regs[ 4] = signr;
+ regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
- regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
/*
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index b2241bb9cac1..f1d4751eead0 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -102,18 +102,18 @@ badframe:
force_sig(SIGSEGV, current);
}
-static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
- struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe_n32 __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
- goto give_sigsegv;
+ return -EFAULT;
/* Create siginfo. */
- err |= copy_siginfo_to_user32(&frame->rs_info, info);
+ err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -123,7 +123,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/*
* Arguments to signal handler:
@@ -135,22 +135,18 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
* $25 and c0_epc point to the signal handler, $29 points to
* the struct rt_sigframe.
*/
- regs->regs[ 4] = signr;
+ regs->regs[ 4] = ksig->sig;
regs->regs[ 5] = (unsigned long) &frame->rs_info;
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) sig_return;
- regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
current->comm, current->pid,
frame, regs->cp0_epc, regs->regs[31]);
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
struct mips_abi mips_abi_n32 = {
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 9dfac5cd16e6..a6c0858592c3 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -186,20 +186,11 @@ static int setup_sigcontext(struct sigcontext __user *sc,
/*
* determine which stack to use..
*/
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
size_t frame_size)
{
- unsigned long sp;
-
- /* default to using normal stack */
- sp = regs->sp;
-
- /* this is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(sp) == 0)
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
+ unsigned long sp = sigsp(regs->sp, ksig);
return (void __user *) ((sp - frame_size) & ~7UL);
}
@@ -207,16 +198,16 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
/*
* set up a normal signal frame
*/
-static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
struct sigframe __user *frame;
- int rsig;
+ int rsig, sig = ksig->sig;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
rsig = sig;
if (sig < 32 &&
@@ -226,40 +217,40 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
if (__put_user(rsig, &frame->sig) < 0 ||
__put_user(&frame->sc, &frame->psc) < 0)
- goto give_sigsegv;
+ return -EFAULT;
if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
- goto give_sigsegv;
+ return -EFAULT;
if (_NSIG_WORDS > 1) {
if (__copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* set up to return from userspace. If provided, use a stub already in
* userspace */
- if (ka->sa.sa_flags & SA_RESTORER) {
- if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
- goto give_sigsegv;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+ return -EFAULT;
} else {
if (__put_user((void (*)(void))frame->retcode,
&frame->pretcode))
- goto give_sigsegv;
+ return -EFAULT;
/* this is mov $,d0; syscall 0 */
if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
__put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
__put_user(0x00, (char *)(frame->retcode + 2)) ||
__put_user(0xf0, (char *)(frame->retcode + 3)) ||
__put_user(0xe0, (char *)(frame->retcode + 4)))
- goto give_sigsegv;
+ return -EFAULT;
flush_icache_range((unsigned long) frame->retcode,
(unsigned long) frame->retcode + 5);
}
/* set up registers for signal handler */
regs->sp = (unsigned long) frame;
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->d0 = sig;
regs->d1 = (unsigned long) &frame->sc;
@@ -270,25 +261,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/*
* set up a realtime signal frame
*/
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
- int rsig;
+ int rsig, sig = ksig->sig;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
rsig = sig;
if (sig < 32 &&
@@ -299,8 +286,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__put_user(rsig, &frame->sig) ||
__put_user(&frame->info, &frame->pinfo) ||
__put_user(&frame->uc, &frame->puc) ||
- copy_siginfo_to_user(&frame->info, info))
- goto give_sigsegv;
+ copy_siginfo_to_user(&frame->info, &ksig->info))
+ return -EFAULT;
/* create the ucontext. */
if (__put_user(0, &frame->uc.uc_flags) ||
@@ -309,13 +296,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
setup_sigcontext(&frame->uc.uc_mcontext,
&frame->fpuctx, regs, set->sig[0]) ||
__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
- goto give_sigsegv;
+ return -EFAULT;
/* set up to return from userspace. If provided, use a stub already in
* userspace */
- if (ka->sa.sa_flags & SA_RESTORER) {
- if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
- goto give_sigsegv;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+ return -EFAULT;
+
} else {
if (__put_user((void(*)(void))frame->retcode,
&frame->pretcode) ||
@@ -326,7 +314,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
__put_user(0x00, (char *)(frame->retcode + 2)) ||
__put_user(0xf0, (char *)(frame->retcode + 3)) ||
__put_user(0xe0, (char *)(frame->retcode + 4)))
- goto give_sigsegv;
+ return -EFAULT;
flush_icache_range((u_long) frame->retcode,
(u_long) frame->retcode + 5);
@@ -334,7 +322,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler */
regs->sp = (unsigned long) frame;
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->d0 = sig;
regs->d1 = (long) &frame->info;
@@ -345,10 +333,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
static inline void stepback(struct pt_regs *regs)
@@ -360,9 +344,7 @@ static inline void stepback(struct pt_regs *regs)
/*
* handle the actual delivery of a signal to userspace
*/
-static int handle_signal(int sig,
- siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs)
+static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -377,7 +359,7 @@ static int handle_signal(int sig,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->d0 = -EINTR;
break;
}
@@ -390,15 +372,12 @@ static int handle_signal(int sig,
}
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
- if (ret)
- return ret;
+ ret = setup_frame(ksig, oldset, regs);
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
return 0;
}
@@ -407,15 +386,10 @@ static int handle_signal(int sig,
*/
static void do_signal(struct pt_regs *regs)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- if (handle_signal(signr, &info, &ka, regs) == 0) {
- }
+ struct ksignal ksig;
+ if (get_signal(&ksig)) {
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 66775bc07a8e..7d1b8235bf90 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -132,30 +132,16 @@ static inline unsigned long align_sigframe(unsigned long sp)
* or the alternate stack.
*/
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs, size_t frame_size)
{
unsigned long sp = regs->sp;
- int onsigstack = on_sig_stack(sp);
/* redzone */
sp -= STACK_FRAME_OVERHEAD;
-
- /* This is the X/Open sanctioned signal stack switching. */
- if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) {
- if (current->sas_ss_size)
- sp = current->sas_ss_sp + current->sas_ss_size;
- }
-
+ sp = sigsp(sp, ksig);
sp = align_sigframe(sp - frame_size);
- /*
- * If we are on the alternate signal stack and would overflow it, don't.
- * Return an always-bogus address instead so we will die with SIGSEGV.
- */
- if (onsigstack && !likely(on_sig_stack(sp)))
- return (void __user *)-1L;
-
return (void __user *)sp;
}
@@ -173,7 +159,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
unsigned long return_ip;
int err = 0;
- frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
+ frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
return -EFAULT;
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 1cba8f29bb49..012d4fa63d97 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -227,8 +227,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_sysc
}
static long
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs, int in_syscall)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
+ int in_syscall)
{
struct rt_sigframe __user *frame;
unsigned long rp, usp;
@@ -241,10 +241,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
usp = (regs->gr[30] & ~(0x01UL));
/*FIXME: frame_size parameter is unused, remove it. */
- frame = get_sigframe(ka, usp, sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
DBG(1,"SETUP_RT_FRAME: START\n");
- DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
+ DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
#ifdef CONFIG_64BIT
@@ -253,7 +253,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (is_compat_task()) {
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
- err |= copy_siginfo_to_user32(&compat_frame->info, info);
+ err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
@@ -265,7 +265,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
{
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
@@ -275,7 +275,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. The first words of tramp are used to
@@ -312,9 +312,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
if (err)
- goto give_sigsegv;
+ return -EFAULT;
- haddr = A(ka->sa.sa_handler);
+ haddr = A(ksig->ka.sa.sa_handler);
/* The sa_handler may be a pointer to a function descriptor */
#ifdef CONFIG_64BIT
if (is_compat_task()) {
@@ -326,7 +326,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
@@ -339,7 +339,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
@@ -386,7 +386,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
regs->gr[2] = rp; /* userland return pointer */
- regs->gr[26] = sig; /* signal number */
+ regs->gr[26] = ksig->sig; /* signal number */
#ifdef CONFIG_64BIT
if (is_compat_task()) {
@@ -410,11 +410,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, current->pid, frame, regs->gr[30],
regs->iaoq[0], regs->iaoq[1], rp);
- return 1;
-
-give_sigsegv:
- DBG(1,"setup_rt_frame: sending SIGSEGV\n");
- force_sigsegv(sig, current);
return 0;
}
@@ -423,20 +418,19 @@ give_sigsegv:
*/
static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs *regs, int in_syscall)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
{
+ int ret;
sigset_t *oldset = sigmask_to_save();
+
DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
- sig, ka, info, oldset, regs);
+ ksig->sig, ksig->ka, ksig->info, oldset, regs);
/* Set up the stack frame */
- if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
- return;
+ ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP) ||
- test_thread_flag(TIF_BLOCKSTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
+ test_thread_flag(TIF_BLOCKSTEP));
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]);
@@ -544,22 +538,18 @@ insert_restart_trampoline(struct pt_regs *regs)
asmlinkage void
do_signal(struct pt_regs *regs, long in_syscall)
{
- siginfo_t info;
- struct k_sigaction ka;
- int signr;
+ struct ksignal ksig;
DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
regs, regs->sr[7], in_syscall);
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
-
- if (signr > 0) {
+ if (get_signal(&ksig)) {
+ DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
/* Restart a system call if necessary. */
if (in_syscall)
- syscall_restart(regs, &ka);
+ syscall_restart(regs, &ksig.ka);
- handle_signal(signr, &info, &ka, regs, in_syscall);
+ handle_signal(&ksig, regs, in_syscall);
return;
}
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 1c794cef2883..cf8c7e4e0b21 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -31,20 +31,14 @@ int show_unhandled_signals = 1;
/*
* Allocate space for the signal frame
*/
-void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
+void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
size_t frame_size, int is_32)
{
unsigned long oldsp, newsp;
/* Default to using normal stack */
oldsp = get_clean_sp(sp, is_32);
-
- /* Check for alt stack */
- if ((ka->sa.sa_flags & SA_ONSTACK) &&
- current->sas_ss_size && !on_sig_stack(oldsp))
- oldsp = (current->sas_ss_sp + current->sas_ss_size);
-
- /* Get aligned frame */
+ oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
/* Check access */
@@ -105,25 +99,23 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
}
}
-static int do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
int ret;
int is32 = is_32bit_task();
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ get_signal(&ksig);
/* Is there any syscall restart business here ? */
- check_syscall_restart(regs, &ka, signr > 0);
+ check_syscall_restart(regs, &ksig.ka, ksig.sig > 0);
- if (signr <= 0) {
+ if (ksig.sig <= 0) {
/* No signal to deliver -- put the saved sigmask back */
restore_saved_sigmask();
regs->trap = 0;
- return 0; /* no signals delivered */
+ return; /* no signals delivered */
}
#ifndef CONFIG_PPC_ADV_DEBUG_REGS
@@ -140,23 +132,16 @@ static int do_signal(struct pt_regs *regs)
thread_change_pc(current, regs);
if (is32) {
- if (ka.sa.sa_flags & SA_SIGINFO)
- ret = handle_rt_signal32(signr, &ka, &info, oldset,
- regs);
+ if (ksig.ka.sa.sa_flags & SA_SIGINFO)
+ ret = handle_rt_signal32(&ksig, oldset, regs);
else
- ret = handle_signal32(signr, &ka, &info, oldset,
- regs);
+ ret = handle_signal32(&ksig, oldset, regs);
} else {
- ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
+ ret = handle_rt_signal64(&ksig, oldset, regs);
}
regs->trap = 0;
- if (ret) {
- signal_delivered(signr, &info, &ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
- }
-
- return ret;
+ signal_setup_done(ret, &ksig, test_thread_flag(TIF_SINGLESTEP));
}
void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index c69b9aeb9f23..51b274199dd9 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -12,15 +12,13 @@
extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
-extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
+extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
size_t frame_size, int is_32);
-extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
+extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs);
-extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
+extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs);
extern unsigned long copy_fpr_to_user(void __user *to,
@@ -44,14 +42,12 @@ extern unsigned long copy_transact_vsx_from_user(struct task_struct *task,
#ifdef CONFIG_PPC64
-extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *set,
+extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
#else /* CONFIG_PPC64 */
-static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *set,
+static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
return -EFAULT;
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 1bc5a1755ed4..b171001698ff 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -981,9 +981,8 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
* Set up a signal frame for a "real-time" signal handler
* (one which gets siginfo).
*/
-int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs *regs)
+int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *rt_sf;
struct mcontext __user *frame;
@@ -995,13 +994,13 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
- rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
+ rt_sf = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
addr = rt_sf;
if (unlikely(rt_sf == NULL))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user(&rt_sf->info, info)
+ if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)
|| __put_user(0, &rt_sf->uc.uc_flags)
|| __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
|| __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
@@ -1051,15 +1050,15 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Fill registers for signal handler */
regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
+ regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long) &rt_sf->info;
regs->gpr[5] = (unsigned long) &rt_sf->uc;
regs->gpr[6] = (unsigned long) rt_sf;
- regs->nip = (unsigned long) ka->sa.sa_handler;
+ regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
/* enter the signal handler in native-endian mode */
regs->msr &= ~MSR_LE;
regs->msr |= (MSR_KERNEL & MSR_LE);
- return 1;
+ return 0;
badframe:
if (show_unhandled_signals)
@@ -1069,8 +1068,7 @@ badframe:
current->comm, current->pid,
addr, regs->nip, regs->link);
- force_sigsegv(sig, current);
- return 0;
+ return 1;
}
static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
@@ -1409,8 +1407,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
/*
* OK, we're invoking a handler
*/
-int handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs)
{
struct sigcontext __user *sc;
struct sigframe __user *frame;
@@ -1420,7 +1417,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
unsigned long tramp;
/* Set up Signal Frame */
- frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1);
+ frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 1);
if (unlikely(frame == NULL))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
@@ -1428,7 +1425,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
#if _NSIG != 64
#error "Please adjust handle_signal()"
#endif
- if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
+ if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler)
|| __put_user(oldset->sig[0], &sc->oldmask)
#ifdef CONFIG_PPC64
|| __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
@@ -1436,7 +1433,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
|| __put_user(oldset->sig[1], &sc->_unused[3])
#endif
|| __put_user(to_user_ptr(&frame->mctx), &sc->regs)
- || __put_user(sig, &sc->signal))
+ || __put_user(ksig->sig, &sc->signal))
goto badframe;
if (vdso32_sigtramp && current->mm->context.vdso_base) {
@@ -1471,12 +1468,12 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
goto badframe;
regs->gpr[1] = newsp;
- regs->gpr[3] = sig;
+ regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long) sc;
- regs->nip = (unsigned long) ka->sa.sa_handler;
+ regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler;
/* enter the signal handler in big-endian mode */
regs->msr &= ~MSR_LE;
- return 1;
+ return 0;
badframe:
if (show_unhandled_signals)
@@ -1486,8 +1483,7 @@ badframe:
current->comm, current->pid,
frame, regs->nip, regs->link);
- force_sigsegv(sig, current);
- return 0;
+ return 1;
}
/*
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 97c1e4b683fc..2cb0c94cafa5 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -708,20 +708,19 @@ badframe:
return 0;
}
-int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long newsp = 0;
long err = 0;
- frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0);
+ frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 0);
if (unlikely(frame == NULL))
goto badframe;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
goto badframe;
@@ -736,15 +735,15 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
&frame->uc_transact.uc_mcontext,
- regs, signr,
+ regs, ksig->sig,
NULL,
- (unsigned long)ka->sa.sa_handler);
+ (unsigned long)ksig->ka.sa.sa_handler);
} else
#endif
{
err |= __put_user(0, &frame->uc.uc_link);
- err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr,
- NULL, (unsigned long)ka->sa.sa_handler,
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, ksig->sig,
+ NULL, (unsigned long)ksig->ka.sa.sa_handler,
1);
}
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -770,7 +769,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
/* Set up "regs" so we "return" to the signal handler. */
if (is_elf2_task()) {
- regs->nip = (unsigned long) ka->sa.sa_handler;
+ regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
regs->gpr[12] = regs->nip;
} else {
/* Handler is *really* a pointer to the function descriptor for
@@ -779,7 +778,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
* entry is the TOC value we need to use.
*/
func_descr_t __user *funct_desc_ptr =
- (func_descr_t __user *) ka->sa.sa_handler;
+ (func_descr_t __user *) ksig->ka.sa.sa_handler;
err |= get_user(regs->nip, &funct_desc_ptr->entry);
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
@@ -789,9 +788,9 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
regs->msr &= ~MSR_LE;
regs->msr |= (MSR_KERNEL & MSR_LE);
regs->gpr[1] = newsp;
- regs->gpr[3] = signr;
+ regs->gpr[3] = ksig->sig;
regs->result = 0;
- if (ka->sa.sa_flags & SA_SIGINFO) {
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
regs->gpr[6] = (unsigned long) frame;
@@ -801,7 +800,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
if (err)
goto badframe;
- return 1;
+ return 0;
badframe:
if (show_unhandled_signals)
@@ -809,6 +808,5 @@ badframe:
current->comm, current->pid, "setup_rt_frame",
(long)frame, regs->nip, regs->link);
- force_sigsegv(signr, current);
- return 0;
+ return 1;
}
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index f204d6920368..598b0b42668b 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -320,38 +320,39 @@ static inline int map_signal(int sig)
return sig;
}
-static int setup_frame32(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs * regs)
+static int setup_frame32(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
- sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+ int sig = ksig->sig;
+ sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(sigframe32));
if (frame == (void __user *) -1UL)
- goto give_sigsegv;
+ return -EFAULT;
if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
- goto give_sigsegv;
+ return -EFAULT;
if (save_sigregs32(regs, &frame->sregs))
- goto give_sigsegv;
+ return -EFAULT;
if (save_sigregs_gprs_high(regs, frame->gprs_high))
- goto give_sigsegv;
+ return -EFAULT;
if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 __force __user *)(frame->retcode)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
@@ -359,7 +360,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
- regs->psw.addr = (__force __u64) ka->sa.sa_handler;
+ regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (__force __u64) &frame->sc;
@@ -376,25 +377,21 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
- goto give_sigsegv;
+ return -EFAULT;
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
int err = 0;
- rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+ rt_sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe32));
if (frame == (void __user *) -1UL)
- goto give_sigsegv;
+ return -EFAULT;
- if (copy_siginfo_to_user32(&frame->info, info))
- goto give_sigsegv;
+ if (copy_siginfo_to_user32(&frame->info, &ksig->info))
+ return -EFAULT;
/* Create the ucontext. */
err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
@@ -404,22 +401,22 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= save_sigregs_gprs_high(regs, frame->gprs_high);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 __force __user *)(frame->retcode)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (__force __u64) frame;
@@ -427,36 +424,30 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
- regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
+ regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
- regs->gprs[2] = map_signal(sig);
+ regs->gprs[2] = map_signal(ksig->sig);
regs->gprs[3] = (__force __u64) &frame->info;
regs->gprs[4] = (__force __u64) &frame->uc;
regs->gprs[5] = task_thread_info(current)->last_break;
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
-void handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
+ struct pt_regs *regs)
{
int ret;
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame32(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame32(ksig, oldset, regs);
else
- ret = setup_frame32(sig, ka, oldset, regs);
- if (ret)
- return;
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLE_STEP));
+ ret = setup_frame32(ksig, oldset, regs);
+
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
}
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 6ac78192455f..1aad48398d06 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -48,8 +48,8 @@ void do_per_trap(struct pt_regs *regs);
void syscall_trace(struct pt_regs *regs, int entryexit);
void kernel_stack_overflow(struct pt_regs * regs);
void do_signal(struct pt_regs *regs);
-void handle_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
+void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
+ struct pt_regs *regs);
void do_notify_resume(struct pt_regs *regs);
void __init init_IRQ(void);
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 42b49f9e19bf..469c4c6d9182 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -200,15 +200,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
frame = get_sigframe(ka, regs, sizeof(sigframe));
if (frame == (void __user *) -1UL)
- goto give_sigsegv;
+ return -EFAULT;
if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
- goto give_sigsegv;
+ return -EFAULT;
if (save_sigregs(regs, &frame->sregs))
- goto give_sigsegv;
+ return -EFAULT;
if (__put_user(&frame->sregs, &frame->sc.sregs))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
@@ -220,12 +220,12 @@ static int setup_frame(int sig, struct k_sigaction *ka,
frame->retcode | PSW_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
(u16 __user *)(frame->retcode)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t __user *) frame))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
@@ -250,27 +250,23 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
- goto give_sigsegv;
+ return -EFAULT;
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
int err = 0;
rt_sigframe __user *frame;
- frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+ frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe));
if (frame == (void __user *) -1UL)
- goto give_sigsegv;
+ return -EFAULT;
- if (copy_siginfo_to_user(&frame->info, info))
- goto give_sigsegv;
+ if (copy_siginfo_to_user(&frame->info, &ksig->info))
+ return -EFAULT;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -279,24 +275,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= save_sigregs(regs, &frame->uc.uc_mcontext);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->gprs[14] = (unsigned long)
- ka->sa.sa_restorer | PSW_ADDR_AMODE;
+ ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE;
} else {
regs->gprs[14] = (unsigned long)
frame->retcode | PSW_ADDR_AMODE;
if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
(u16 __user *)(frame->retcode)))
- goto give_sigsegv;
+ return -EFAULT;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t __user *) frame))
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[15] = (unsigned long) frame;
@@ -304,34 +300,27 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
- regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
+ regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE;
- regs->gprs[2] = map_signal(sig);
+ regs->gprs[2] = map_signal(ksig->sig);
regs->gprs[3] = (unsigned long) &frame->info;
regs->gprs[4] = (unsigned long) &frame->uc;
regs->gprs[5] = task_thread_info(current)->last_break;
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, sigset_t *oldset,
+ struct pt_regs *regs)
{
int ret;
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
- if (ret)
- return;
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLE_STEP));
+ ret = setup_frame(ksig->sig, &ksig->ka, oldset, regs);
+
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
}
/*
@@ -345,9 +334,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
sigset_t *oldset = sigmask_to_save();
/*
@@ -357,9 +344,8 @@ void do_signal(struct pt_regs *regs)
*/
current_thread_info()->system_call =
test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
if (current_thread_info()->system_call) {
regs->int_code = current_thread_info()->system_call;
@@ -370,7 +356,7 @@ void do_signal(struct pt_regs *regs)
regs->gprs[2] = -EINTR;
break;
case -ERESTARTSYS:
- if (!(ka.sa.sa_flags & SA_RESTART)) {
+ if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->gprs[2] = -EINTR;
break;
}
@@ -387,9 +373,9 @@ void do_signal(struct pt_regs *regs)
clear_pt_regs_flag(regs, PIF_SYSCALL);
if (is_compat_task())
- handle_signal32(signr, &ka, &info, oldset, regs);
+ handle_signal32(&ksig, oldset, regs);
else
- handle_signal(signr, &ka, &info, oldset, regs);
+ handle_signal(&ksig, oldset, regs);
return;
}
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index a00fba32b0eb..1651807774ad 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -173,15 +173,15 @@ badframe:
return 0;
}
-static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
- int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
+ sigset_t *set)
{
struct rt_sigframe __user *frame;
int err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
/*
* Set up the return code ...
@@ -194,7 +194,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __put_user(0x80008002, frame->rs_code + 1);
flush_cache_sigtramp((unsigned long) frame->rs_code);
- err |= copy_siginfo_to_user(&frame->rs_info, info);
+ err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
err |= __put_user(0, &frame->rs_uc.uc_flags);
err |= __put_user(NULL, &frame->rs_uc.uc_link);
err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[0]);
@@ -202,26 +202,23 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ return -EFAULT;
regs->regs[0] = (unsigned long) frame;
regs->regs[3] = (unsigned long) frame->rs_code;
- regs->regs[4] = signr;
+ regs->regs[4] = ksig->sig;
regs->regs[5] = (unsigned long) &frame->rs_info;
regs->regs[6] = (unsigned long) &frame->rs_uc;
- regs->regs[29] = (unsigned long) ka->sa.sa_handler;
- regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
+ regs->regs[29] = (unsigned long) ksig->ka.sa.sa_handler;
+ regs->cp0_epc = (unsigned long) ksig->ka.sa.sa_handler;
return 0;
-
-give_sigsegv:
- force_sigsegv(signr, current);
- return -EFAULT;
}
-static void handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
+ int ret;
+
if (regs->is_syscall) {
switch (regs->regs[4]) {
case ERESTART_RESTARTBLOCK:
@@ -229,7 +226,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[4] = EINTR;
break;
case ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[4] = EINTR;
break;
}
@@ -245,17 +242,14 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
/*
* Set up the stack frame
*/
- if (setup_rt_frame(ka, regs, sig, sigmask_to_save(), info) < 0)
- return;
+ ret = setup_rt_frame(ksig, regs, sigmask_to_save());
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
static void do_signal(struct pt_regs *regs)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which is why we may in certain
@@ -265,10 +259,9 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Actually deliver the signal. */
- handle_signal(signr, &info, &ka, regs);
+ handle_signal(&ksig, regs);
return;
}
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 594cd371aa28..2f002b24fb92 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -262,17 +262,17 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
extern void __kernel_sigreturn(void);
extern void __kernel_rt_sigreturn(void);
-static int setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
- frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -288,8 +288,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- regs->pr = (unsigned long) ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
} else if (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_sigreturn);
@@ -309,7 +309,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsigned long) frame;
@@ -319,15 +319,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
+ (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
err |= __get_user(regs->pc, &funcptr->text);
err |= __get_user(regs->regs[12], &funcptr->GOT);
} else
- regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
if (err)
- goto give_sigsegv;
+ return -EFAULT;
set_fs(USER_DS);
@@ -335,23 +335,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
- frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -359,7 +355,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -371,8 +367,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
- regs->pr = (unsigned long) ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
} else if (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
@@ -392,7 +388,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsigned long) frame;
@@ -402,15 +398,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
+ (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
err |= __get_user(regs->pc, &funcptr->text);
err |= __get_user(regs->regs[12], &funcptr->GOT);
} else
- regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
if (err)
- goto give_sigsegv;
+ return -EFAULT;
set_fs(USER_DS);
@@ -418,10 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
static inline void
@@ -455,22 +447,18 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
* OK, we're invoking a handler
*/
static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
- struct pt_regs *regs, unsigned int save_r0)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
+ ret = setup_frame(ksig, oldset, regs);
- if (ret)
- return;
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -484,9 +472,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
*/
static void do_signal(struct pt_regs *regs, unsigned int save_r0)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which
@@ -497,12 +483,11 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_syscall_restart(save_r0, regs, &ka.sa);
+ if (get_signal(&ksig)) {
+ handle_syscall_restart(save_r0, regs, &ksig.ka.sa);
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, regs, save_r0);
+ handle_signal(&ksig, regs, save_r0);
return;
}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 23d4c71c91af..897abe7b871e 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -41,8 +41,7 @@
#define DEBUG_SIG 0
static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs * regs);
+handle_signal(struct ksignal *ksig, struct pt_regs *regs);
static inline void
handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
@@ -82,9 +81,7 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
*/
static void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which
@@ -95,12 +92,11 @@ static void do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, 0);
- if (signr > 0) {
- handle_syscall_restart(regs, &ka.sa);
+ if (get_signal(&ksig)) {
+ handle_syscall_restart(regs, &ksig.ka.sa);
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, &ka, regs);
+ handle_signal(&ksig, regs);
return;
}
@@ -378,17 +374,16 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
void sa_default_restorer(void); /* See comments below */
void sa_default_rt_restorer(void); /* See comments below */
-static int setup_frame(int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
- frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -400,7 +395,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Give up earlier as i386, in case */
if (err)
- goto give_sigsegv;
+ return -EFAULT;
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
@@ -408,16 +403,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
/* Give up earlier as i386, in case */
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
/*
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = neff_sign_extend((unsigned long)
- ka->sa.sa_restorer | 0x1);
+ ksig->ka->sa.sa_restorer | 0x1);
} else {
/*
* Different approach on SH5.
@@ -435,7 +430,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
if (__copy_to_user(frame->retcode,
(void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
- goto give_sigsegv;
+ return -EFAULT;
/* Cohere the trampoline with the I-cache. */
flush_cache_sigtramp(DEREF_REG_PR-1);
@@ -460,7 +455,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
- regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
+ regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
set_fs(USER_DS);
@@ -471,23 +466,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
- frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ return -EFAULT;
signal = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -497,11 +488,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
/* Give up earlier as i386, in case */
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
@@ -513,16 +504,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Give up earlier as i386, in case */
if (err)
- goto give_sigsegv;
+ return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- if (ka->sa.sa_flags & SA_RESTORER) {
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
/*
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = neff_sign_extend((unsigned long)
- ka->sa.sa_restorer | 0x1);
+ ksig->ka.sa.sa_restorer | 0x1);
} else {
/*
* Different approach on SH5.
@@ -540,7 +531,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (__copy_to_user(frame->retcode,
(void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
- goto give_sigsegv;
+ return -EFAULT;
/* Cohere the trampoline with the I-cache. */
flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
@@ -554,7 +545,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
- regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
+ regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
set_fs(USER_DS);
@@ -564,33 +555,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
- struct pt_regs * regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
/* Set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(sig, ka, oldset, regs);
-
- if (ret)
- return;
+ ret = setup_frame(ksig, oldset, regs);
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index ffd4493efc78..c14e36f008c8 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -267,8 +267,7 @@ static inline int is_compat_task(void)
return current_thread_info()->status & TS_COMPAT;
}
-extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *set,
+extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
/* Compat syscalls. */
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 19c04b5ce408..8c5abf2e4794 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -190,18 +190,18 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
return (void __user *) sp;
}
-int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
unsigned long restorer;
struct compat_rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int usig;
- frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+ frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ goto err;
usig = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -210,12 +210,12 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
: sig;
/* Always write at least the signal number for the stack backtracer. */
- if (ka->sa.sa_flags & SA_SIGINFO) {
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
/* At sigreturn time, restore the callee-save registers too. */
- err |= copy_siginfo_to_user32(&frame->info, info);
+ err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
regs->flags |= PT_FLAGS_RESTORE_REGS;
} else {
- err |= __put_user(info->si_signo, &frame->info.si_signo);
+ err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
}
/* Create the ucontext. */
@@ -226,11 +226,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ goto err;
restorer = VDSO_SYM(&__vdso_rt_sigreturn);
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
/*
* Set up registers for signal handler.
@@ -239,7 +239,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
* since some things rely on this (e.g. glibc's debug/segfault.c).
*/
- regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
+ regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
regs->sp = ptr_to_compat_reg(frame);
regs->lr = restorer;
@@ -249,7 +249,8 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->flags |= PT_FLAGS_CALLER_SAVES;
return 0;
-give_sigsegv:
- signal_fault("bad setup frame", regs, frame, sig);
+err:
+ trace_unhandled_signal("bad sigreturn frame", regs,
+ (unsigned long)frame, SIGSEGV);
return -EFAULT;
}
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index d1d026f01267..7c2fecc52177 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -153,18 +153,18 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
return (void __user *) sp;
}
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
unsigned long restorer;
struct rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int usig;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- goto give_sigsegv;
+ goto err;
usig = current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
@@ -173,12 +173,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
: sig;
/* Always write at least the signal number for the stack backtracer. */
- if (ka->sa.sa_flags & SA_SIGINFO) {
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
/* At sigreturn time, restore the callee-save registers too. */
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
regs->flags |= PT_FLAGS_RESTORE_REGS;
} else {
- err |= __put_user(info->si_signo, &frame->info.si_signo);
+ err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
}
/* Create the ucontext. */
@@ -189,11 +189,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
- goto give_sigsegv;
+ goto err;
restorer = VDSO_SYM(&__vdso_rt_sigreturn);
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = (unsigned long) ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ restorer = (unsigned long) ksig->ka.sa.sa_restorer;
/*
* Set up registers for signal handler.
@@ -202,7 +202,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* We always pass siginfo and mcontext, regardless of SA_SIGINFO,
* since some things rely on this (e.g. glibc's debug/segfault.c).
*/
- regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
regs->sp = (unsigned long) frame;
regs->lr = restorer;
@@ -212,8 +212,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->flags |= PT_FLAGS_CALLER_SAVES;
return 0;
-give_sigsegv:
- signal_fault("bad setup frame", regs, frame, sig);
+err:
+ trace_unhandled_signal("bad sigreturn frame", regs,
+ (unsigned long)frame, SIGSEGV);
return -EFAULT;
}
@@ -221,9 +222,7 @@ give_sigsegv:
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka,
- struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int ret;
@@ -238,7 +237,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->regs[0] = -EINTR;
break;
}
@@ -254,14 +253,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
/* Set up the stack frame */
#ifdef CONFIG_COMPAT
if (is_compat_task())
- ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
+ ret = compat_setup_rt_frame(ksig, oldset, regs);
else
#endif
- ret = setup_rt_frame(sig, ka, info, oldset, regs);
- if (ret)
- return;
- signal_delivered(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ ret = setup_rt_frame(ksig, oldset, regs);
+
+ signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
}
/*
@@ -271,9 +268,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
*/
void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
/*
* i386 will check if we're coming from kernel mode and bail out
@@ -282,10 +277,9 @@ void do_signal(struct pt_regs *regs)
* helpful, we can reinstate the check on "!user_mode(regs)".
*/
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
+ if (get_signal(&ksig)) {
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &info, &ka, regs);
+ handle_signal(&ksig, regs);
goto done;
}
diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h
index f2ca5702a4e2..a5cde5c433b4 100644
--- a/arch/um/include/shared/frame_kern.h
+++ b/arch/um/include/shared/frame_kern.h
@@ -6,14 +6,10 @@
#ifndef __FRAME_KERN_H_
#define __FRAME_KERN_H_
-extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
- struct k_sigaction *ka,
- struct pt_regs *regs,
- sigset_t *mask);
-extern int setup_signal_stack_si(unsigned long stack_top, int sig,
- struct k_sigaction *ka,
- struct pt_regs *regs, struct siginfo *info,
- sigset_t *mask);
+extern int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *mask);
+extern int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *mask);
#endif
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index f57e02e7910f..4f60e4aad790 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -18,8 +18,7 @@ EXPORT_SYMBOL(unblock_signals);
/*
* OK, we're invoking a handler
*/
-static void handle_signal(struct pt_regs *regs, unsigned long signr,
- struct k_sigaction *ka, struct siginfo *info)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
sigset_t *oldset = sigmask_to_save();
int singlestep = 0;
@@ -39,7 +38,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
PT_REGS_SYSCALL_RET(regs) = -EINTR;
break;
}
@@ -52,32 +51,28 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
}
sp = PT_REGS_SP(regs);
- if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
+ if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
- if (!(ka->sa.sa_flags & SA_SIGINFO))
- err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
+ if (!(ksig->ka.sa.sa_flags & SA_SIGINFO))
+ err = setup_signal_stack_sc(sp, ksig, regs, oldset);
else
#endif
- err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
+ err = setup_signal_stack_si(sp, ksig, regs, oldset);
- if (err)
- force_sigsegv(signr, current);
- else
- signal_delivered(signr, info, ka, regs, singlestep);
+ signal_setup_done(err, ksig, singlestep);
}
static int kern_do_signal(struct pt_regs *regs)
{
- struct k_sigaction ka_copy;
- struct siginfo info;
- int sig, handled_sig = 0;
+ struct ksignal ksig;
+ int handled_sig = 0;
- while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
+ while (get_signal(&ksig)) {
handled_sig = 1;
/* Whee! Actually deliver the signal. */
- handle_signal(regs, sig, &ka_copy, &info);
+ handle_signal(&ksig, regs);
}
/* Did we come from a system call? */
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index 6905f0ebdc77..780d77388dec 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -238,10 +238,10 @@ static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
return 0;
}
-static int setup_frame(int usig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
- struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+ struct sigframe __user *frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
int err = 0;
if (!frame)
@@ -254,29 +254,29 @@ static int setup_frame(int usig, struct k_sigaction *ka,
err |= setup_sigframe(frame, regs, set);
if (err == 0)
- err |= setup_return(regs, ka, frame->retcode, frame, usig);
+ err |= setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
return err;
}
-static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe __user *frame =
- get_sigframe(ka, regs, sizeof(*frame));
+ get_sigframe(&ksig->ka, regs, sizeof(*frame));
int err = 0;
if (!frame)
return 1;
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= __put_user(0, &frame->sig.uc.uc_flags);
err |= __put_user(NULL, &frame->sig.uc.uc_link);
err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp);
err |= setup_sigframe(&frame->sig, regs, set);
if (err == 0)
- err |= setup_return(regs, ka, frame->sig.retcode, frame, usig);
+ err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
if (err == 0) {
/*
@@ -299,13 +299,13 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, struct pt_regs *regs, int syscall)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
+ int syscall)
{
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
sigset_t *oldset = sigmask_to_save();
- int usig = sig;
+ int usig = ksig->sig;
int ret;
/*
@@ -318,7 +318,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
regs->UCreg_00 = -EINTR;
break;
case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART)) {
+ if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
regs->UCreg_00 = -EINTR;
break;
}
@@ -338,22 +338,17 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
/*
* Set up the stack frame
*/
- if (ka->sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(usig, ka, info, oldset, regs);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(ksig, oldset, regs);
else
- ret = setup_frame(usig, ka, oldset, regs);
+ ret = setup_frame(ksig, oldset, regs);
/*
* Check that the resulting registers are actually sane.
*/
ret |= !valid_user_regs(regs);
- if (ret != 0) {
- force_sigsegv(sig, tsk);
- return;
- }
-
- signal_delivered(sig, info, ka, regs, 0);
+ signal_setup_done(ret, ksig, 0);
}
/*
@@ -367,9 +362,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
static void do_signal(struct pt_regs *regs, int syscall)
{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
+ struct ksignal ksig;
/*
* We want the common case to go fast, which
@@ -380,9 +373,8 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (!user_mode(regs))
return;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- handle_signal(signr, &ka, &info, regs, syscall);
+ if (get_signsl(&ksig)) {
+ handle_signal(&ksig, regs, syscall);
return;
}
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index 5e04a1c899fa..79d824551c1a 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -370,13 +370,12 @@ struct rt_sigframe
char retcode[8];
};
-int setup_signal_stack_sc(unsigned long stack_top, int sig,
- struct k_sigaction *ka, struct pt_regs *regs,
- sigset_t *mask)
+int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *mask)
{
struct sigframe __user *frame;
void __user *restorer;
- int err = 0;
+ int err = 0, sig = ksig->sig;
/* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
stack_top = ((stack_top + 4) & -16UL) - 4;
@@ -385,8 +384,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig);
@@ -410,20 +409,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return err;
PT_REGS_SP(regs) = (unsigned long) frame;
- PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+ PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
PT_REGS_AX(regs) = (unsigned long) sig;
PT_REGS_DX(regs) = (unsigned long) 0;
PT_REGS_CX(regs) = (unsigned long) 0;
return 0;
}
-int setup_signal_stack_si(unsigned long stack_top, int sig,
- struct k_sigaction *ka, struct pt_regs *regs,
- siginfo_t *info, sigset_t *mask)
+int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *mask)
{
struct rt_sigframe __user *frame;
void __user *restorer;
- int err = 0;
+ int err = 0, sig = ksig->sig;
stack_top &= -8UL;
frame = (struct rt_sigframe __user *) stack_top - 1;
@@ -431,14 +429,14 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
- if (ka->sa.sa_flags & SA_RESTORER)
- restorer = ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ restorer = ksig->ka.sa.sa_restorer;
err |= __put_user(restorer, &frame->pretcode);
err |= __put_user(sig, &frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
PT_REGS_SP(regs));
@@ -457,7 +455,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return err;
PT_REGS_SP(regs) = (unsigned long) frame;
- PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+ PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
PT_REGS_AX(regs) = (unsigned long) sig;
PT_REGS_DX(regs) = (unsigned long) &frame->info;
PT_REGS_CX(regs) = (unsigned long) &frame->uc;
@@ -502,12 +500,11 @@ struct rt_sigframe
struct _fpstate fpstate;
};
-int setup_signal_stack_si(unsigned long stack_top, int sig,
- struct k_sigaction *ka, struct pt_regs * regs,
- siginfo_t *info, sigset_t *set)
+int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+ struct pt_regs *regs, sigset_t *set)
{
struct rt_sigframe __user *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16);
@@ -517,8 +514,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto out;
- if (ka->sa.sa_flags & SA_SIGINFO) {
- err |= copy_siginfo_to_user(&frame->info, info);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
goto out;
}
@@ -543,8 +540,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
* already in userspace.
*/
/* x86-64 should always use SA_RESTORER. */
- if (ka->sa.sa_flags & SA_RESTORER)
- err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
else
/* could use a vstub here */
return err;
@@ -570,7 +567,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
*/
PT_REGS_SI(regs) = (unsigned long) &frame->info;
PT_REGS_DX(regs) = (unsigned long) &frame->uc;
- PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+ PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
out:
return err;
}
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index 98b67d5f1514..4612321c73cc 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -331,17 +331,17 @@ gen_return_code(unsigned char *codemem)
}
-static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
{
struct rt_sigframe *frame;
- int err = 0;
+ int err = 0, sig = ksig->sig;
int signal;
unsigned long sp, ra, tp;
sp = regs->areg[1];
- if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
+ if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
sp = current->sas_ss_sp + current->sas_ss_size;
}
@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
panic ("Double exception sys_sigreturn\n");
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
- goto give_sigsegv;
+ return -EFAULT;
}
signal = current_thread_info()->exec_domain
@@ -360,8 +360,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
- if (ka->sa.sa_flags & SA_SIGINFO) {
- err |= copy_siginfo_to_user(&frame->info, info);
+ if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+ err |= copy_siginfo_to_user(&frame->info, &ksig->info);
}
/* Create the user context. */
@@ -372,8 +372,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= setup_sigcontext(frame, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
- if (ka->sa.sa_flags & SA_RESTORER) {
- ra = (unsigned long)ka->sa.sa_restorer;
+ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+ ra = (unsigned long)ksig->ka.sa.sa_restorer;
} else {
/* Create sys_rt_sigreturn syscall in stack frame */
@@ -381,7 +381,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= gen_return_code(frame->retcode);
if (err) {
- goto give_sigsegv;
+ return -EFAULT;
}
ra = (unsigned long) frame->retcode;
}
@@ -393,7 +393,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Set up registers for signal handler; preserve the threadptr */
tp = regs->threadptr;
- start_thread(regs, (unsigned long) ka->sa.sa_handler,
+ start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
(unsigned long) frame);
/* Set up a stack frame for a call4
@@ -416,10 +416,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
#endif
return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return -EFAULT;
}
/*
@@ -433,15 +429,11 @@ give_sigsegv:
*/
static void do_signal(struct pt_regs *regs)
{
- siginfo_t info;
- int signr;
- struct k_sigaction ka;
+ struct ksignal ksig;
task_pt_regs(current)->icountlevel = 0;
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
- if (signr > 0) {
+ if (get_signal(&ksig)) {
int ret;
/* Are we from a system call? */
@@ -457,7 +449,7 @@ static void do_signal(struct pt_regs *regs)
break;
case -ERESTARTSYS:
- if (!(ka.sa.sa_flags & SA_RESTART)) {
+ if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
regs->areg[2] = -EINTR;
break;
}
@@ -476,11 +468,8 @@ static void do_signal(struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
/* Set up the stack frame */
- ret = setup_frame(signr, &ka, &info, sigmask_to_save(), regs);
- if (ret)
- return;
-
- signal_delivered(signr, &info, &ka, regs, 0);
+ ret = setup_frame(&ksig, sigmask_to_save(), regs);
+ signal_setup_done(ret, &ksig, 0);
if (current->ptrace & PT_SINGLESTEP)
task_pt_regs(current)->icountlevel = 1;