Skip to content

Commit 7aeb753

Browse files
committed
MIPS: Implement task_user_regset_view.
There are no users yet of task_user_regset_view. yet; users will be implemented rsp activated in subsequent commits. Signed-off-by: Ralf Baechle <[email protected]>
1 parent bc3d22c commit 7aeb753

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

arch/mips/kernel/ptrace.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
*/
1717
#include <linux/compiler.h>
1818
#include <linux/context_tracking.h>
19+
#include <linux/elf.h>
1920
#include <linux/kernel.h>
2021
#include <linux/sched.h>
2122
#include <linux/mm.h>
2223
#include <linux/errno.h>
2324
#include <linux/ptrace.h>
25+
#include <linux/regset.h>
2426
#include <linux/smp.h>
2527
#include <linux/user.h>
2628
#include <linux/security.h>
@@ -256,6 +258,133 @@ int ptrace_set_watch_regs(struct task_struct *child,
256258
return 0;
257259
}
258260

261+
/* regset get/set implementations */
262+
263+
static int gpr_get(struct task_struct *target,
264+
const struct user_regset *regset,
265+
unsigned int pos, unsigned int count,
266+
void *kbuf, void __user *ubuf)
267+
{
268+
struct pt_regs *regs = task_pt_regs(target);
269+
270+
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
271+
regs, 0, sizeof(*regs));
272+
}
273+
274+
static int gpr_set(struct task_struct *target,
275+
const struct user_regset *regset,
276+
unsigned int pos, unsigned int count,
277+
const void *kbuf, const void __user *ubuf)
278+
{
279+
struct pt_regs newregs;
280+
int ret;
281+
282+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
283+
&newregs,
284+
0, sizeof(newregs));
285+
if (ret)
286+
return ret;
287+
288+
*task_pt_regs(target) = newregs;
289+
290+
return 0;
291+
}
292+
293+
static int fpr_get(struct task_struct *target,
294+
const struct user_regset *regset,
295+
unsigned int pos, unsigned int count,
296+
void *kbuf, void __user *ubuf)
297+
{
298+
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
299+
&target->thread.fpu,
300+
0, sizeof(elf_fpregset_t));
301+
/* XXX fcr31 */
302+
}
303+
304+
static int fpr_set(struct task_struct *target,
305+
const struct user_regset *regset,
306+
unsigned int pos, unsigned int count,
307+
const void *kbuf, const void __user *ubuf)
308+
{
309+
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
310+
&target->thread.fpu,
311+
0, sizeof(elf_fpregset_t));
312+
/* XXX fcr31 */
313+
}
314+
315+
enum mips_regset {
316+
REGSET_GPR,
317+
REGSET_FPR,
318+
};
319+
320+
static const struct user_regset mips_regsets[] = {
321+
[REGSET_GPR] = {
322+
.core_note_type = NT_PRSTATUS,
323+
.n = ELF_NGREG,
324+
.size = sizeof(unsigned int),
325+
.align = sizeof(unsigned int),
326+
.get = gpr_get,
327+
.set = gpr_set,
328+
},
329+
[REGSET_FPR] = {
330+
.core_note_type = NT_PRFPREG,
331+
.n = ELF_NFPREG,
332+
.size = sizeof(elf_fpreg_t),
333+
.align = sizeof(elf_fpreg_t),
334+
.get = fpr_get,
335+
.set = fpr_set,
336+
},
337+
};
338+
339+
static const struct user_regset_view user_mips_view = {
340+
.name = "mips",
341+
.e_machine = ELF_ARCH,
342+
.ei_osabi = ELF_OSABI,
343+
.regsets = mips_regsets,
344+
.n = ARRAY_SIZE(mips_regsets),
345+
};
346+
347+
static const struct user_regset mips64_regsets[] = {
348+
[REGSET_GPR] = {
349+
.core_note_type = NT_PRSTATUS,
350+
.n = ELF_NGREG,
351+
.size = sizeof(unsigned long),
352+
.align = sizeof(unsigned long),
353+
.get = gpr_get,
354+
.set = gpr_set,
355+
},
356+
[REGSET_FPR] = {
357+
.core_note_type = NT_PRFPREG,
358+
.n = ELF_NFPREG,
359+
.size = sizeof(elf_fpreg_t),
360+
.align = sizeof(elf_fpreg_t),
361+
.get = fpr_get,
362+
.set = fpr_set,
363+
},
364+
};
365+
366+
static const struct user_regset_view user_mips64_view = {
367+
.name = "mips",
368+
.e_machine = ELF_ARCH,
369+
.ei_osabi = ELF_OSABI,
370+
.regsets = mips64_regsets,
371+
.n = ARRAY_SIZE(mips_regsets),
372+
};
373+
374+
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
375+
{
376+
#ifdef CONFIG_32BIT
377+
return &user_mips_view;
378+
#endif
379+
380+
#ifdef CONFIG_MIPS32_O32
381+
if (test_thread_flag(TIF_32BIT_REGS))
382+
return &user_mips_view;
383+
#endif
384+
385+
return &user_mips64_view;
386+
}
387+
259388
long arch_ptrace(struct task_struct *child, long request,
260389
unsigned long addr, unsigned long data)
261390
{

0 commit comments

Comments
 (0)