Skip to content

Commit 19b39c3

Browse files
committed
Merge branch 'work.regset' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull ptrace regset updates from Al Viro: "Internal regset API changes: - regularize copy_regset_{to,from}_user() callers - switch to saner calling conventions for ->get() - kill user_regset_copyout() The ->put() side of things will have to wait for the next cycle, unfortunately. The balance is about -1KLoC and replacements for ->get() instances are a lot saner" * 'work.regset' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (41 commits) regset: kill user_regset_copyout{,_zero}() regset(): kill ->get_size() regset: kill ->get() csky: switch to ->regset_get() xtensa: switch to ->regset_get() parisc: switch to ->regset_get() nds32: switch to ->regset_get() nios2: switch to ->regset_get() hexagon: switch to ->regset_get() h8300: switch to ->regset_get() openrisc: switch to ->regset_get() riscv: switch to ->regset_get() c6x: switch to ->regset_get() ia64: switch to ->regset_get() arc: switch to ->regset_get() arm: switch to ->regset_get() sh: convert to ->regset_get() arm64: switch to ->regset_get() mips: switch to ->regset_get() sparc: switch to ->regset_get() ...
2 parents 995909a + ce327e1 commit 19b39c3

File tree

41 files changed

+1370
-2349
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1370
-2349
lines changed

arch/arc/kernel/ptrace.c

Lines changed: 58 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -18,88 +18,61 @@ static struct callee_regs *task_callee_regs(struct task_struct *tsk)
1818

