Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356761
b: refs/heads/master
c: 50b3c9e
h: refs/heads/master
i:
  356759: 497d183
v: v3
  • Loading branch information
Al Viro committed Feb 3, 2013
1 parent f32a37c commit 92eec26
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 27 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: a402922bff5f28469ec6bbc5066bda3556299f52
refs/heads/master: 50b3c9e30a53172b627081e7129c03ef53f27319
5 changes: 0 additions & 5 deletions trunk/arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ config TILE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
select GENERIC_SIGALTSTACK
select GENERIC_COMPAT_RT_SIGACTION
select GENERIC_COMPAT_RT_SIGQUEUEINFO
select GENERIC_COMPAT_RT_SIGPROCMASK
select GENERIC_COMPAT_RT_SIGPENDING

# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/tile/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,17 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
struct pt_regs *regs);

/* Compat syscalls. */
struct compat_sigaction;
struct compat_siginfo;
struct compat_sigaltstack;
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
struct compat_sigaction __user *oact,
size_t sigsetsize);
long compat_sys_rt_sigqueueinfo(int pid, int sig,
struct compat_siginfo __user *uinfo);
long compat_sys_rt_sigreturn(void);
long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr);
long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high);
long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high);
long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/tile/include/asm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ long sys_ftruncate64(unsigned int fd, loff_t length);

/* Provide versions of standard syscalls that use current_pt_regs(). */
long sys_rt_sigreturn(void);
long sys_sigaltstack(const stack_t __user *, stack_t __user *);
#define sys_rt_sigreturn sys_rt_sigreturn
#define sys_sigaltstack sys_sigaltstack

/* These are the intvec*.S trampolines. */
long _sys_rt_sigreturn(void);
Expand Down
112 changes: 110 additions & 2 deletions trunk/arch/tile/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@
#include <asm/syscalls.h>
#include <arch/interrupts.h>

struct compat_sigaction {
compat_uptr_t sa_handler;
compat_ulong_t sa_flags;
compat_uptr_t sa_restorer;
sigset_t sa_mask __packed;
};

struct compat_sigaltstack {
compat_uptr_t ss_sp;
int ss_flags;
compat_size_t ss_size;
};

struct compat_ucontext {
compat_ulong_t uc_flags;
compat_uptr_t uc_link;
Expand All @@ -48,6 +61,63 @@ struct compat_rt_sigframe {
struct compat_ucontext uc;
};

long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
struct compat_sigaction __user *oact,
size_t sigsetsize)
{
struct k_sigaction new_sa, old_sa;
int ret = -EINVAL;

/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
goto out;

if (act) {
compat_uptr_t handler, restorer;

if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(handler, &act->sa_handler) ||
__get_user(new_sa.sa.sa_flags, &act->sa_flags) ||
__get_user(restorer, &act->sa_restorer) ||
__copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask,
sizeof(sigset_t)))
return -EFAULT;
new_sa.sa.sa_handler = compat_ptr(handler);
new_sa.sa.sa_restorer = compat_ptr(restorer);
}

ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);

if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(ptr_to_compat(old_sa.sa.sa_handler),
&oact->sa_handler) ||
__put_user(ptr_to_compat(old_sa.sa.sa_restorer),
&oact->sa_restorer) ||
__put_user(old_sa.sa.sa_flags, &oact->sa_flags) ||
__copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask,
sizeof(sigset_t)))
return -EFAULT;
}
out:
return ret;
}

long compat_sys_rt_sigqueueinfo(int pid, int sig,
struct compat_siginfo __user *uinfo)
{
siginfo_t info;
int ret;
mm_segment_t old_fs = get_fs();

if (copy_siginfo_from_user32(&info, uinfo))
return -EFAULT;
set_fs(KERNEL_DS);
ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
set_fs(old_fs);
return ret;
}

int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from)
{
int err;
Expand Down Expand Up @@ -126,6 +196,40 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
return err;
}

