mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 16:29:59 +00:00
ARC: Make way for pt_regs != user_regs_struct
These have been register compatible so far. However ARCv2 mandates different pt_regs layout (due to h/w auto save). To keep pt_regs same for both, we start by removing the assumption - used mainly for block copies between the 2 structs in signal handling and ptrace Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
parent
5a343b9fe2
commit
6ffb9c8c5f
2 changed files with 137 additions and 9 deletions
|
@ -47,10 +47,47 @@ static int genregs_get(struct task_struct *target,
|
|||
offsetof(struct user_regs_struct, LOC) + 4);
|
||||
|
||||
REG_O_ZERO(pad);
|
||||
REG_O_CHUNK(scratch, callee, ptregs);
|
||||
REG_O_ONE(scratch.bta, &ptregs->bta);
|
||||
REG_O_ONE(scratch.lp_start, &ptregs->lp_start);
|
||||
REG_O_ONE(scratch.lp_end, &ptregs->lp_end);
|
||||
REG_O_ONE(scratch.lp_count, &ptregs->lp_count);
|
||||
REG_O_ONE(scratch.status32, &ptregs->status32);
|
||||
REG_O_ONE(scratch.ret, &ptregs->ret);
|
||||
REG_O_ONE(scratch.blink, &ptregs->blink);
|
||||
REG_O_ONE(scratch.fp, &ptregs->fp);
|
||||
REG_O_ONE(scratch.gp, &ptregs->r26);
|
||||
REG_O_ONE(scratch.r12, &ptregs->r12);
|
||||
REG_O_ONE(scratch.r11, &ptregs->r11);
|
||||
REG_O_ONE(scratch.r10, &ptregs->r10);
|
||||
REG_O_ONE(scratch.r9, &ptregs->r9);
|
||||
REG_O_ONE(scratch.r8, &ptregs->r8);
|
||||
REG_O_ONE(scratch.r7, &ptregs->r7);
|
||||
REG_O_ONE(scratch.r6, &ptregs->r6);
|
||||
REG_O_ONE(scratch.r5, &ptregs->r5);
|
||||
REG_O_ONE(scratch.r4, &ptregs->r4);
|
||||
REG_O_ONE(scratch.r3, &ptregs->r3);
|
||||
REG_O_ONE(scratch.r2, &ptregs->r2);
|
||||
REG_O_ONE(scratch.r1, &ptregs->r1);
|
||||
REG_O_ONE(scratch.r0, &ptregs->r0);
|
||||
REG_O_ONE(scratch.sp, &ptregs->sp);
|
||||
|
||||
REG_O_ZERO(pad2);
|
||||
REG_O_CHUNK(callee, efa, cregs);
|
||||
REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address);
|
||||
|
||||
REG_O_ONE(callee.r25, &cregs->r25);
|
||||
REG_O_ONE(callee.r24, &cregs->r24);
|
||||
REG_O_ONE(callee.r23, &cregs->r23);
|
||||
REG_O_ONE(callee.r22, &cregs->r22);
|
||||
REG_O_ONE(callee.r21, &cregs->r21);
|
||||
REG_O_ONE(callee.r20, &cregs->r20);
|
||||
REG_O_ONE(callee.r19, &cregs->r19);
|
||||
REG_O_ONE(callee.r18, &cregs->r18);
|
||||
REG_O_ONE(callee.r17, &cregs->r17);
|
||||
REG_O_ONE(callee.r16, &cregs->r16);
|
||||
REG_O_ONE(callee.r15, &cregs->r15);
|
||||
REG_O_ONE(callee.r14, &cregs->r14);
|
||||
REG_O_ONE(callee.r13, &cregs->r13);
|
||||
|
||||
REG_O_ONE(efa, &target->thread.fault_address);
|
||||
|
||||
if (!ret) {
|
||||
if (in_brkpt_trap(ptregs)) {
|
||||
|
@ -97,12 +134,51 @@ static int genregs_set(struct task_struct *target,
|
|||
offsetof(struct user_regs_struct, LOC) + 4);
|
||||
|
||||
REG_IGNORE_ONE(pad);
|
||||
/* TBD: disallow updates to STATUS32 etc*/
|
||||
REG_IN_CHUNK(scratch, pad2, ptregs); /* pt_regs[bta..sp] */
|
||||
|
||||
REG_IN_ONE(scratch.bta, &ptregs->bta);
|
||||
REG_IN_ONE(scratch.lp_start, &ptregs->lp_start);
|
||||
REG_IN_ONE(scratch.lp_end, &ptregs->lp_end);
|
||||
REG_IN_ONE(scratch.lp_count, &ptregs->lp_count);
|
||||
|
||||
REG_IGNORE_ONE(scratch.status32);
|
||||
|
||||
REG_IN_ONE(scratch.ret, &ptregs->ret);
|
||||
REG_IN_ONE(scratch.blink, &ptregs->blink);
|
||||
REG_IN_ONE(scratch.fp, &ptregs->fp);
|
||||
REG_IN_ONE(scratch.gp, &ptregs->r26);
|
||||
REG_IN_ONE(scratch.r12, &ptregs->r12);
|
||||
REG_IN_ONE(scratch.r11, &ptregs->r11);
|
||||
REG_IN_ONE(scratch.r10, &ptregs->r10);
|
||||
REG_IN_ONE(scratch.r9, &ptregs->r9);
|
||||
REG_IN_ONE(scratch.r8, &ptregs->r8);
|
||||
REG_IN_ONE(scratch.r7, &ptregs->r7);
|
||||
REG_IN_ONE(scratch.r6, &ptregs->r6);
|
||||
REG_IN_ONE(scratch.r5, &ptregs->r5);
|
||||
REG_IN_ONE(scratch.r4, &ptregs->r4);
|
||||
REG_IN_ONE(scratch.r3, &ptregs->r3);
|
||||
REG_IN_ONE(scratch.r2, &ptregs->r2);
|
||||
REG_IN_ONE(scratch.r1, &ptregs->r1);
|
||||
REG_IN_ONE(scratch.r0, &ptregs->r0);
|
||||
REG_IN_ONE(scratch.sp, &ptregs->sp);
|
||||
|
||||
REG_IGNORE_ONE(pad2);
|
||||
REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */
|
||||
|
||||
REG_IN_ONE(callee.r25, &cregs->r25);
|
||||
REG_IN_ONE(callee.r24, &cregs->r24);
|
||||
REG_IN_ONE(callee.r23, &cregs->r23);
|
||||
REG_IN_ONE(callee.r22, &cregs->r22);
|
||||
REG_IN_ONE(callee.r21, &cregs->r21);
|
||||
REG_IN_ONE(callee.r20, &cregs->r20);
|
||||
REG_IN_ONE(callee.r19, &cregs->r19);
|
||||
REG_IN_ONE(callee.r18, &cregs->r18);
|
||||
REG_IN_ONE(callee.r17, &cregs->r17);
|
||||
REG_IN_ONE(callee.r16, &cregs->r16);
|
||||
REG_IN_ONE(callee.r15, &cregs->r15);
|
||||
REG_IN_ONE(callee.r14, &cregs->r14);
|
||||
REG_IN_ONE(callee.r13, &cregs->r13);
|
||||
|
||||
REG_IGNORE_ONE(efa); /* efa update invalid */
|
||||
REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */
|
||||
REG_IGNORE_ONE(stop_pc); /* PC updated via @ret */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,33 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
|
|||
sigset_t *set)
|
||||
{
|
||||
int err;
|
||||
err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), regs,
|
||||
struct user_regs_struct uregs;
|
||||
|
||||
uregs.scratch.bta = regs->bta;
|
||||
uregs.scratch.lp_start = regs->lp_start;
|
||||
uregs.scratch.lp_end = regs->lp_end;
|
||||
uregs.scratch.lp_count = regs->lp_count;
|
||||
uregs.scratch.status32 = regs->status32;
|
||||
uregs.scratch.ret = regs->ret;
|
||||
uregs.scratch.blink = regs->blink;
|
||||
uregs.scratch.fp = regs->fp;
|
||||
uregs.scratch.gp = regs->r26;
|
||||
uregs.scratch.r12 = regs->r12;
|
||||
uregs.scratch.r11 = regs->r11;
|
||||
uregs.scratch.r10 = regs->r10;
|
||||
uregs.scratch.r9 = regs->r9;
|
||||
uregs.scratch.r8 = regs->r8;
|
||||
uregs.scratch.r7 = regs->r7;
|
||||
uregs.scratch.r6 = regs->r6;
|
||||
uregs.scratch.r5 = regs->r5;
|
||||
uregs.scratch.r4 = regs->r4;
|
||||
uregs.scratch.r3 = regs->r3;
|
||||
uregs.scratch.r2 = regs->r2;
|
||||
uregs.scratch.r1 = regs->r1;
|
||||
uregs.scratch.r0 = regs->r0;
|
||||
uregs.scratch.sp = regs->sp;
|
||||
|
||||
err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
|
||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
|
||||
|
||||
|
@ -78,14 +104,40 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
|
|||
{
|
||||
sigset_t set;
|
||||
int err;
|
||||
struct user_regs_struct uregs;
|
||||
|
||||
err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
|
||||
if (!err)
|
||||
set_current_blocked(&set);
|
||||
|
||||
err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch),
|
||||
err |= __copy_from_user(&uregs.scratch,
|
||||
&(sf->uc.uc_mcontext.regs.scratch),
|
||||
sizeof(sf->uc.uc_mcontext.regs.scratch));
|
||||
|
||||
regs->bta = uregs.scratch.bta;
|
||||
regs->lp_start = uregs.scratch.lp_start;
|
||||
regs->lp_end = uregs.scratch.lp_end;
|
||||
regs->lp_count = uregs.scratch.lp_count;
|
||||
regs->status32 = uregs.scratch.status32;
|
||||
regs->ret = uregs.scratch.ret;
|
||||
regs->blink = uregs.scratch.blink;
|
||||
regs->fp = uregs.scratch.fp;
|
||||
regs->r26 = uregs.scratch.gp;
|
||||
regs->r12 = uregs.scratch.r12;
|
||||
regs->r11 = uregs.scratch.r11;
|
||||
regs->r10 = uregs.scratch.r10;
|
||||
regs->r9 = uregs.scratch.r9;
|
||||
regs->r8 = uregs.scratch.r8;
|
||||
regs->r7 = uregs.scratch.r7;
|
||||
regs->r6 = uregs.scratch.r6;
|
||||
regs->r5 = uregs.scratch.r5;
|
||||
regs->r4 = uregs.scratch.r4;
|
||||
regs->r3 = uregs.scratch.r3;
|
||||
regs->r2 = uregs.scratch.r2;
|
||||
regs->r1 = uregs.scratch.r1;
|
||||
regs->r0 = uregs.scratch.r0;
|
||||
regs->sp = uregs.scratch.sp;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue