Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356757
b: refs/heads/master
c: 47669ab
h: refs/heads/master
i:
  356755: d27a865
v: v3
  • Loading branch information
Al Viro committed Feb 3, 2013
1 parent eaa3994 commit a1bb808
Show file tree
Hide file tree
Showing 20 changed files with 457 additions and 140 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: 52ad6b3f90c63653ba24c4f63f218a925b8e14d7
refs/heads/master: 47669ab0361558a734e42f78196636d70201e44f
8 changes: 0 additions & 8 deletions trunk/arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,12 @@ config SPARC
select GENERIC_STRNLEN_USER
select MODULES_USE_ELF_RELA
select ODD_RT_SIGACTION
select GENERIC_SIGALTSTACK
select GENERIC_COMPAT_RT_SIGQUEUEINFO
select GENERIC_COMPAT_RT_SIGPROCMASK
select GENERIC_COMPAT_RT_SIGPENDING
select GENERIC_COMPAT_RT_SIGACTION
select OLD_SIGSUSPEND

config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
select CLZ_TAB
select HAVE_UID16
select OLD_SIGACTION

config SPARC64
def_bool 64BIT
Expand Down Expand Up @@ -551,7 +544,6 @@ config COMPAT
select COMPAT_BINFMT_ELF
select HAVE_UID16
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION

config SYSVIPC_COMPAT
bool
Expand Down
6 changes: 6 additions & 0 deletions trunk/arch/sparc/include/asm/compat_signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ struct __old_sigaction32 {
unsigned int sa_flags;
unsigned sa_restorer; /* not used by Linux/SPARC yet */
};

typedef struct sigaltstack32 {
u32 ss_sp;
int ss_flags;
compat_size_t ss_size;
} stack_t32;
#endif

#endif /* !(_COMPAT_SIGNAL_H) */
2 changes: 1 addition & 1 deletion trunk/arch/sparc/include/uapi/asm/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,14 @@ struct __new_sigaction {
__sigrestore_t sa_restorer; /* not used by Linux/SPARC yet */
__new_sigset_t sa_mask;
};
#endif

struct __old_sigaction {
__sighandler_t sa_handler;
__old_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void); /* not used by Linux/SPARC yet */
};
#endif

typedef struct sigaltstack {
void __user *ss_sp;
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/sparc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,14 @@ sys_sparc_pipe:
call sparc_pipe
mov %l5, %o7

.align 4
.globl sys_sigaltstack
sys_sigaltstack:
mov %o7, %l5
mov %fp, %o2
call do_sigaltstack
mov %l5, %o7

.align 4
.globl sys_sigstack
sys_sigstack:
Expand Down
48 changes: 44 additions & 4 deletions trunk/arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct rt_signal_frame32 {
compat_sigset_t mask;
/* __siginfo_fpu_t * */ u32 fpu_save;
unsigned int insns[2];
compat_stack_t stack;
stack_t32 stack;
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus;
Expand Down Expand Up @@ -230,11 +230,13 @@ void do_sigreturn32(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{
struct rt_signal_frame32 __user *sf;
unsigned int psr, pc, npc;
unsigned int psr, pc, npc, u_ss_sp;
compat_uptr_t fpu_save;
compat_uptr_t rwin_save;
mm_segment_t old_fs;
sigset_t set;
compat_sigset_t seta;
stack_t st;
int err, i;

/* Always make any pending restarted system calls return -EINTR */
Expand Down Expand Up @@ -293,10 +295,20 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
if (!err && fpu_save)
err |= restore_fpu_state(regs, compat_ptr(fpu_save));
err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
err |= compat_restore_altstack(&sf->stack);
err |= __get_user(u_ss_sp, &sf->stack.ss_sp);
st.ss_sp = compat_ptr(u_ss_sp);
err |= __get_user(st.ss_flags, &sf->stack.ss_flags);
err |= __get_user(st.ss_size, &sf->stack.ss_size);
if (err)
goto segv;

/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs);

err |= __get_user(rwin_save, &sf->rwin_save);
if (!err && rwin_save) {
if (restore_rwin_state(compat_ptr(rwin_save)))
Expand Down Expand Up @@ -630,7 +642,9 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err |= copy_siginfo_to_user32(&sf->info, info);

/* Setup sigaltstack */
err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);

switch (_NSIG_WORDS) {
case 4: seta.sig[7] = (oldset->sig[3] >> 32);
Expand Down Expand Up @@ -842,3 +856,29 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
out:
return ret;
}

asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
{
stack_t uss, uoss;
u32 u_ss_sp = 0;
int ret;
mm_segment_t old_fs;
stack_t32 __user *uss32 = compat_ptr(ussa);
stack_t32 __user *uoss32 = compat_ptr(uossa);

if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) ||
__get_user(uss.ss_flags, &uss32->ss_flags) ||
__get_user(uss.ss_size, &uss32->ss_size)))
return -EFAULT;
uss.ss_sp = compat_ptr(u_ss_sp);
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL,
uossa ? (stack_t __user *) &uoss : NULL, sp);
set_fs(old_fs);
if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) ||
__put_user(uoss.ss_flags, &uoss32->ss_flags) ||
__put_user(uoss.ss_size, &uoss32->ss_size)))
return -EFAULT;
return ret;
}
29 changes: 27 additions & 2 deletions trunk/arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ struct rt_signal_frame {
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))

