Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 356724
b: refs/heads/master
c: 7cce246
h: refs/heads/master
v: v3
  • Loading branch information
Al Viro committed Feb 3, 2013
1 parent 2e34468 commit 529911a
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 102 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: b0f95824f2e91fb0df59fd63ddd6b36a94c05699
refs/heads/master: 7cce246557bf379ea271d91f257ce248362cc12d
5 changes: 0 additions & 5 deletions trunk/arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ config PARISC
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS
select GENERIC_SIGALTSTACK
select GENERIC_COMPAT_RT_SIGACTION
select GENERIC_COMPAT_RT_SIGQUEUEINFO
select GENERIC_COMPAT_RT_SIGPROCMASK
select GENERIC_COMPAT_RT_SIGPENDING

help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
Expand Down
38 changes: 38 additions & 0 deletions trunk/arch/parisc/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,44 @@ ENTRY(sys_rt_sigreturn_wrapper)
LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */
ENDPROC(sys_rt_sigreturn_wrapper)

ENTRY(sys_sigaltstack_wrapper)
/* Get the user stack pointer */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r24 /* get pt regs */
LDREG TASK_PT_GR30(%r24),%r24
STREG %r2, -RP_OFFSET(%r30)
#ifdef CONFIG_64BIT
ldo FRAME_SIZE(%r30), %r30
BL do_sigaltstack,%r2
ldo -16(%r30),%r29 /* Reference param save area */
#else
BL do_sigaltstack,%r2
ldo FRAME_SIZE(%r30), %r30
#endif

ldo -FRAME_SIZE(%r30), %r30
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
nop
ENDPROC(sys_sigaltstack_wrapper)

#ifdef CONFIG_64BIT
ENTRY(sys32_sigaltstack_wrapper)
/* Get the user stack pointer */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
LDREG TASK_PT_GR30(%r24),%r24
STREG %r2, -RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30), %r30
BL do_sigaltstack32,%r2
ldo -16(%r30),%r29 /* Reference param save area */

ldo -FRAME_SIZE(%r30), %r30
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
nop
ENDPROC(sys32_sigaltstack_wrapper)
#endif

ENTRY(syscall_exit)
/* NOTE: HP-UX syscalls also come through here
* after hpux_syscall_exit fixes up return
Expand Down
19 changes: 15 additions & 4 deletions trunk/arch/parisc/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
goto give_sigsegv;
DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
usp, &compat_frame->uc.uc_stack);
if (compat_restore_altstack(&compat_frame->uc.uc_stack))
if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT)
goto give_sigsegv;
} else
#endif
Expand All @@ -154,7 +154,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
goto give_sigsegv;
DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n",
usp, &frame->uc.uc_stack);
if (restore_altstack(&frame->uc.uc_stack))
if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
goto give_sigsegv;
}

Expand Down Expand Up @@ -260,7 +260,15 @@ 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 |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
DBG(1,"SETUP_RT_FRAME: 1\n");
compat_val = (compat_int_t)current->sas_ss_sp;
err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
DBG(1,"SETUP_RT_FRAME: 2\n");
compat_val = (compat_int_t)current->sas_ss_size;
err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size);
DBG(1,"SETUP_RT_FRAME: 3\n");
compat_val = sas_ss_flags(regs->gr[30]);
err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags);
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);
err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext,
Expand All @@ -272,7 +280,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
{
DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
err |= copy_siginfo_to_user(&frame->info, info);
err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= __put_user(sas_ss_flags(regs->gr[30]),
&frame->uc.uc_stack.ss_flags);
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);
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
Expand Down
142 changes: 142 additions & 0 deletions trunk/arch/parisc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,129 @@ sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
}

static int
put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
{
compat_sigset_t s;

if (sz != sizeof *set)
return -EINVAL;
sigset_64to32(&s, set);

return copy_to_user(up, &s, sizeof s);
}

static int
get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
{
compat_sigset_t s;
int r;

if (sz != sizeof *set)
return -EINVAL;

if ((r = copy_from_user(&s, up, sz)) == 0) {
sigset_32to64(set, &s);
}

return r;
}

int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
unsigned int sigsetsize)
{
sigset_t old_set, new_set;
int ret;

if (set && get_sigset32(set, &new_set, sigsetsize))
return -EFAULT;

KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);

if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
return -EFAULT;

return ret;
}


int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
{
int ret;
sigset_t set;

KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);

if (!ret && put_sigset32(uset, &set, sigsetsize))
return -EFAULT;

return ret;
}

long
sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
size_t sigsetsize)
{
struct k_sigaction32 new_sa32, old_sa32;
struct k_sigaction new_sa, old_sa;
int ret = -EINVAL;

if (act) {
if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
return -EFAULT;
new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
}

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

if (!ret && oact) {
sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
return -EFAULT;
}
return ret;
}

int
do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
{
compat_stack_t ss32, oss32;
stack_t ss, oss;
stack_t *ssp = NULL, *ossp = NULL;
int ret;

if (uss32) {
if (copy_from_user(&ss32, uss32, sizeof ss32))
return -EFAULT;

ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
ss.ss_flags = ss32.ss_flags;
ss.ss_size = ss32.ss_size;

ssp = &ss;
}

if (uoss32)
ossp = &oss;

KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);

if (!ret && uoss32) {
oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
oss32.ss_flags = oss.ss_flags;
oss32.ss_size = oss.ss_size;
if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
return -EFAULT;
}

return ret;
}

long
restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
struct pt_regs *regs)
Expand Down Expand Up @@ -376,3 +499,22 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
}
return err;
}

asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
struct compat_siginfo __user *uinfo)
{
siginfo_t info;

if (copy_siginfo_from_user32(&info, uinfo))
return -EFAULT;

/* Not even root can pretend to send signals from the kernel.
Nor can they impersonate a kill(), which adds source info. */
if (info.si_code >= 0)
return -EPERM;
info.si_signo = sig;

