[S390] 64-bit register support for 31-bit processes
From: Heiko Carstens <heiko.carstens@de.ibm.com> From: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
dd43bfca43
commit
ea2a4d3a3a
@ -39,6 +39,7 @@ typedef struct
|
||||
struct sigcontext32 sc;
|
||||
_sigregs32 sregs;
|
||||
int signo;
|
||||
__u32 gprs_high[NUM_GPRS];
|
||||
__u8 retcode[S390_SYSCALL_SIZE];
|
||||
} sigframe32;
|
||||
|
||||
@ -48,6 +49,7 @@ typedef struct
|
||||
__u8 retcode[S390_SYSCALL_SIZE];
|
||||
compat_siginfo_t info;
|
||||
struct ucontext32 uc;
|
||||
__u32 gprs_high[NUM_GPRS];
|
||||
} rt_sigframe32;
|
||||
|
||||
int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
|
||||
@ -344,6 +346,30 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
|
||||
{
|
||||
__u32 gprs_high[NUM_GPRS];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GPRS; i++)
|
||||
gprs_high[i] = regs->gprs[i] >> 32;
|
||||
|
||||
return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high));
|
||||
}
|
||||
|
||||
static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
|
||||
{
|
||||
__u32 gprs_high[NUM_GPRS];
|
||||
int err, i;
|
||||
|
||||
err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high));
|
||||
if (err)
|
||||
return err;
|
||||
for (i = 0; i < NUM_GPRS; i++)
|
||||
*(__u32 *)®s->gprs[i] = gprs_high[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
asmlinkage long sys32_sigreturn(void)
|
||||
{
|
||||
struct pt_regs *regs = task_pt_regs(current);
|
||||
@ -363,6 +389,8 @@ asmlinkage long sys32_sigreturn(void)
|
||||
|
||||
if (restore_sigregs32(regs, &frame->sregs))
|
||||
goto badframe;
|
||||
if (restore_sigregs_gprs_high(regs, frame->gprs_high))
|
||||
goto badframe;
|
||||
|
||||
return regs->gprs[2];
|
||||
|
||||
@ -394,6 +422,8 @@ asmlinkage long sys32_rt_sigreturn(void)
|
||||
|
||||
if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
if (restore_sigregs_gprs_high(regs, frame->gprs_high))
|
||||
goto badframe;
|
||||
|
||||
err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
|
||||
st.ss_sp = compat_ptr(ss_sp);
|
||||
@ -474,6 +504,8 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
|
||||
|
||||
if (save_sigregs32(regs, &frame->sregs))
|
||||
goto give_sigsegv;
|
||||
if (save_sigregs_gprs_high(regs, frame->gprs_high))
|
||||
goto give_sigsegv;
|
||||
if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
|
||||
goto give_sigsegv;
|
||||
|
||||
@ -529,13 +561,14 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
goto give_sigsegv;
|
||||
|
||||
/* Create the ucontext. */
|
||||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
|
||||
err |= __put_user(0, &frame->uc.uc_link);
|
||||
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(regs->gprs[15]),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
|
||||
err |= save_sigregs_gprs_high(regs, frame->gprs_high);
|
||||
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
|
||||
if (err)
|
||||
goto give_sigsegv;
|
||||
|
Reference in New Issue
Block a user