Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 189777
b: refs/heads/master
c: d814c28
h: refs/heads/master
i:
  189775: 9566d2d
v: v3
  • Loading branch information
David Daney authored and Ralf Baechle committed Apr 12, 2010
1 parent eead1ef commit 6b1a281
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 136 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c52d0d30aef84aa8893b34e5254716c8ab5c4472
refs/heads/master: d814c28ceca8f659c0012eaec8e21eee43710716
6 changes: 4 additions & 2 deletions trunk/arch/mips/include/asm/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#include <asm/siginfo.h>

struct mips_abi {
int (* const setup_frame)(struct k_sigaction * ka,
int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr,
sigset_t *set);
int (* const setup_rt_frame)(struct k_sigaction * ka,
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);
const unsigned long rt_signal_return_offset;
const unsigned long restart;
};

Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/mips/kernel/signal-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@
*/
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size);
/*
* install trampoline code to get back from the sig handler
*/
extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);

/* Check and clear pending FPU exceptions in saved CSR */
extern int fpcsr_pending(unsigned int __user *fpcsr);

Expand Down
86 changes: 19 additions & 67 deletions trunk/arch/mips/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
#include <asm/vdso.h>

#include "signal-common.h"

Expand All @@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);

/*
* Horribly complicated - with the bloody RM9000 workarounds enabled
* the signal trampolines is moving to the end of the structure so we can
* increase the alignment without breaking software compatibility.
*/
#if ICACHE_REFILLS_WORKAROUND_WAR == 0

struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_code[2]; /* signal trampoline */
u32 sf_pad[2]; /* Was: signal trampoline */
struct sigcontext sf_sc;
sigset_t sf_mask;
};

struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
u32 rs_code[2]; /* signal trampoline */
u32 rs_pad[2]; /* Was: signal trampoline */
struct siginfo rs_info;
struct ucontext rs_uc;
};

#else

struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_pad[2];
struct sigcontext sf_sc; /* hw context */
sigset_t sf_mask;
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
};

struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
u32 rs_pad[2];
struct siginfo rs_info;
struct ucontext rs_uc;
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
};

#endif

/*
* Helper routines
*/
Expand Down Expand Up @@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
}

int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
{
int err;

/*
* Set up the return code ...
*
* li v0, __NR__foo_sigreturn
* syscall
*/

err = __put_user(0x24020000 + syscall, tramp + 0);
err |= __put_user(0x0000000c , tramp + 1);
if (ICACHE_REFILLS_WORKAROUND_WAR) {
err |= __put_user(0, tramp + 2);
err |= __put_user(0, tramp + 3);
err |= __put_user(0, tramp + 4);
err |= __put_user(0, tramp + 5);
err |= __put_user(0, tramp + 6);
err |= __put_user(0, tramp + 7);
}
flush_cache_sigtramp((unsigned long) tramp);

return err;
}

/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
Expand Down Expand Up @@ -484,8 +432,8 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
}

#ifdef CONFIG_TRAD_SIGNALS
static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
static int setup_frame(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set)
{
struct sigframe __user *frame;
int err = 0;
Expand All @@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;

err |= install_sigtramp(frame->sf_code, __NR_sigreturn);

err |= setup_sigcontext(regs, &frame->sf_sc);
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
if (err)
Expand All @@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) frame->sf_code;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;

DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
Expand All @@ -529,8 +475,9 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
}
#endif

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(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set,
siginfo_t *info)
{
struct rt_sigframe __user *frame;
int err = 0;
Expand All @@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;

err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);

/* Create siginfo. */
err |= copy_siginfo_to_user(&frame->rs_info, info);

Expand Down Expand Up @@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
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) frame->rs_code;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;

DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
Expand All @@ -590,15 +535,20 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
struct mips_abi mips_abi = {
#ifdef CONFIG_TRAD_SIGNALS
.setup_frame = setup_frame,
.signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
#endif
.setup_rt_frame = setup_rt_frame,
.rt_signal_return_offset =
offsetof(struct mips_vdso, rt_signal_trampoline),
.restart = __NR_restart_syscall
};

