瀏覽代碼

ARCv2: ptrace: provide regset for accumulator/r30 regs

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Vineet Gupta 8 年之前
父節點
當前提交
65c02a556b
共有 3 個文件被更改,包括 65 次插入3 次删除
  1. 1 0
      arch/arc/include/uapi/asm/elf.h
  2. 5 0
      arch/arc/include/uapi/asm/ptrace.h
  3. 59 3
      arch/arc/kernel/ptrace.c

+ 1 - 0
arch/arc/include/uapi/asm/elf.h

@@ -27,6 +27,7 @@ typedef unsigned long elf_greg_t;
 typedef unsigned long elf_fpregset_t;
 
 #define ELF_NGREG	(sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+#define ELF_ARCV2REG	(sizeof(struct user_regs_arcv2) / sizeof(elf_greg_t))
 
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 

+ 5 - 0
arch/arc/include/uapi/asm/ptrace.h

@@ -47,6 +47,11 @@ struct user_regs_struct {
 	unsigned long efa;	/* break pt addr, for break points in delay slots */
 	unsigned long stop_pc;	/* give dbg stop_pc after ensuring brkpt trap */
 };
+
+struct user_regs_arcv2 {
+	unsigned long r30, r58, r59;
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_ARC_PTRACE_H */

+ 59 - 3
arch/arc/kernel/ptrace.c

@@ -184,19 +184,75 @@ static int genregs_set(struct task_struct *target,
 	return ret;
 }
 
+#ifdef CONFIG_ISA_ARCV2
+static int arcv2regs_get(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
+{
+	const struct pt_regs *regs = task_pt_regs(target);
+	int ret, copy_sz;
+
+	if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS))
+		copy_sz = sizeof(struct user_regs_arcv2);
+	else
+		copy_sz = 4;	/* r30 only */
+
+	/*
+	 * itemized copy not needed like above as layout of regs (r30,r58,r59)
+	 * is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2)
+	 */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &regs->r30,
+				  0, copy_sz);
+
+	return ret;
+}
+
+static int arcv2regs_set(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
+{
+	const struct pt_regs *regs = task_pt_regs(target);
+	int ret, copy_sz;
+
+	if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS))
+		copy_sz = sizeof(struct user_regs_arcv2);
+	else
+		copy_sz = 4;	/* r30 only */
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, (void *)&regs->r30,
+				  0, copy_sz);
+
+	return ret;
+}
+
+#endif
+
 enum arc_getset {
-	REGSET_GENERAL,
+	REGSET_CMN,
+	REGSET_ARCV2,
 };
 
 static const struct user_regset arc_regsets[] = {
-	[REGSET_GENERAL] = {
+	[REGSET_CMN] = {
 	       .core_note_type = NT_PRSTATUS,
 	       .n = ELF_NGREG,
 	       .size = sizeof(unsigned long),
 	       .align = sizeof(unsigned long),
 	       .get = genregs_get,
 	       .set = genregs_set,
-	}
+	},
+#ifdef CONFIG_ISA_ARCV2
+	[REGSET_ARCV2] = {
+	       .core_note_type = NT_ARC_V2,
+	       .n = ELF_ARCV2REG,
+	       .size = sizeof(unsigned long),
+	       .align = sizeof(unsigned long),
+	       .get = arcv2regs_get,
+	       .set = arcv2regs_set,
+	},
+#endif
 };
 
 static const struct user_regset_view user_arc_view = {