Skip to content

Commit

Permalink
ARCv3: r13 register changes in accordance with ABI
Browse files Browse the repository at this point in the history
For the ARCv3 architecture, changes have occurred regarding the r13 registry
in the ABI. Now register r13 from callee saved has become a scratch register.
This patch moves r13 in the corresponding structures and makes changes
in functions for proper saving and restoring user context.

We also saving and restoring missed r58/r59 registers when signal handling.
  • Loading branch information
xxkent committed Jun 13, 2024
1 parent 613326e commit 8fbed42
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 8 deletions.
8 changes: 8 additions & 0 deletions arch/arc/include/uapi/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,21 @@ struct user_regs_struct {
struct {
unsigned long bta, lp_start, lp_end, lp_count;
unsigned long status32, ret, blink, fp, gp;
#ifdef __ARC64__

This comment has been minimized.

Copy link
@shahab-vahedi

shahab-vahedi Jun 18, 2024

Member

@xxkent I think the following is a cleaner approach

struct user_regs_struct {

	unsigned long pad;
	struct {
		unsigned long bta, lp_start, lp_end, lp_count;
		unsigned long status32, ret, blink, fp, gp;
#ifdef __ARC64__
		unsigned long r13;
#endif
		unsigned long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
		unsigned long sp;
	} scratch;
	unsigned long pad2;
	struct {
		unsigned long r25, r24, r23, r22, r21, r20;
		unsigned long r19, r18, r17, r16, r15, r14;
#ifndef __ARC64__
		unsigned long r13;
#endif
	} callee;
	unsigned long efa;	/* break pt addr, for break points in delay slots */
	unsigned long stop_pc;	/* give dbg stop_pc after ensuring brkpt trap */
};
unsigned long r13, r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
#else
unsigned long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
#endif
unsigned long sp;
} scratch;
unsigned long pad2;
struct {
unsigned long r25, r24, r23, r22, r21, r20;
#ifdef __ARC64__
unsigned long r19, r18, r17, r16, r15, r14;
#else
unsigned long r19, r18, r17, r16, r15, r14, r13;
#endif
} callee;
unsigned long efa; /* break pt addr, for break points in delay slots */
unsigned long stop_pc; /* give dbg stop_pc after ensuring brkpt trap */
Expand Down
14 changes: 8 additions & 6 deletions arch/arc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ static int genregs_get(struct task_struct *target,
membuf_store(&to, ptregs->blink);
membuf_store(&to, ptregs->fp);
membuf_store(&to, ptregs->gp);
#ifdef CONFIG_ISA_ARCV3
membuf_store(&to, ptregs->r13);
#endif
membuf_store(&to, ptregs->r12);
membuf_store(&to, ptregs->r11);
membuf_store(&to, ptregs->r10);
Expand Down Expand Up @@ -68,9 +71,7 @@ static int genregs_get(struct task_struct *target,
membuf_store(&to, cregs->r16);
membuf_store(&to, cregs->r15);
membuf_store(&to, cregs->r14);
#ifdef CONFIG_ISA_ARCV3
membuf_store(&to, ptregs->r13);
#else
#ifndef CONFIG_ISA_ARCV3
membuf_store(&to, cregs->r13);
#endif
membuf_store(&to, target->thread.fault_address); // efa
Expand Down Expand Up @@ -134,6 +135,9 @@ static int genregs_set(struct task_struct *target,
REG_IN_ONE(scratch.blink, &ptregs->blink);
REG_IN_ONE(scratch.fp, &ptregs->fp);
REG_IN_ONE(scratch.gp, &ptregs->gp);
#ifdef CONFIG_ISA_ARCV3
REG_IN_ONE(scratch.r13, &ptregs->r13);
#endif
REG_IN_ONE(scratch.r12, &ptregs->r12);
REG_IN_ONE(scratch.r11, &ptregs->r11);
REG_IN_ONE(scratch.r10, &ptregs->r10);
Expand Down Expand Up @@ -164,9 +168,7 @@ static int genregs_set(struct task_struct *target,
REG_IN_ONE(callee.r15, &cregs->r15);
REG_IN_ONE(callee.r14, &cregs->r14);

#ifdef CONFIG_ISA_ARCV3
REG_IN_ONE(callee.r13, &ptregs->r13);
#else
#ifndef CONFIG_ISA_ARCV3
REG_IN_ONE(callee.r13, &cregs->r13);
#endif

Expand Down
10 changes: 8 additions & 2 deletions arch/arc/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
uregs.scratch.blink = regs->blink;
uregs.scratch.fp = regs->fp;
uregs.scratch.gp = regs->gp;
#ifdef CONFIG_ISA_ARCV3
uregs.scratch.r13 = regs->r13;
#endif
uregs.scratch.r12 = regs->r12;
uregs.scratch.r11 = regs->r11;
uregs.scratch.r10 = regs->r10;
Expand All @@ -147,7 +150,7 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
sizeof(sf->uc.uc_mcontext.regs.scratch));

if (is_isa_arcv2())
if (!is_isa_arcompact())
err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs);

err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
Expand All @@ -166,7 +169,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
&(sf->uc.uc_mcontext.regs.scratch),
sizeof(sf->uc.uc_mcontext.regs.scratch));

if (is_isa_arcv2())
if (!is_isa_arcompact())
err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs);

if (err)
Expand All @@ -184,6 +187,9 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
regs->blink = uregs.scratch.blink;
regs->fp = uregs.scratch.fp;
regs->gp = uregs.scratch.gp;
#ifdef CONFIG_ISA_ARCV3
regs->r13 = uregs.scratch.r13;
#endif
regs->r12 = uregs.scratch.r12;
regs->r11 = uregs.scratch.r11;
regs->r10 = uregs.scratch.r10;
Expand Down

0 comments on commit 8fbed42

Please sign in to comment.