long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr)
{
stack_t uss, uoss;
int ret;
mm_segment_t seg;

if (uss_ptr) {
u32 ptr;

memset(&uss, 0, sizeof(stack_t));
if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) ||
__get_user(ptr, &uss_ptr->ss_sp) ||
__get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
__get_user(uss.ss_size, &uss_ptr->ss_size))
return -EFAULT;
uss.ss_sp = compat_ptr(ptr);
}
seg = get_fs();
set_fs(KERNEL_DS);
ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
(stack_t __user __force *)&uoss,
(unsigned long)compat_ptr(current_pt_regs()->sp));
set_fs(seg);
if (ret >= 0 && uoss_ptr) {
if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
__put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
__put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
__put_user(uoss.ss_size, &uoss_ptr->ss_size))
ret = -EFAULT;
}
return ret;
}

/* The assembly shim for this function arranges to ignore the return value. */
long compat_sys_rt_sigreturn(void)
{
Expand All @@ -144,7 +248,7 @@ long compat_sys_rt_sigreturn(void)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;

if (compat_restore_altstack(&frame->uc.uc_stack))
if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL) == -EFAULT)
goto badframe;

return 0;
Expand Down Expand Up @@ -221,7 +325,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)),
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->sp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
Expand Down
15 changes: 13 additions & 2 deletions trunk/arch/tile/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@

#define DEBUG_SIG 0

SYSCALL_DEFINE2(sigaltstack, const stack_t __user *, uss,
stack_t __user *, uoss)
{
return do_sigaltstack(uss, uoss, current_pt_regs()->sp);
}


/*
* Do a signal return; undo the signal stack.
*/
Expand Down Expand Up @@ -93,7 +100,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;

if (restore_altstack(&frame->uc.uc_stack))
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
goto badframe;

return 0;
Expand Down Expand Up @@ -184,7 +191,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(NULL, &frame->uc.uc_link);
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
err |= __put_user((void __user *)(current->sas_ss_sp),
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->sp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/unicore32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ config UNICORE32
select ARCH_WANT_FRAME_POINTERS
select GENERIC_IOMAP
select MODULES_USE_ELF_REL
select GENERIC_SIGALTSTACK
help
UniCore-32 is 32-bit Instruction Set Architecture,
including a series of low-power-consumption RISC chip
Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/unicore32/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -674,11 +674,6 @@ ENTRY(sys_rt_sigreturn)
b __sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn)

ENTRY(sys_sigaltstack)
ldw r2, [sp+], #S_OFF + S_SP
b do_sigaltstack
ENDPROC(sys_sigaltstack)

__INIT

/*
Expand Down
12 changes: 2 additions & 10 deletions trunk/arch/unicore32/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ asmlinkage int __sys_rt_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, &frame->sig))
goto badframe;

if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->UCreg_sp)
== -EFAULT)
if (restore_altstack(&frame->sig.uc.uc_stack))
goto badframe;

return regs->UCreg_00;
Expand Down Expand Up @@ -265,7 +264,6 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
{
struct rt_sigframe __user *frame =
get_sigframe(ka, regs, sizeof(*frame));
stack_t stack;
int err = 0;

if (!frame)
Expand All @@ -275,13 +273,7 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,

err |= __put_user(0, &frame->sig.uc.uc_flags);
err |= __put_user(NULL, &frame->sig.uc.uc_link);

memset(&stack, 0, sizeof(stack));
stack.ss_sp = (void __user *)current->sas_ss_sp;
stack.ss_flags = sas_ss_flags(regs->UCreg_sp);
stack.ss_size = current->sas_ss_size;
err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack));

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);
Expand Down
4 changes: 2 additions & 2 deletions trunk/include/uapi/asm-generic/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,9 @@ __SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
#define __NR_rt_sigaction 134
__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
#define __NR_rt_sigprocmask 135
__SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask)
__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
#define __NR_rt_sigpending 136
__SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending)
__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
#define __NR_rt_sigtimedwait 137
__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
compat_sys_rt_sigtimedwait)
Expand Down

0 comments on commit 92eec26

Please sign in to comment.