aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-06-24 20:02:58 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 21:28:45 -0400
commitc014e15a2f667f91b5c2d08a90d77197a89d8065 (patch)
tree8c02bf94abe2fcc53b8be94da527bbb2a42c671f /arch/blackfin/kernel
parent18070dd6692a35bec266ed9ea559c24da4fdeeef (diff)
Blackfin: convert ptrace to new memory functions
Now that we have a Blackfin memory function to figure out how to properly access the different regions, drop the custom memory range checks in our ptrace code and use that. It makes the code nicer and fixes bugs where the ptrace logic wasn't handling all the different regions. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/ptrace.c129
1 files changed, 72 insertions, 57 deletions
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 6a387eec6b65..271d7c63cef2 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -206,6 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
206{ 206{
207 int ret; 207 int ret;
208 unsigned long __user *datap = (unsigned long __user *)data; 208 unsigned long __user *datap = (unsigned long __user *)data;
209 void *paddr = (void *)addr;
209 210
210 switch (request) { 211 switch (request) {
211 /* when I and D space are separate, these will need to be fixed. */ 212 /* when I and D space are separate, these will need to be fixed. */
@@ -215,42 +216,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
215 case PTRACE_PEEKTEXT: /* read word at location addr. */ 216 case PTRACE_PEEKTEXT: /* read word at location addr. */
216 { 217 {
217 unsigned long tmp = 0; 218 unsigned long tmp = 0;
218 int copied; 219 int copied = 0, to_copy = sizeof(tmp);
219 220
220 ret = -EIO; 221 ret = -EIO;
221 pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data)); 222 pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %i\n", addr, to_copy);
222 if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) 223 if (is_user_addr_valid(child, addr, to_copy) < 0)
223 break; 224 break;
224 pr_debug("ptrace: user address is valid\n"); 225 pr_debug("ptrace: user address is valid\n");
225 226
226 if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start() 227 switch (bfin_mem_access_type(addr, to_copy)) {
227 && addr + sizeof(tmp) <= get_l1_code_start() + L1_CODE_LENGTH) { 228 case BFIN_MEM_ACCESS_CORE:
228 safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp)); 229 case BFIN_MEM_ACCESS_CORE_ONLY:
229 copied = sizeof(tmp);
230
231 } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
232 && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
233 memcpy(&tmp, (const void *)(addr), sizeof(tmp));
234 copied = sizeof(tmp);
235
236 } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
237 && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
238 memcpy(&tmp, (const void *)(addr), sizeof(tmp));
239 copied = sizeof(tmp);
240
241 } else if (addr >= FIXED_CODE_START
242 && addr + sizeof(tmp) <= FIXED_CODE_END) {
243 copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp));
244 copied = sizeof(tmp);
245
246 } else
247 copied = access_process_vm(child, addr, &tmp, 230 copied = access_process_vm(child, addr, &tmp,
248 sizeof(tmp), 0); 231 to_copy, 0);
232 if (copied)
233 break;
234
235 /* hrm, why didn't that work ... maybe no mapping */
236 if (addr >= FIXED_CODE_START &&
237 addr + to_copy <= FIXED_CODE_END) {
238 copy_from_user_page(0, 0, 0, &tmp, paddr, to_copy);
239 copied = to_copy;
240 } else if (addr >= BOOT_ROM_START) {
241 memcpy(&tmp, paddr, to_copy);
242 copied = to_copy;
243 }
249 244
250 pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
251 if (copied != sizeof(tmp))
252 break; 245 break;
253 ret = put_user(tmp, datap); 246 case BFIN_MEM_ACCESS_DMA:
247 if (safe_dma_memcpy(&tmp, paddr, to_copy))
248 copied = to_copy;
249 break;
250 case BFIN_MEM_ACCESS_ITEST:
251 if (isram_memcpy(&tmp, paddr, to_copy))
252 copied = to_copy;
253 break;
254 default:
255 copied = 0;
256 break;
257 }
258
259 pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
260 if (copied == to_copy)
261 ret = put_user(tmp, datap);
254 break; 262 break;
255 } 263 }
256 264
@@ -294,43 +302,50 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
294 /* fall through */ 302 /* fall through */
295 case PTRACE_POKETEXT: /* write the word at location addr. */ 303 case PTRACE_POKETEXT: /* write the word at location addr. */
296 { 304 {
297 int copied; 305 int copied = 0, to_copy = sizeof(data);
298 306
299 ret = -EIO; 307 ret = -EIO;
300 pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n", 308 pr_debug("ptrace: POKETEXT at addr 0x%08lx + %i bytes %lx\n",
301 addr, sizeof(data), data); 309 addr, to_copy, data);
302 if (is_user_addr_valid(child, addr, sizeof(data)) < 0) 310 if (is_user_addr_valid(child, addr, to_copy) < 0)
303 break; 311 break;
304 pr_debug("ptrace: user address is valid\n"); 312 pr_debug("ptrace: user address is valid\n");
305 313
306 if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start() 314 switch (bfin_mem_access_type(addr, to_copy)) {
307 && addr + sizeof(data) <= get_l1_code_start() + L1_CODE_LENGTH) { 315 case BFIN_MEM_ACCESS_CORE:
308 safe_dma_memcpy ((void *)(addr), &data, sizeof(data)); 316 case BFIN_MEM_ACCESS_CORE_ONLY:
309 copied = sizeof(data);
310
311 } else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
312 && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
313 memcpy((void *)(addr), &data, sizeof(data));
314 copied = sizeof(data);
315
316 } else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
317 && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
318 memcpy((void *)(addr), &data, sizeof(data));
319 copied = sizeof(data);
320
321 } else if (addr >= FIXED_CODE_START
322 && addr + sizeof(data) <= FIXED_CODE_END) {
323 copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data));
324 copied = sizeof(data);
325
326 } else
327 copied = access_process_vm(child, addr, &data, 317 copied = access_process_vm(child, addr, &data,
328 sizeof(data), 1); 318 to_copy, 0);
319 if (copied)
320 break;
321
322 /* hrm, why didn't that work ... maybe no mapping */
323 if (addr >= FIXED_CODE_START &&
324 addr + to_copy <= FIXED_CODE_END) {
325 copy_to_user_page(0, 0, 0, paddr, &data, to_copy);
326 copied = to_copy;
327 } else if (addr >= BOOT_ROM_START) {
328 memcpy(paddr, &data, to_copy);
329 copied = to_copy;
330 }
329 331
330 pr_debug("ptrace: copied size %d\n", copied);
331 if (copied != sizeof(data))
332 break; 332 break;
333 ret = 0; 333 case BFIN_MEM_ACCESS_DMA:
334 if (safe_dma_memcpy(paddr, &data, to_copy))
335 copied = to_copy;
336 break;
337 case BFIN_MEM_ACCESS_ITEST:
338 if (isram_memcpy(paddr, &data, to_copy))
339 copied = to_copy;
340 break;
341 default:
342 copied = 0;
343 break;
344 }
345
346 pr_debug("ptrace: copied size %d\n", copied);
347 if (copied == to_copy)
348 ret = 0;
334 break; 349 break;
335 } 350 }
336 351