/* POSIX.1b doesn't mention process groups. */
return kill_proc_info(sig, &info, pid);
}

23 changes: 23 additions & 0 deletions trunk/arch/parisc/kernel/signal32.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@

#include <linux/compat.h>

typedef compat_uptr_t compat_sighandler_t;

typedef struct compat_sigaltstack {
compat_uptr_t ss_sp;
compat_int_t ss_flags;
compat_size_t ss_size;
} compat_stack_t;

/* Most things should be clean enough to redefine this at will, if care
is taken to make libc match. */

struct compat_sigaction {
compat_sighandler_t sa_handler;
compat_uint_t sa_flags;
compat_sigset_t sa_mask; /* mask last for extensibility */
};

/* 32-bit ucontext as seen from an 64-bit kernel */
struct compat_ucontext {
compat_uint_t uc_flags;
Expand All @@ -34,6 +51,10 @@ struct compat_ucontext {

/* ELF32 signal handling */

struct k_sigaction32 {
struct compat_sigaction sa;
};

int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from);
int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from);

Expand Down Expand Up @@ -81,6 +102,8 @@ struct compat_rt_sigframe {

void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
int do_sigaltstack32 (const compat_stack_t __user *uss32,
compat_stack_t __user *uoss32, unsigned long sp);
long restore_sigcontext32(struct compat_sigcontext __user *sc,
struct compat_regfile __user *rf,
struct pt_regs *regs);
Expand Down
12 changes: 12 additions & 0 deletions trunk/arch/parisc/kernel/sys32.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,16 @@
set_fs (old_fs); \
}

#ifdef CONFIG_COMPAT

typedef __u32 __sighandler_t32;

struct sigaction32 {
__sighandler_t32 sa_handler;
unsigned int sa_flags;
compat_sigset_t sa_mask; /* mask last for extensibility */
};

#endif

#endif
12 changes: 12 additions & 0 deletions trunk/arch/parisc/kernel/sys_parisc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
return -ENOSYS;
}

asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
struct compat_timespec __user *interval)
{
struct timespec t;
int ret;

KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t);
if (put_compat_timespec(&t, interval))
return -EFAULT;
return ret;
}

struct msgbuf32 {
int mtype;
char mtext[1];
Expand Down
10 changes: 5 additions & 5 deletions trunk/arch/parisc/kernel/syscall_table.S
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,12 @@
/* These 2 would've worked if someone had defined struct timespec
* carefully, like timeval for example (which is about the same).
* Unfortunately it contains a long :-( */
ENTRY_COMP(sched_rr_get_interval)
ENTRY_DIFF(sched_rr_get_interval)
ENTRY_COMP(nanosleep)
ENTRY_SAME(mremap)
ENTRY_SAME(setresuid)
ENTRY_SAME(getresuid) /* 165 */
ENTRY_COMP(sigaltstack)
ENTRY_DIFF(sigaltstack_wrapper)
ENTRY_SAME(ni_syscall) /* query_module */
ENTRY_SAME(poll)
/* structs contain pointers and an in_addr... */
Expand All @@ -265,9 +265,9 @@
ENTRY_SAME(prctl)
/* signals need a careful review */
ENTRY_SAME(rt_sigreturn_wrapper)
ENTRY_COMP(rt_sigaction)
ENTRY_COMP(rt_sigprocmask) /* 175 */
ENTRY_COMP(rt_sigpending)
ENTRY_DIFF(rt_sigaction)
ENTRY_DIFF(rt_sigprocmask) /* 175 */
ENTRY_DIFF(rt_sigpending)
ENTRY_COMP(rt_sigtimedwait)
/* even though the struct siginfo_t is different, it appears like
* all the paths use values which should be same wide and narrow.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ config PPC
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
select CLONE_BACKWARDS
select GENERIC_SIGALTSTACK

config EARLY_PRINTK
bool
Expand Down
4 changes: 0 additions & 4 deletions trunk/arch/powerpc/include/asm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,5 @@ asmlinkage long ppc64_personality(unsigned long personality);
asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
asmlinkage time_t sys64_time(time_t __user * tloc);

asmlinkage long sys_sigaltstack(const stack_t __user *uss,
stack_t __user *uoss, unsigned long r5, unsigned long r6,
unsigned long r7, unsigned long r8, struct pt_regs *regs);

#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_SYSCALLS_H */
Loading

0 comments on commit 529911a

Please sign in to comment.