1919
static int genregs_get(struct task_struct *target,
2020
const struct user_regset *regset,
21-
unsigned int pos, unsigned int count,
22-
void *kbuf, void __user *ubuf)
21+
struct membuf to)
2322
{
2423
const struct pt_regs *ptregs = task_pt_regs(target);
2524
const struct callee_regs *cregs = task_callee_regs(target);
26-
int ret = 0;
2725
unsigned int stop_pc_val;
2826

29-
#define REG_O_CHUNK(START, END, PTR) \
30-
if (!ret) \
31-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \
32-
offsetof(struct user_regs_struct, START), \
33-
offsetof(struct user_regs_struct, END));
34-
35-
#define REG_O_ONE(LOC, PTR) \
36-
if (!ret) \
37-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \
38-
offsetof(struct user_regs_struct, LOC), \
39-
offsetof(struct user_regs_struct, LOC) + 4);
40-
41-
#define REG_O_ZERO(LOC) \
42-
if (!ret) \
43-
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, \
44-
offsetof(struct user_regs_struct, LOC), \
45-
offsetof(struct user_regs_struct, LOC) + 4);
46-
47-
REG_O_ZERO(pad);
48-
REG_O_ONE(scratch.bta, &ptregs->bta);
49-
REG_O_ONE(scratch.lp_start, &ptregs->lp_start);
50-
REG_O_ONE(scratch.lp_end, &ptregs->lp_end);
51-
REG_O_ONE(scratch.lp_count, &ptregs->lp_count);
52-
REG_O_ONE(scratch.status32, &ptregs->status32);
53-
REG_O_ONE(scratch.ret, &ptregs->ret);
54-
REG_O_ONE(scratch.blink, &ptregs->blink);
55-
REG_O_ONE(scratch.fp, &ptregs->fp);
56-
REG_O_ONE(scratch.gp, &ptregs->r26);
57-
REG_O_ONE(scratch.r12, &ptregs->r12);
58-
REG_O_ONE(scratch.r11, &ptregs->r11);
59-
REG_O_ONE(scratch.r10, &ptregs->r10);
60-
REG_O_ONE(scratch.r9, &ptregs->r9);
61-
REG_O_ONE(scratch.r8, &ptregs->r8);
62-
REG_O_ONE(scratch.r7, &ptregs->r7);
63-
REG_O_ONE(scratch.r6, &ptregs->r6);
64-
REG_O_ONE(scratch.r5, &ptregs->r5);
65-
REG_O_ONE(scratch.r4, &ptregs->r4);
66-
REG_O_ONE(scratch.r3, &ptregs->r3);
67-
REG_O_ONE(scratch.r2, &ptregs->r2);
68-
REG_O_ONE(scratch.r1, &ptregs->r1);
69-
REG_O_ONE(scratch.r0, &ptregs->r0);
70-
REG_O_ONE(scratch.sp, &ptregs->sp);
71-
72-
REG_O_ZERO(pad2);
73-
74-
REG_O_ONE(callee.r25, &cregs->r25);
75-
REG_O_ONE(callee.r24, &cregs->r24);
76-
REG_O_ONE(callee.r23, &cregs->r23);
77-
REG_O_ONE(callee.r22, &cregs->r22);
78-
REG_O_ONE(callee.r21, &cregs->r21);
79-
REG_O_ONE(callee.r20, &cregs->r20);
80-
REG_O_ONE(callee.r19, &cregs->r19);
81-
REG_O_ONE(callee.r18, &cregs->r18);
82-
REG_O_ONE(callee.r17, &cregs->r17);
83-
REG_O_ONE(callee.r16, &cregs->r16);
84-
REG_O_ONE(callee.r15, &cregs->r15);
85-
REG_O_ONE(callee.r14, &cregs->r14);
86-
REG_O_ONE(callee.r13, &cregs->r13);
87-
88-
REG_O_ONE(efa, &target->thread.fault_address);
89-
90-
if (!ret) {
91-
if (in_brkpt_trap(ptregs)) {
92-
stop_pc_val = target->thread.fault_address;
93-
pr_debug("\t\tstop_pc (brk-pt)\n");
94-
} else {
95-
stop_pc_val = ptregs->ret;
96-
pr_debug("\t\tstop_pc (others)\n");
97-
}
98-
99-
REG_O_ONE(stop_pc, &stop_pc_val);
27+
membuf_zero(&to, 4); // pad
28+
membuf_store(&to, ptregs->bta);
29+
membuf_store(&to, ptregs->lp_start);
30+
membuf_store(&to, ptregs->lp_end);
31+
membuf_store(&to, ptregs->lp_count);
32+
membuf_store(&to, ptregs->status32);
33+
membuf_store(&to, ptregs->ret);
34+
membuf_store(&to, ptregs->blink);
35+
membuf_store(&to, ptregs->fp);
36+
membuf_store(&to, ptregs->r26); // gp
37+
membuf_store(&to, ptregs->r12);
38+
membuf_store(&to, ptregs->r11);
39+
membuf_store(&to, ptregs->r10);
40+
membuf_store(&to, ptregs->r9);
41+
membuf_store(&to, ptregs->r8);
42+
membuf_store(&to, ptregs->r7);
43+
membuf_store(&to, ptregs->r6);
44+
membuf_store(&to, ptregs->r5);
45+
membuf_store(&to, ptregs->r4);
46+
membuf_store(&to, ptregs->r3);
47+
membuf_store(&to, ptregs->r2);
48+
membuf_store(&to, ptregs->r1);
49+
membuf_store(&to, ptregs->r0);
50+
membuf_store(&to, ptregs->sp);
51+
membuf_zero(&to, 4); // pad2
52+
membuf_store(&to, cregs->r25);
53+
membuf_store(&to, cregs->r24);
54+
membuf_store(&to, cregs->r23);
55+
membuf_store(&to, cregs->r22);
56+
membuf_store(&to, cregs->r21);
57+
membuf_store(&to, cregs->r20);
58+
membuf_store(&to, cregs->r19);
59+
membuf_store(&to, cregs->r18);
60+
membuf_store(&to, cregs->r17);
61+
membuf_store(&to, cregs->r16);
62+
membuf_store(&to, cregs->r15);
63+
membuf_store(&to, cregs->r14);
64+
membuf_store(&to, cregs->r13);
65+
membuf_store(&to, target->thread.fault_address); // efa
66+
67+
if (in_brkpt_trap(ptregs)) {
68+
stop_pc_val = target->thread.fault_address;
69+
pr_debug("\t\tstop_pc (brk-pt)\n");
70+
} else {
71+
stop_pc_val = ptregs->ret;
72+
pr_debug("\t\tstop_pc (others)\n");
10073
}
10174

102-
return ret;
75+
return membuf_store(&to, stop_pc_val); // stop_pc
10376
}
10477

10578
static int genregs_set(struct task_struct *target,
@@ -184,25 +157,20 @@ static int genregs_set(struct task_struct *target,
184157
#ifdef CONFIG_ISA_ARCV2
185158
static int arcv2regs_get(struct task_struct *target,
186159
const struct user_regset *regset,
187-
unsigned int pos, unsigned int count,
188-
void *kbuf, void __user *ubuf)
160+
struct membuf to)
189161
{
190162
const struct pt_regs *regs = task_pt_regs(target);
191-
int ret, copy_sz;
192163

193164
if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS))
194-
copy_sz = sizeof(struct user_regs_arcv2);
195-
else
196-
copy_sz = 4; /* r30 only */
165+
/*
166+
* itemized copy not needed like above as layout of regs (r30,r58,r59)
167+
* is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2)
168+
*/
169+
return membuf_write(&to, &regs->r30, sizeof(struct user_regs_arcv2));
197170

198-
/*
199-
* itemized copy not needed like above as layout of regs (r30,r58,r59)
200-
* is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2)
201-
*/
202-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &regs->r30,
203-
0, copy_sz);
204171

205-
return ret;
172+
membuf_write(&to, &regs->r30, 4); /* r30 only */
173+
return membuf_zero(&to, sizeof(struct user_regs_arcv2) - 4);
206174
}
207175

