diff options
author | Simon Marchi <simon.marchi@polymtl.ca> | 2012-12-17 20:08:09 -0500 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-12-18 14:53:06 -0500 |
commit | 7be68284bd201174bc6663b010cb56867a874276 (patch) | |
tree | 643e809627d815d460595b437217df20f75d32d6 | |
parent | 395e095ed92b1ccfe74c90fee4cc637cff468ea7 (diff) |
arch/tile: implement user_regset interface on tile
This is a basic implementation of user_regset for the tile
architecture. It reuses the basic blocks that were already there.
Signed-off-by: Simon Marchi <simon.marchi@polymtl.ca>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r-- | arch/tile/kernel/ptrace.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index b32bc3f9d631..882e38164773 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
@@ -19,7 +19,10 @@ | |||
19 | #include <linux/kprobes.h> | 19 | #include <linux/kprobes.h> |
20 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/regset.h> | ||
23 | #include <linux/elf.h> | ||
22 | #include <asm/traps.h> | 24 | #include <asm/traps.h> |
25 | #include <arch/chip.h> | ||
23 | 26 | ||
24 | void user_enable_single_step(struct task_struct *child) | 27 | void user_enable_single_step(struct task_struct *child) |
25 | { | 28 | { |
@@ -80,6 +83,65 @@ static void putregs(struct task_struct *child, struct pt_regs *uregs) | |||
80 | *regs = *uregs; | 83 | *regs = *uregs; |
81 | } | 84 | } |
82 | 85 | ||
86 | enum tile_regset { | ||
87 | REGSET_GPR, | ||
88 | }; | ||
89 | |||
90 | static int tile_gpr_get(struct task_struct *target, | ||
91 | const struct user_regset *regset, | ||
92 | unsigned int pos, unsigned int count, | ||
93 | void *kbuf, void __user *ubuf) | ||
94 | { | ||
95 | struct pt_regs regs; | ||
96 | |||
97 | getregs(target, ®s); | ||
98 | |||
99 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s, 0, | ||
100 | sizeof(regs)); | ||
101 | } | ||
102 | |||
103 | static int tile_gpr_set(struct task_struct *target, | ||
104 | const struct user_regset *regset, | ||
105 | unsigned int pos, unsigned int count, | ||
106 | const void *kbuf, const void __user *ubuf) | ||
107 | { | ||
108 | int ret; | ||
109 | struct pt_regs regs; | ||
110 | |||
111 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s, 0, | ||
112 | sizeof(regs)); | ||
113 | if (ret) | ||
114 | return ret; | ||
115 | |||
116 | putregs(target, ®s); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static const struct user_regset tile_user_regset[] = { | ||
122 | [REGSET_GPR] = { | ||
123 | .core_note_type = NT_PRSTATUS, | ||
124 | .n = ELF_NGREG, | ||
125 | .size = sizeof(elf_greg_t), | ||
126 | .align = sizeof(elf_greg_t), | ||
127 | .get = tile_gpr_get, | ||
128 | .set = tile_gpr_set, | ||
129 | }, | ||
130 | }; | ||
131 | |||
132 | static const struct user_regset_view tile_user_regset_view = { | ||
133 | .name = CHIP_ARCH_NAME, | ||
134 | .e_machine = ELF_ARCH, | ||
135 | .ei_osabi = ELF_OSABI, | ||
136 | .regsets = tile_user_regset, | ||
137 | .n = ARRAY_SIZE(tile_user_regset), | ||
138 | }; | ||
139 | |||
140 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | ||
141 | { | ||
142 | return &tile_user_regset_view; | ||
143 | } | ||
144 | |||
83 | long arch_ptrace(struct task_struct *child, long request, | 145 | long arch_ptrace(struct task_struct *child, long request, |
84 | unsigned long addr, unsigned long data) | 146 | unsigned long addr, unsigned long data) |
85 | { | 147 | { |