aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/signal32.c')
-rw-r--r--arch/mips/kernel/signal32.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 183fc7e55f34..c28cb21514c8 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -8,6 +8,7 @@
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */ 9 */
10#include <linux/cache.h> 10#include <linux/cache.h>
11#include <linux/compat.h>
11#include <linux/sched.h> 12#include <linux/sched.h>
12#include <linux/mm.h> 13#include <linux/mm.h>
13#include <linux/smp.h> 14#include <linux/smp.h>
@@ -24,6 +25,7 @@
24 25
25#include <asm/abi.h> 26#include <asm/abi.h>
26#include <asm/asm.h> 27#include <asm/asm.h>
28#include <asm/compat-signal.h>
27#include <linux/bitops.h> 29#include <linux/bitops.h>
28#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
29#include <asm/sim.h> 31#include <asm/sim.h>
@@ -104,8 +106,6 @@ typedef struct compat_siginfo {
104#define __NR_O32_rt_sigreturn 4193 106#define __NR_O32_rt_sigreturn 4193
105#define __NR_O32_restart_syscall 4253 107#define __NR_O32_restart_syscall 4253
106 108
107#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
108
109/* 32-bit compatibility types */ 109/* 32-bit compatibility types */
110 110
111#define _NSIG_BPW32 32 111#define _NSIG_BPW32 32
@@ -139,8 +139,20 @@ struct ucontext32 {
139 sigset_t32 uc_sigmask; /* mask last for extensibility */ 139 sigset_t32 uc_sigmask; /* mask last for extensibility */
140}; 140};
141 141
142/*
143 * Horribly complicated - with the bloody RM9000 workarounds enabled
144 * the signal trampolines is moving to the end of the structure so we can
145 * increase the alignment without breaking software compatibility.
146 */
142#if ICACHE_REFILLS_WORKAROUND_WAR == 0 147#if ICACHE_REFILLS_WORKAROUND_WAR == 0
143 148
149struct sigframe32 {
150 u32 sf_ass[4]; /* argument save space for o32 */
151 u32 sf_code[2]; /* signal trampoline */
152 struct sigcontext32 sf_sc;
153 sigset_t sf_mask;
154};
155
144struct rt_sigframe32 { 156struct rt_sigframe32 {
145 u32 rs_ass[4]; /* argument save space for o32 */ 157 u32 rs_ass[4]; /* argument save space for o32 */
146 u32 rs_code[2]; /* signal trampoline */ 158 u32 rs_code[2]; /* signal trampoline */
@@ -150,6 +162,14 @@ struct rt_sigframe32 {
150 162
151#else /* ICACHE_REFILLS_WORKAROUND_WAR */ 163#else /* ICACHE_REFILLS_WORKAROUND_WAR */
152 164
165struct sigframe32 {
166 u32 sf_ass[4]; /* argument save space for o32 */
167 u32 sf_pad[2];
168 struct sigcontext32 sf_sc; /* hw context */
169 sigset_t sf_mask;
170 u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
171};
172
153struct rt_sigframe32 { 173struct rt_sigframe32 {
154 u32 rs_ass[4]; /* argument save space for o32 */ 174 u32 rs_ass[4]; /* argument save space for o32 */
155 u32 rs_pad[2]; 175 u32 rs_pad[2];
@@ -493,13 +513,13 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
493 513
494asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) 514asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
495{ 515{
496 struct sigframe __user *frame; 516 struct sigframe32 __user *frame;
497 sigset_t blocked; 517 sigset_t blocked;
498 518
499 frame = (struct sigframe __user *) regs.regs[29]; 519 frame = (struct sigframe32 __user *) regs.regs[29];
500 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 520 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
501 goto badframe; 521 goto badframe;
502 if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) 522 if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
503 goto badframe; 523 goto badframe;
504 524
505 sigdelsetmask(&blocked, ~_BLOCKABLE); 525 sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -536,7 +556,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
536 frame = (struct rt_sigframe32 __user *) regs.regs[29]; 556 frame = (struct rt_sigframe32 __user *) regs.regs[29];
537 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 557 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
538 goto badframe; 558 goto badframe;
539 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) 559 if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
540 goto badframe; 560 goto badframe;
541 561
542 sigdelsetmask(&set, ~_BLOCKABLE); 562 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -581,7 +601,7 @@ badframe:
581int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 601int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
582 int signr, sigset_t *set) 602 int signr, sigset_t *set)
583{ 603{
584 struct sigframe __user *frame; 604 struct sigframe32 __user *frame;
585 int err = 0; 605 int err = 0;
586 606
587 frame = get_sigframe(ka, regs, sizeof(*frame)); 607 frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -591,7 +611,8 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
591 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn); 611 err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
592 612
593 err |= setup_sigcontext32(regs, &frame->sf_sc); 613 err |= setup_sigcontext32(regs, &frame->sf_sc);
594 err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); 614 err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
615
595 if (err) 616 if (err)
596 goto give_sigsegv; 617 goto give_sigsegv;
597 618
@@ -650,7 +671,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
650 err |= __put_user(current->sas_ss_size, 671 err |= __put_user(current->sas_ss_size,
651 &frame->rs_uc.uc_stack.ss_size); 672 &frame->rs_uc.uc_stack.ss_size);
652 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); 673 err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
653 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); 674 err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
654 675
655 if (err) 676 if (err)
656 goto give_sigsegv; 677 goto give_sigsegv;