Skip to content

Commit 96f1b00

Browse files
committed
ARCv2: save ABI registers across signal handling
ARCv2 has some configuration dependent registers (r30, r58, r59) which could be targetted by the compiler. To keep the ABI stable, these were unconditionally part of the glibc ABI (sysdeps/unix/sysv/linux/arc/sys/ucontext.h:mcontext_t) however we missed populating them (by saving/restoring them across signal handling). This patch fixes the issue by - adding arcv2 ABI regs to kernel struct sigcontext - populating them during signal handling Change to struct sigcontext might seem like a glibc ABI change (although it primarily uses ucontext_t:mcontext_t) but the fact is - it has only been extended (existing fields are not touched) - the old sigcontext was ABI incomplete to begin with anyways Fixes: foss-for-synopsys-dwc-arc-processors#53 Cc: <[email protected]> Tested-by: kernel test robot <[email protected]> Reported-by: Vladimir Isaev <[email protected]> Signed-off-by: Vineet Gupta <[email protected]>
1 parent d07f6ca commit 96f1b00

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

arch/arc/include/uapi/asm/sigcontext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
struct sigcontext {
2020
struct user_regs_struct regs;
21+
struct user_regs_arcv2 v2abi;
2122
};
2223

2324
#endif /* _ASM_ARC_SIGCONTEXT_H */

arch/arc/kernel/signal.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,41 @@ struct rt_sigframe {
6161
unsigned int sigret_magic;
6262
};
6363

64+
static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
65+
{
66+
int err = 0;
67+
#ifndef CONFIG_ISA_ARCOMPACT
68+
struct user_regs_arcv2 v2abi;
69+
70+
v2abi.r30 = regs->r30;
71+
#ifdef CONFIG_ARC_HAS_ACCL_REGS
72+
v2abi.r58 = regs->r58;
73+
v2abi.r59 = regs->r59;
74+
#else
75+
v2abi.r58 = v2abi.r59 = 0;
76+
#endif
77+
err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi));
78+
#endif
79+
return err;
80+
}
81+
82+
static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
83+
{
84+
int err = 0;
85+
#ifndef CONFIG_ISA_ARCOMPACT
86+
struct user_regs_arcv2 v2abi;
87+
88+
err = __copy_from_user(&v2abi, &mctx->v2abi, sizeof(v2abi));
89+
90+
regs->r30 = v2abi.r30;
91+
#ifdef CONFIG_ARC_HAS_ACCL_REGS
92+
regs->r58 = v2abi.r58;
93+
regs->r59 = v2abi.r59;
94+
#endif
95+
#endif
96+
return err;
97+
}
98+
6499
static int
65100
stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
66101
sigset_t *set)
@@ -94,6 +129,10 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
94129

95130
err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
96131
sizeof(sf->uc.uc_mcontext.regs.scratch));
132+
133+
if (is_isa_arcv2())
134+
err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs);
135+
97136
err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
98137

99138
return err ? -EFAULT : 0;
@@ -109,6 +148,10 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
109148
err |= __copy_from_user(&uregs.scratch,
110149
&(sf->uc.uc_mcontext.regs.scratch),
111150
sizeof(sf->uc.uc_mcontext.regs.scratch));
151+
152+
if (is_isa_arcv2())
153+
err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs);
154+
112155
if (err)
113156
return -EFAULT;
114157

0 commit comments

Comments
 (0)