static int handle_signal(unsigned long sig, siginfo_t *info,
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
{
int ret;
struct mips_abi *abi = current->thread.abi;
void *vdso = current->mm->context.vdso;

switch(regs->regs[0]) {
case ERESTART_RESTARTBLOCK:
Expand All @@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
regs->regs[0] = 0; /* Don't deal with this again. */

if (sig_uses_siginfo(ka))
ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
ka, regs, sig, oldset, info);
else
ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
ret = abi->setup_frame(vdso + abi->signal_return_offset,
ka, regs, sig, oldset);

spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
Expand Down
55 changes: 14 additions & 41 deletions trunk/arch/mips/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/war.h>
#include <asm/vdso.h>

#include "signal-common.h"

Expand All @@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
/*
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
*/
#define __NR_O32_sigreturn 4119
#define __NR_O32_rt_sigreturn 4193
#define __NR_O32_restart_syscall 4253

/* 32-bit compatibility types */
Expand Down Expand Up @@ -77,47 +76,20 @@ struct ucontext32 {
compat_sigset_t uc_sigmask; /* mask last for extensibility */
};

/*
* Horribly complicated - with the bloody RM9000 workarounds enabled
* the signal trampolines is moving to the end of the structure so we can
* increase the alignment without breaking software compatibility.
*/
#if ICACHE_REFILLS_WORKAROUND_WAR == 0

struct sigframe32 {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_code[2]; /* signal trampoline */
u32 sf_pad[2]; /* Was: signal trampoline */
struct sigcontext32 sf_sc;
compat_sigset_t sf_mask;
};

struct rt_sigframe32 {
u32 rs_ass[4]; /* argument save space for o32 */
u32 rs_code[2]; /* signal trampoline */
u32 rs_pad[2]; /* Was: signal trampoline */
compat_siginfo_t rs_info;
struct ucontext32 rs_uc;
};

#else /* ICACHE_REFILLS_WORKAROUND_WAR */

struct sigframe32 {
u32 sf_ass[4]; /* argument save space for o32 */
u32 sf_pad[2];
struct sigcontext32 sf_sc; /* hw context */
compat_sigset_t sf_mask;
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
};

struct rt_sigframe32 {
u32 rs_ass[4]; /* argument save space for o32 */
u32 rs_pad[2];
compat_siginfo_t rs_info;
struct ucontext32 rs_uc;
u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
};

#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */

/*
* sigcontext handlers
*/
Expand Down Expand Up @@ -598,8 +570,8 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
force_sig(SIGSEGV, current);
}

static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
int signr, sigset_t *set)
static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set)
{
struct sigframe32 __user *frame;
int err = 0;
Expand All @@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;

err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);

err |= setup_sigcontext32(regs, &frame->sf_sc);
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);

Expand All @@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
regs->regs[ 5] = 0;
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
regs->regs[29] = (unsigned long) frame;
regs->regs[31] = (unsigned long) frame->sf_code;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;

DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
Expand All @@ -644,8 +614,9 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
return -EFAULT;
}

static int setup_rt_frame_32(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 k_sigaction *ka,
struct pt_regs *regs, int signr, sigset_t *set,
siginfo_t *info)
{
struct rt_sigframe32 __user *frame;
int err = 0;
Expand All @@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
goto give_sigsegv;

err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);

/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
err |= copy_siginfo_to_user32(&frame->rs_info, info);

Expand Down Expand Up @@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
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) frame->rs_code;
regs->regs[31] = (unsigned long) sig_return;
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;

DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
Expand All @@ -709,7 +678,11 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
*/
struct mips_abi mips_abi_32 = {
.setup_frame = setup_frame_32,
.signal_return_offset =
offsetof(struct mips_vdso, o32_signal_trampoline),
.setup_rt_frame = setup_rt_frame_32,
.rt_signal_return_offset =
offsetof(struct mips_vdso, o32_rt_signal_trampoline),
.restart = __NR_O32_restart_syscall
};

Expand Down
Loading

0 comments on commit 6b1a281

Please sign in to comment.