208176
static int arcv2regs_set(struct task_struct *target,
@@ -237,7 +205,7 @@ static const struct user_regset arc_regsets[] = {
237205
.n = ELF_NGREG,
238206
.size = sizeof(unsigned long),
239207
.align = sizeof(unsigned long),
240-
.get = genregs_get,
208+
.regset_get = genregs_get,
241209
.set = genregs_set,
242210
},
243211
#ifdef CONFIG_ISA_ARCV2
@@ -246,7 +214,7 @@ static const struct user_regset arc_regsets[] = {
246214
.n = ELF_ARCV2REG,
247215
.size = sizeof(unsigned long),
248216
.align = sizeof(unsigned long),
249-
.get = arcv2regs_get,
217+
.regset_get = arcv2regs_get,
250218
.set = arcv2regs_set,
251219
},
252220
#endif

arch/arm/kernel/ptrace.c

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -569,14 +569,9 @@ static int ptrace_sethbpregs(struct task_struct *tsk, long num,
569569

570570
static int gpr_get(struct task_struct *target,
571571
const struct user_regset *regset,
572-
unsigned int pos, unsigned int count,
573-
void *kbuf, void __user *ubuf)
572+
struct membuf to)
574573
{
575-
struct pt_regs *regs = task_pt_regs(target);
576-
577-
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
578-
regs,
579-
0, sizeof(*regs));
574+
return membuf_write(&to, task_pt_regs(target), sizeof(struct pt_regs));
580575
}
581576

582577
static int gpr_set(struct task_struct *target,
@@ -602,12 +597,10 @@ static int gpr_set(struct task_struct *target,
602597

603598
static int fpa_get(struct task_struct *target,
604599
const struct user_regset *regset,
605-
unsigned int pos, unsigned int count,
606-
void *kbuf, void __user *ubuf)
600+
struct membuf to)
607601
{
608-
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
609-
&task_thread_info(target)->fpstate,
610-
0, sizeof(struct user_fp));
602+
return membuf_write(&to, &task_thread_info(target)->fpstate,
603+
sizeof(struct user_fp));
611604
}
612605

613606
static int fpa_set(struct task_struct *target,
@@ -642,41 +635,20 @@ static int fpa_set(struct task_struct *target,
642635
* vfp_set() ignores this chunk
643636
*
644637
* 1 word for the FPSCR
645-
*
646-
* The bounds-checking logic built into user_regset_copyout and friends
647-
* means that we can make a simple sequence of calls to map the relevant data
648-
* to/from the specified slice of the user regset structure.
649638
*/
650639
static int vfp_get(struct task_struct *target,
651640
const struct user_regset *regset,
652-
unsigned int pos, unsigned int count,
653-
void *kbuf, void __user *ubuf)
641+
struct membuf to)
654642
{
655-
int ret;
656643
struct thread_info *thread = task_thread_info(target);
657644
struct vfp_hard_struct const *vfp = &thread->vfpstate.hard;
658-
const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
659645
const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
660646

661647
vfp_sync_hwstate(thread);
662648

663-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
664-
&vfp->fpregs,
665-
user_fpregs_offset,
666-
user_fpregs_offset + sizeof(vfp->fpregs));
667-
if (ret)
668-
return ret;
669-
670-
ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
671-
user_fpregs_offset + sizeof(vfp->fpregs),
672-
user_fpscr_offset);
673-
if (ret)
674-
return ret;
675-
676-
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
677-
&vfp->fpscr,
678-
user_fpscr_offset,
679-
user_fpscr_offset + sizeof(vfp->fpscr));
649+
membuf_write(&to, vfp->fpregs, sizeof(vfp->fpregs));
650+
membuf_zero(&to, user_fpscr_offset - sizeof(vfp->fpregs));
651+
return membuf_store(&to, vfp->fpscr);
680652
}
681653

682654
/*
@@ -739,7 +711,7 @@ static const struct user_regset arm_regsets[] = {
739711
.n = ELF_NGREG,
740712
.size = sizeof(u32),
741713
.align = sizeof(u32),
742-
.get = gpr_get,
714+
.regset_get = gpr_get,
743715
.set = gpr_set
744716
},
745717
[REGSET_FPR] = {
@@ -751,7 +723,7 @@ static const struct user_regset arm_regsets[] = {
751723
.n = sizeof(struct user_fp) / sizeof(u32),
752724
.size = sizeof(u32),
753725
.align = sizeof(u32),
754-
.get = fpa_get,
726+
.regset_get = fpa_get,
755727
.set = fpa_set
756728
},
757729
#ifdef CONFIG_VFP
@@ -764,7 +736,7 @@ static const struct user_regset arm_regsets[] = {
764736
.n = ARM_VFPREGS_SIZE / sizeof(u32),
765737
.size = sizeof(u32),
766738
.align = sizeof(u32),
767-
.get = vfp_get,
739+
.regset_get = vfp_get,
768740
.set = vfp_set
769741
},
770742
#endif /* CONFIG_VFP */

0 commit comments

Comments
 (0)