static int _sigpause_common(old_sigset_t set)
{
sigset_t blocked;
siginitset(&blocked, set);
return sigsuspend(&blocked);
}

asmlinkage int sys_sigsuspend(old_sigset_t set)
{
return _sigpause_common(set);
}

asmlinkage void do_sigreturn(struct pt_regs *regs)
{
struct signal_frame __user *sf;
Expand Down Expand Up @@ -129,7 +141,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
unsigned int psr, pc, npc;
__siginfo_fpu_t __user *fpu_save;
__siginfo_rwin_t __user *rwin_save;
mm_segment_t old_fs;
sigset_t set;
stack_t st;
int err;

synchronize_user_stack();
Expand Down Expand Up @@ -157,14 +171,23 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
if (!err && fpu_save)
err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
err |= restore_altstack(&sf->stack);

err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));

if (err)
goto segv;

regs->pc = pc;
regs->npc = npc;

/* It is more difficult to avoid calling this function than to
* call it and ignore errors.
*/
old_fs = get_fs();
set_fs(KERNEL_DS);
do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf);
set_fs(old_fs);

err |= __get_user(rwin_save, &sf->rwin_save);
if (!err && rwin_save) {
if (restore_rwin_state(rwin_save))
Expand Down Expand Up @@ -368,7 +391,9 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));

/* Setup sigaltstack */
err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);

if (!wsaved) {
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
Expand Down
24 changes: 21 additions & 3 deletions trunk/arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,23 @@ struct rt_signal_frame {
__siginfo_rwin_t *rwin_save;
};

static long _sigpause_common(old_sigset_t set)
{
sigset_t blocked;
siginitset(&blocked, set);
return sigsuspend(&blocked);
}

asmlinkage long sys_sigpause(unsigned int set)
{
return _sigpause_common(set);
}

asmlinkage long sys_sigsuspend(old_sigset_t set)
{
return _sigpause_common(set);
}

void do_rt_sigreturn(struct pt_regs *regs)
{
struct rt_signal_frame __user *sf;
Expand Down Expand Up @@ -278,8 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
err |= restore_fpu_state(regs, fpu_save);

err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
err |= restore_altstack(&sf->stack);
if (err)
if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
goto segv;

err |= __get_user(rwin_save, &sf->rwin_save);
Expand Down Expand Up @@ -387,7 +403,9 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
}

/* Setup sigaltstack */
err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);

err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));

Expand Down
86 changes: 86 additions & 0 deletions trunk/arch/sparc/kernel/sys32.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,108 @@ STUB: sra REG1, 0, REG1; \
jmpl %g1 + %lo(SYSCALL), %g0; \
sra REG3, 0, REG3

#define SIGN4(STUB,SYSCALL,REG1,REG2,REG3,REG4) \
.align 32; \
.globl STUB; \
STUB: sra REG1, 0, REG1; \
sethi %hi(SYSCALL), %g1; \
sra REG2, 0, REG2; \
sra REG3, 0, REG3; \
jmpl %g1 + %lo(SYSCALL), %g0; \
sra REG4, 0, REG4

