diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 129 |
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 | ||