aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2007-07-17 07:03:43 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:03 -0400
commit7664732315c97f48dba9d1e7339ad16fc5a320ac (patch)
tree1eb9639b0fbe3f24341cecf1dafcae192cb7bde7
parentbcdcd8e725b923ad7c0de809680d5d5658a7bf8c (diff)
PTRACE_PEEKDATA consolidation
Identical implementations of PTRACE_PEEKDATA go into generic_ptrace_peekdata() function. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Christoph Hellwig <hch@lst.de> Cc: <linux-arch@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm26/kernel/ptrace.c8
-rw-r--r--arch/avr32/kernel/ptrace.c7
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c14
-rw-r--r--arch/frv/kernel/ptrace.c12
-rw-r--r--arch/i386/kernel/ptrace.c12
-rw-r--r--arch/m32r/kernel/ptrace.c7
-rw-r--r--arch/m68k/kernel/ptrace.c5
-rw-r--r--arch/m68knommu/kernel/ptrace.c12
-rw-r--r--arch/mips/kernel/ptrace.c12
-rw-r--r--arch/parisc/kernel/ptrace.c13
-rw-r--r--arch/powerpc/kernel/ptrace.c12
-rw-r--r--arch/s390/kernel/ptrace.c6
-rw-r--r--arch/sh/kernel/ptrace.c13
-rw-r--r--arch/sh64/kernel/ptrace.c12
-rw-r--r--arch/um/kernel/ptrace.c12
-rw-r--r--arch/v850/kernel/ptrace.c8
-rw-r--r--arch/x86_64/kernel/ptrace.c12
-rw-r--r--arch/xtensa/kernel/ptrace.c12
-rw-r--r--include/linux/ptrace.h1
-rw-r--r--kernel/ptrace.c11
21 files changed, 43 insertions, 166 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 6f2f46c2e406..9a5d9754c2a2 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -657,7 +657,6 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
657 657
658long arch_ptrace(struct task_struct *child, long request, long addr, long data) 658long arch_ptrace(struct task_struct *child, long request, long addr, long data)
659{ 659{
660 unsigned long tmp;
661 int ret; 660 int ret;
662 661
663 switch (request) { 662 switch (request) {
@@ -666,12 +665,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
666 */ 665 */
667 case PTRACE_PEEKTEXT: 666 case PTRACE_PEEKTEXT:
668 case PTRACE_PEEKDATA: 667 case PTRACE_PEEKDATA:
669 ret = access_process_vm(child, addr, &tmp, 668 ret = generic_ptrace_peekdata(child, addr, data);
670 sizeof(unsigned long), 0);
671 if (ret == sizeof(unsigned long))
672 ret = put_user(tmp, (unsigned long __user *) data);
673 else
674 ret = -EIO;
675 break; 669 break;
676 670
677 case PTRACE_PEEKUSR: 671 case PTRACE_PEEKUSR:
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 416927956721..0d0ead0e0a74 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -531,7 +531,6 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
531 531
532long arch_ptrace(struct task_struct *child, long request, long addr, long data) 532long arch_ptrace(struct task_struct *child, long request, long addr, long data)
533{ 533{
534 unsigned long tmp;
535 int ret; 534 int ret;
536 535
537 switch (request) { 536 switch (request) {
@@ -540,12 +539,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
540 */ 539 */
541 case PTRACE_PEEKTEXT: 540 case PTRACE_PEEKTEXT:
542 case PTRACE_PEEKDATA: 541 case PTRACE_PEEKDATA:
543 ret = access_process_vm(child, addr, &tmp, 542 ret = generic_ptrace_peekdata(child, addr, data);
544 sizeof(unsigned long), 0);
545 if (ret == sizeof(unsigned long))
546 ret = put_user(tmp, (unsigned long *) data);
547 else
548 ret = -EIO;
549 break; 543 break;
550 544
551 case PTRACE_PEEKUSR: 545 case PTRACE_PEEKUSR:
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 3c36c2d16148..1043fdc2df7f 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -153,7 +153,6 @@ static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
153 153
154long arch_ptrace(struct task_struct *child, long request, long addr, long data) 154long arch_ptrace(struct task_struct *child, long request, long addr, long data)
155{ 155{
156 unsigned long tmp;
157 int ret; 156 int ret;
158 157
159 pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n", 158 pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
@@ -166,11 +165,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
166 /* Read the word at location addr in the child process */ 165 /* Read the word at location addr in the child process */
167 case PTRACE_PEEKTEXT: 166 case PTRACE_PEEKTEXT:
168 case PTRACE_PEEKDATA: 167 case PTRACE_PEEKDATA:
169 ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 168 ret = generic_ptrace_peekdata(child, addr, data);
170 if (ret == sizeof(tmp))
171 ret = put_user(tmp, (unsigned long __user *)data);
172 else
173 ret = -EIO;
174 break; 169 break;
175 170
176 case PTRACE_PEEKUSR: 171 case PTRACE_PEEKUSR:
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index fd2129a04586..74b1b4dc8225 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -83,19 +83,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
83 switch (request) { 83 switch (request) {
84 /* Read word at location address. */ 84 /* Read word at location address. */
85 case PTRACE_PEEKTEXT: 85 case PTRACE_PEEKTEXT:
86 case PTRACE_PEEKDATA: { 86 case PTRACE_PEEKDATA:
87 unsigned long tmp; 87 ret = generic_ptrace_peekdata(child, addr, data);
88 int copied;
89
90 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
91 ret = -EIO;
92
93 if (copied != sizeof(tmp))
94 break;
95
96 ret = put_user(tmp,datap);
97 break; 88 break;
98 }
99 89
100 /* Read the word at location address in the USER area. */ 90 /* Read the word at location address in the USER area. */
101 case PTRACE_PEEKUSR: { 91 case PTRACE_PEEKUSR: {
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index ce88fb95ee59..a10f3092fad4 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -112,20 +112,12 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
112 switch (request) { 112 switch (request) {
113 /* when I and D space are separate, these will need to be fixed. */ 113 /* when I and D space are separate, these will need to be fixed. */
114 case PTRACE_PEEKTEXT: /* read word at location addr. */ 114 case PTRACE_PEEKTEXT: /* read word at location addr. */
115 case PTRACE_PEEKDATA: { 115 case PTRACE_PEEKDATA:
116 int copied;
117
118 ret = -EIO; 116 ret = -EIO;
119 if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) 117 if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
120 break; 118 break;
121 119 ret = generic_ptrace_peekdata(child, addr, data);
122 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
123 if (copied != sizeof(tmp))
124 break;
125
126 ret = put_user(tmp,(unsigned long *) data);
127 break; 120 break;
128 }
129 121
130 /* read the word at location addr in the USER area. */ 122 /* read the word at location addr in the USER area. */
131 case PTRACE_PEEKUSR: { 123 case PTRACE_PEEKUSR: {
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 0c0ceec5de00..f4bcf1da662a 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -358,17 +358,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
358 switch (request) { 358 switch (request) {
359 /* when I and D space are separate, these will need to be fixed. */ 359 /* when I and D space are separate, these will need to be fixed. */
360 case PTRACE_PEEKTEXT: /* read word at location addr. */ 360 case PTRACE_PEEKTEXT: /* read word at location addr. */
361 case PTRACE_PEEKDATA: { 361 case PTRACE_PEEKDATA:
362 unsigned long tmp; 362 ret = generic_ptrace_peekdata(child, addr, data);
363 int copied;
364
365 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
366 ret = -EIO;
367 if (copied != sizeof(tmp))
368 break;
369 ret = put_user(tmp, datap);
370 break; 363 break;
371 }
372 364
373 /* read the word at location addr in the USER area. */ 365 /* read the word at location addr in the USER area. */
374 case PTRACE_PEEKUSR: { 366 case PTRACE_PEEKUSR: {
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 5f02b3144875..01a1c9ac8458 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -595,7 +595,6 @@ void ptrace_disable(struct task_struct *child)
595static int 595static int
596do_ptrace(long request, struct task_struct *child, long addr, long data) 596do_ptrace(long request, struct task_struct *child, long addr, long data)
597{ 597{
598 unsigned long tmp;
599 int ret; 598 int ret;
600 599
601 switch (request) { 600 switch (request) {
@@ -604,11 +603,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
604 */ 603 */
605 case PTRACE_PEEKTEXT: 604 case PTRACE_PEEKTEXT:
606 case PTRACE_PEEKDATA: 605 case PTRACE_PEEKDATA:
607 ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 606 ret = generic_ptrace_peekdata(child, addr, data);
608 if (ret == sizeof(tmp))
609 ret = put_user(tmp,(unsigned long __user *) data);
610 else
611 ret = -EIO;
612 break; 607 break;
613 608
614 /* 609 /*
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index cdba9fd6d82f..01a3a09c53d9 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -128,10 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
128 /* when I and D space are separate, these will need to be fixed. */ 128 /* when I and D space are separate, these will need to be fixed. */
129 case PTRACE_PEEKTEXT: /* read word at location addr. */ 129 case PTRACE_PEEKTEXT: /* read word at location addr. */
130 case PTRACE_PEEKDATA: 130 case PTRACE_PEEKDATA:
131 i = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 131 ret = generic_ptrace_peekdata(child, addr, data);
132 if (i != sizeof(tmp))
133 goto out_eio;
134 ret = put_user(tmp, (unsigned long *)data);
135 break; 132 break;
136 133
137 /* read the word at location addr in the USER area. */ 134 /* read the word at location addr in the USER area. */
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index f54b6a3dfecb..f550e614aa78 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -106,17 +106,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
106 switch (request) { 106 switch (request) {
107 /* when I and D space are separate, these will need to be fixed. */ 107 /* when I and D space are separate, these will need to be fixed. */
108 case PTRACE_PEEKTEXT: /* read word at location addr. */ 108 case PTRACE_PEEKTEXT: /* read word at location addr. */
109 case PTRACE_PEEKDATA: { 109 case PTRACE_PEEKDATA:
110 unsigned long tmp; 110 ret = generic_ptrace_peekdata(child, addr, data);
111 int copied;
112
113 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
114 ret = -EIO;
115 if (copied != sizeof(tmp))
116 break;
117 ret = put_user(tmp,(unsigned long *) data);
118 break; 111 break;
119 }
120 112
121 /* read the word at location addr in the USER area. */ 113 /* read the word at location addr in the USER area. */
122 case PTRACE_PEEKUSR: { 114 case PTRACE_PEEKUSR: {
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index b5a7b46bbc49..af9d0bec8731 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -174,17 +174,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
174 switch (request) { 174 switch (request) {
175 /* when I and D space are separate, these will need to be fixed. */ 175 /* when I and D space are separate, these will need to be fixed. */
176 case PTRACE_PEEKTEXT: /* read word at location addr. */ 176 case PTRACE_PEEKTEXT: /* read word at location addr. */
177 case PTRACE_PEEKDATA: { 177 case PTRACE_PEEKDATA:
178 unsigned long tmp; 178 ret = generic_ptrace_peekdata(child, addr, data);
179 int copied;
180
181 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
182 ret = -EIO;
183 if (copied != sizeof(tmp))
184 break;
185 ret = put_user(tmp,(unsigned long __user *) data);
186 break; 179 break;
187 }
188 180
189 /* Read the word at location addr in the USER area. */ 181 /* Read the word at location addr in the USER area. */
190 case PTRACE_PEEKUSR: { 182 case PTRACE_PEEKUSR: {
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 8a0db376e91e..26ec774c5027 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -87,10 +87,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
87 switch (request) { 87 switch (request) {
88 case PTRACE_PEEKTEXT: /* read word at location addr. */ 88 case PTRACE_PEEKTEXT: /* read word at location addr. */
89 case PTRACE_PEEKDATA: { 89 case PTRACE_PEEKDATA: {
90 int copied;
91
92#ifdef CONFIG_64BIT 90#ifdef CONFIG_64BIT
93 if (__is_compat_task(child)) { 91 if (__is_compat_task(child)) {
92 int copied;
94 unsigned int tmp; 93 unsigned int tmp;
95 94
96 addr &= 0xffffffffL; 95 addr &= 0xffffffffL;
@@ -105,15 +104,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
105 } 104 }
106 else 105 else
107#endif 106#endif
108 { 107 ret = generic_ptrace_peekdata(child, addr, data);
109 unsigned long tmp;
110
111 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
112 ret = -EIO;
113 if (copied != sizeof(tmp))
114 goto out_tsk;
115 ret = put_user(tmp,(unsigned long *) data);
116 }
117 goto out_tsk; 108 goto out_tsk;
118 } 109 }
119 110
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 0fb53950da43..581d427148e7 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -379,17 +379,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
379 switch (request) { 379 switch (request) {
380 /* when I and D space are separate, these will need to be fixed. */ 380 /* when I and D space are separate, these will need to be fixed. */
381 case PTRACE_PEEKTEXT: /* read word at location addr. */ 381 case PTRACE_PEEKTEXT: /* read word at location addr. */
382 case PTRACE_PEEKDATA: { 382 case PTRACE_PEEKDATA:
383 unsigned long tmp; 383 ret = generic_ptrace_peekdata(child, addr, data);
384 int copied;
385
386 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
387 ret = -EIO;
388 if (copied != sizeof(tmp))
389 break;
390 ret = put_user(tmp,(unsigned long __user *) data);
391 break; 384 break;
392 }
393 385
394 /* read the word at location addr in the USER area. */ 386 /* read the word at location addr in the USER area. */
395 case PTRACE_PEEKUSR: { 387 case PTRACE_PEEKUSR: {
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 2a8f0872ea8b..28afff4e5d1b 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -294,7 +294,6 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
294static int 294static int
295do_ptrace_normal(struct task_struct *child, long request, long addr, long data) 295do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
296{ 296{
297 unsigned long tmp;
298 ptrace_area parea; 297 ptrace_area parea;
299 int copied, ret; 298 int copied, ret;
300 299
@@ -304,10 +303,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
304 /* Remove high order bit from address (only for 31 bit). */ 303 /* Remove high order bit from address (only for 31 bit). */
305 addr &= PSW_ADDR_INSN; 304 addr &= PSW_ADDR_INSN;
306 /* read word at location addr. */ 305 /* read word at location addr. */
307 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 306 return generic_ptrace_peekdata(child, addr, data);
308 if (copied != sizeof(tmp))
309 return -EIO;
310 return put_user(tmp, (unsigned long __force __user *) data);
311 307
312 case PTRACE_PEEKUSR: 308 case PTRACE_PEEKUSR:
313 /* read the word at location addr in the USER area. */ 309 /* read the word at location addr in the USER area. */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index f2eaa485d04d..f23f949576a5 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -91,17 +91,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
91 switch (request) { 91 switch (request) {
92 /* when I and D space are separate, these will need to be fixed. */ 92 /* when I and D space are separate, these will need to be fixed. */
93 case PTRACE_PEEKTEXT: /* read word at location addr. */ 93 case PTRACE_PEEKTEXT: /* read word at location addr. */
94 case PTRACE_PEEKDATA: { 94 case PTRACE_PEEKDATA:
95 unsigned long tmp; 95 ret = generic_ptrace_peekdata(child, addr, data);
96 int copied;
97
98 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
99 ret = -EIO;
100 if (copied != sizeof(tmp))
101 break;
102 ret = put_user(tmp,(unsigned long __user *) data);
103 break;
104 }
105 96
106 /* read the word at location addr in the USER area. */ 97 /* read the word at location addr in the USER area. */
107 case PTRACE_PEEKUSR: { 98 case PTRACE_PEEKUSR: {
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 4e95e18b46d9..12340e499bfb 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -129,17 +129,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
129 switch (request) { 129 switch (request) {
130 /* when I and D space are separate, these will need to be fixed. */ 130 /* when I and D space are separate, these will need to be fixed. */
131 case PTRACE_PEEKTEXT: /* read word at location addr. */ 131 case PTRACE_PEEKTEXT: /* read word at location addr. */
132 case PTRACE_PEEKDATA: { 132 case PTRACE_PEEKDATA:
133 unsigned long tmp; 133 ret = generic_ptrace_peekdata(child, addr, data);
134 int copied;
135
136 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
137 ret = -EIO;
138 if (copied != sizeof(tmp))
139 break;
140 ret = put_user(tmp,(unsigned long *) data);
141 break; 134 break;
142 }
143 135
144 /* read the word at location addr in the USER area. */ 136 /* read the word at location addr in the USER area. */
145 case PTRACE_PEEKUSR: { 137 case PTRACE_PEEKUSR: {
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 627742d89434..1966da6eb363 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -52,17 +52,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
52 switch (request) { 52 switch (request) {
53 /* when I and D space are separate, these will need to be fixed. */ 53 /* when I and D space are separate, these will need to be fixed. */
54 case PTRACE_PEEKTEXT: /* read word at location addr. */ 54 case PTRACE_PEEKTEXT: /* read word at location addr. */
55 case PTRACE_PEEKDATA: { 55 case PTRACE_PEEKDATA:
56 unsigned long tmp; 56 ret = generic_ptrace_peekdata(child, addr, data);
57 int copied;
58
59 ret = -EIO;
60 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
61 if (copied != sizeof(tmp))
62 break;
63 ret = put_user(tmp, p);
64 break; 57 break;
65 }
66 58
67 /* read the word at location addr in the USER area. */ 59 /* read the word at location addr in the USER area. */
68 case PTRACE_PEEKUSR: 60 case PTRACE_PEEKUSR:
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index a9b09343097d..3bedd144e52d 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -117,15 +117,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
117 int rval; 117 int rval;
118 118
119 switch (request) { 119 switch (request) {
120 unsigned long val, copied; 120 unsigned long val;
121 121
122 case PTRACE_PEEKTEXT: /* read word at location addr. */ 122 case PTRACE_PEEKTEXT: /* read word at location addr. */
123 case PTRACE_PEEKDATA: 123 case PTRACE_PEEKDATA:
124 copied = access_process_vm(child, addr, &val, sizeof(val), 0); 124 rval = generic_ptrace_peekdata(child, addr, data);
125 rval = -EIO;
126 if (copied != sizeof(val))
127 break;
128 rval = put_user(val, (unsigned long *)data);
129 goto out; 125 goto out;
130 126
131 case PTRACE_POKETEXT: /* write the word at location addr. */ 127 case PTRACE_POKETEXT: /* write the word at location addr. */
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 9409117b9f19..327ff93a38b6 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -313,17 +313,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
313 switch (request) { 313 switch (request) {
314 /* when I and D space are separate, these will need to be fixed. */ 314 /* when I and D space are separate, these will need to be fixed. */
315 case PTRACE_PEEKTEXT: /* read word at location addr. */ 315 case PTRACE_PEEKTEXT: /* read word at location addr. */
316 case PTRACE_PEEKDATA: { 316 case PTRACE_PEEKDATA:
317 unsigned long tmp; 317 ret = generic_ptrace_peekdata(child, addr, data);
318 int copied;
319
320 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
321 ret = -EIO;
322 if (copied != sizeof(tmp))
323 break;
324 ret = put_user(tmp,(unsigned long __user *) data);
325 break; 318 break;
326 }
327 319
328 /* read the word at location addr in the USER area. */ 320 /* read the word at location addr in the USER area. */
329 case PTRACE_PEEKUSR: { 321 case PTRACE_PEEKUSR: {
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 14104ff63093..af182d3a7000 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -50,18 +50,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
50 switch (request) { 50 switch (request) {
51 case PTRACE_PEEKTEXT: /* read word at location addr. */ 51 case PTRACE_PEEKTEXT: /* read word at location addr. */
52 case PTRACE_PEEKDATA: 52 case PTRACE_PEEKDATA:
53 { 53 ret = generic_ptrace_peekdata(child, addr, data);
54 unsigned long tmp;
55 int copied;
56
57 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
58 ret = -EIO;
59 if (copied != sizeof(tmp))
60 break;
61 ret = put_user(tmp,(unsigned long *) data);
62
63 goto out; 54 goto out;
64 }
65 55
66 /* Read the word at location addr in the USER area. */ 56 /* Read the word at location addr in the USER area. */
67 57
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index eeb1976ef7bf..477cc8ed6bcb 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -110,6 +110,7 @@ static inline void ptrace_unlink(struct task_struct *child)
110 __ptrace_unlink(child); 110 __ptrace_unlink(child);
111} 111}
112 112
113int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
113 114
114#ifndef force_successful_syscall_return 115#ifndef force_successful_syscall_return
115/* 116/*
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index b1d11f1c7cf7..1653d35419a1 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -490,3 +490,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
490 return ret; 490 return ret;
491} 491}
492#endif /* __ARCH_SYS_PTRACE */ 492#endif /* __ARCH_SYS_PTRACE */
493
494int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
495{
496 unsigned long tmp;
497 int copied;
498
499 copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
500 if (copied != sizeof(tmp))
501 return -EIO;
502 return put_user(tmp, (unsigned long __user *)data);
503}