SIGN1(sys32_exit, sparc_exit, %o0)
SIGN1(sys32_exit_group, sparc_exit_group, %o0)
SIGN1(sys32_wait4, compat_sys_wait4, %o2)
SIGN1(sys32_creat, sys_creat, %o1)
SIGN1(sys32_mknod, sys_mknod, %o1)
SIGN1(sys32_umount, sys_umount, %o1)
SIGN1(sys32_signal, sys_signal, %o0)
SIGN1(sys32_access, sys_access, %o1)
SIGN1(sys32_msync, sys_msync, %o2)
SIGN2(sys32_reboot, sys_reboot, %o0, %o1)
SIGN1(sys32_setitimer, compat_sys_setitimer, %o0)
SIGN1(sys32_getitimer, compat_sys_getitimer, %o0)
SIGN1(sys32_sethostname, sys_sethostname, %o1)
SIGN1(sys32_swapon, sys_swapon, %o1)
SIGN1(sys32_sigaction, compat_sys_sigaction, %o0)
SIGN1(sys32_rt_sigaction, compat_sys_rt_sigaction, %o0)
SIGN1(sys32_sigprocmask, compat_sys_sigprocmask, %o0)
SIGN1(sys32_rt_sigprocmask, compat_sys_rt_sigprocmask, %o0)
SIGN2(sys32_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo, %o0, %o1)
SIGN1(sys32_getrusage, compat_sys_getrusage, %o0)
SIGN1(sys32_setxattr, sys_setxattr, %o4)
SIGN1(sys32_lsetxattr, sys_lsetxattr, %o4)
SIGN1(sys32_fsetxattr, sys_fsetxattr, %o4)
SIGN1(sys32_fgetxattr, sys_fgetxattr, %o0)
SIGN1(sys32_flistxattr, sys_flistxattr, %o0)
SIGN1(sys32_fremovexattr, sys_fremovexattr, %o0)
SIGN2(sys32_tkill, sys_tkill, %o0, %o1)
SIGN1(sys32_epoll_create, sys_epoll_create, %o0)
SIGN3(sys32_epoll_ctl, sys_epoll_ctl, %o0, %o1, %o2)
SIGN3(sys32_epoll_wait, sys_epoll_wait, %o0, %o2, %o3)
SIGN1(sys32_readahead, compat_sys_readahead, %o0)
SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4)
SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5)
SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1)
SIGN1(sys32_mlockall, sys_mlockall, %o0)
SIGN1(sys32_clock_nanosleep, compat_sys_clock_nanosleep, %o1)
SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1)
SIGN1(sys32_io_submit, compat_sys_io_submit, %o1)
SIGN1(sys32_mq_open, compat_sys_mq_open, %o1)
SIGN1(sys32_select, compat_sys_select, %o0)
SIGN1(sys32_mkdir, sys_mkdir, %o1)
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1)
SIGN1(sys32_prctl, sys_prctl, %o0)
SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0)
SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2)
SIGN1(sys32_getgroups, sys_getgroups, %o0)
SIGN1(sys32_getpgid, sys_getpgid, %o0)
SIGN2(sys32_getpriority, sys_getpriority, %o0, %o1)
SIGN1(sys32_getsid, sys_getsid, %o0)
SIGN2(sys32_kill, sys_kill, %o0, %o1)
SIGN1(sys32_nice, sys_nice, %o0)
SIGN1(sys32_lseek, sys_lseek, %o1)
SIGN2(sys32_open, sparc32_open, %o1, %o2)
SIGN1(sys32_readlink, sys_readlink, %o2)
SIGN1(sys32_sched_get_priority_max, sys_sched_get_priority_max, %o0)
SIGN1(sys32_sched_get_priority_min, sys_sched_get_priority_min, %o0)
SIGN1(sys32_sched_getparam, sys_sched_getparam, %o0)
SIGN1(sys32_sched_getscheduler, sys_sched_getscheduler, %o0)
SIGN1(sys32_sched_setparam, sys_sched_setparam, %o0)
SIGN2(sys32_sched_setscheduler, sys_sched_setscheduler, %o0, %o1)
SIGN1(sys32_getdomainname, sys_getdomainname, %o1)
SIGN1(sys32_setdomainname, sys_setdomainname, %o1)
SIGN1(sys32_setgroups, sys_setgroups, %o0)
SIGN2(sys32_setpgid, sys_setpgid, %o0, %o1)
SIGN3(sys32_setpriority, sys_setpriority, %o0, %o1, %o2)
SIGN1(sys32_ssetmask, sys_ssetmask, %o0)
SIGN2(sys32_syslog, sys_syslog, %o0, %o2)
SIGN1(sys32_umask, sys_umask, %o0)
SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2)
SIGN1(sys32_sendto, sys_sendto, %o0)
SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2)
SIGN2(sys32_connect, sys_connect, %o0, %o2)
SIGN2(sys32_bind, sys_bind, %o0, %o2)
SIGN2(sys32_listen, sys_listen, %o0, %o1)
SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0)
SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0)
SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1)
SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2)
SIGN1(sys32_getpeername, sys_getpeername, %o0)
SIGN1(sys32_getsockname, sys_getsockname, %o0)
SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
SIGN2(sys32_splice, sys_splice, %o0, %o2)
SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
SIGN2(sys32_tee, sys_tee, %o0, %o1)
SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
SIGN1(sys32_truncate, sys_truncate, %o1)
SIGN1(sys32_ftruncate, sys_ftruncate, %o1)

.globl sys32_mmap2
sys32_mmap2:
Expand Down
Loading

0 comments on commit a1bb808

Please sign in to comment.