aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2007-07-17 07:03:44 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:03 -0400
commitf284ce7269031947326bac6bb19a977705276222 (patch)
tree8b145d42d4da182fb185dacc53b24ca7a2546114
parent7664732315c97f48dba9d1e7339ad16fc5a320ac (diff)
PTRACE_POKEDATA consolidation
Identical implementations of PTRACE_POKEDATA go into generic_ptrace_pokedata() function. AFAICS, fix bug on xtensa where successful PTRACE_POKEDATA will nevertheless return EPERM. 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/alpha/kernel/ptrace.c4
-rw-r--r--arch/arm/kernel/ptrace.c7
-rw-r--r--arch/arm26/kernel/ptrace.c7
-rw-r--r--arch/avr32/kernel/ptrace.c6
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c7
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c7
-rw-r--r--arch/frv/kernel/ptrace.c4
-rw-r--r--arch/h8300/kernel/ptrace.c5
-rw-r--r--arch/i386/kernel/ptrace.c5
-rw-r--r--arch/m32r/kernel/ptrace.c12
-rw-r--r--arch/m68k/kernel/ptrace.c3
-rw-r--r--arch/m68knommu/kernel/ptrace.c5
-rw-r--r--arch/mips/kernel/ptrace.c6
-rw-r--r--arch/powerpc/kernel/ptrace.c6
-rw-r--r--arch/s390/kernel/ptrace.c5
-rw-r--r--arch/sh/kernel/ptrace.c5
-rw-r--r--arch/sh64/kernel/ptrace.c5
-rw-r--r--arch/um/kernel/ptrace.c6
-rw-r--r--arch/v850/kernel/ptrace.c6
-rw-r--r--arch/x86_64/kernel/ptrace.c5
-rw-r--r--arch/xtensa/kernel/ptrace.c5
-rw-r--r--include/linux/ptrace.h1
-rw-r--r--kernel/ptrace.c8
23 files changed, 32 insertions, 98 deletions
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 0cd060598f9a..83a781842266 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -315,9 +315,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
315 /* When I and D space are separate, this will have to be fixed. */ 315 /* When I and D space are separate, this will have to be fixed. */
316 case PTRACE_POKETEXT: /* write the word at location addr. */ 316 case PTRACE_POKETEXT: /* write the word at location addr. */
317 case PTRACE_POKEDATA: 317 case PTRACE_POKEDATA:
318 tmp = data; 318 ret = generic_ptrace_pokedata(child, addr, data);
319 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
320 ret = (copied == sizeof(tmp)) ? 0 : -EIO;
321 break; 319 break;
322 320
323 case PTRACE_POKEUSR: /* write the specified register */ 321 case PTRACE_POKEUSR: /* write the specified register */
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9a5d9754c2a2..78c9f1a3d41f 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -677,12 +677,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
677 */ 677 */
678 case PTRACE_POKETEXT: 678 case PTRACE_POKETEXT:
679 case PTRACE_POKEDATA: 679 case PTRACE_POKEDATA:
680 ret = access_process_vm(child, addr, &data, 680 ret = generic_ptrace_pokedata(child, addr, data);
681 sizeof(unsigned long), 1);
682 if (ret == sizeof(unsigned long))
683 ret = 0;
684 else
685 ret = -EIO;
686 break; 681 break;
687 682
688 case PTRACE_POKEUSR: 683 case PTRACE_POKEUSR:
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 0d0ead0e0a74..0fefb86970c6 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -551,12 +551,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
551 */ 551 */
552 case PTRACE_POKETEXT: 552 case PTRACE_POKETEXT:
553 case PTRACE_POKEDATA: 553 case PTRACE_POKEDATA:
554 ret = access_process_vm(child, addr, &data, 554 ret = generic_ptrace_pokedata(child, addr, data);
555 sizeof(unsigned long), 1);
556 if (ret == sizeof(unsigned long))
557 ret = 0;
558 else
559 ret = -EIO;
560 break; 555 break;
561 556
562 case PTRACE_POKEUSR: 557 case PTRACE_POKEUSR:
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 1043fdc2df7f..39060cbeb2a3 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -176,11 +176,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
176 /* Write the word in data at location addr */ 176 /* Write the word in data at location addr */
177 case PTRACE_POKETEXT: 177 case PTRACE_POKETEXT:
178 case PTRACE_POKEDATA: 178 case PTRACE_POKEDATA:
179 ret = access_process_vm(child, addr, &data, sizeof(data), 1); 179 ret = generic_ptrace_pokedata(child, addr, data);
180 if (ret == sizeof(data))
181 ret = 0;
182 else
183 ret = -EIO;
184 break; 180 break;
185 181
186 case PTRACE_POKEUSR: 182 case PTRACE_POKEUSR:
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 74b1b4dc8225..f4f9db698b44 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -103,12 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
103 /* Write the word at location address. */ 103 /* Write the word at location address. */
104 case PTRACE_POKETEXT: 104 case PTRACE_POKETEXT:
105 case PTRACE_POKEDATA: 105 case PTRACE_POKEDATA:
106 ret = 0; 106 ret = generic_ptrace_pokedata(child, addr, data);
107
108 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
109 break;
110
111 ret = -EIO;
112 break; 107 break;
113 108
114 /* Write the word at location address in the USER area. */ 109 /* Write the word at location address in the USER area. */
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index d4d57b741334..38ece0cd47cb 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -146,12 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
146 /* Write the word at location address. */ 146 /* Write the word at location address. */
147 case PTRACE_POKETEXT: 147 case PTRACE_POKETEXT:
148 case PTRACE_POKEDATA: 148 case PTRACE_POKEDATA:
149 ret = 0; 149 ret = generic_ptrace_pokedata(child, addr, data);
150
151 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
152 break;
153
154 ret = -EIO;
155 break; 150 break;
156 151
157 /* Write the word at location address in the USER area. */ 152 /* Write the word at location address in the USER area. */
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index a10f3092fad4..709e9bdc6126 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -168,9 +168,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
168 ret = -EIO; 168 ret = -EIO;
169 if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) 169 if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
170 break; 170 break;
171 if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data)) 171 ret = generic_ptrace_pokedata(child, addr, data);
172 break;
173 ret = 0;
174 break; 172 break;
175 173
176 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 174 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index 8a7a991b8f76..d32bbf02fc48 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -111,10 +111,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
111 /* when I and D space are separate, this will have to be fixed. */ 111 /* when I and D space are separate, this will have to be fixed. */
112 case PTRACE_POKETEXT: /* write the word at location addr. */ 112 case PTRACE_POKETEXT: /* write the word at location addr. */
113 case PTRACE_POKEDATA: 113 case PTRACE_POKEDATA:
114 ret = 0; 114 ret = generic_ptrace_pokedata(child, addr, data);
115 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
116 break;
117 ret = -EIO;
118 break; 115 break;
119 116
120 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 117 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index f4bcf1da662a..1c075f58d1f9 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -387,10 +387,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
387 /* when I and D space are separate, this will have to be fixed. */ 387 /* when I and D space are separate, this will have to be fixed. */
388 case PTRACE_POKETEXT: /* write the word at location addr. */ 388 case PTRACE_POKETEXT: /* write the word at location addr. */
389 case PTRACE_POKEDATA: 389 case PTRACE_POKEDATA:
390 ret = 0; 390 ret = generic_ptrace_pokedata(child, addr, data);
391 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
392 break;
393 ret = -EIO;
394 break; 391 break;
395 392
396 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 393 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 01a1c9ac8458..57a92ef31a90 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -619,15 +619,9 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
619 */ 619 */
620 case PTRACE_POKETEXT: 620 case PTRACE_POKETEXT:
621 case PTRACE_POKEDATA: 621 case PTRACE_POKEDATA:
622 ret = access_process_vm(child, addr, &data, sizeof(data), 1); 622 ret = generic_ptrace_pokedata(child, addr, data);
623 if (ret == sizeof(data)) { 623 if (ret == 0 && request == PTRACE_POKETEXT)
624 ret = 0; 624 invalidate_cache();
625 if (request == PTRACE_POKETEXT) {
626 invalidate_cache();
627 }
628 } else {
629 ret = -EIO;
630 }
631 break; 625 break;
632 626
633 /* 627 /*
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 01a3a09c53d9..2cf0690b7882 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -157,8 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
157 /* when I and D space are separate, this will have to be fixed. */ 157 /* when I and D space are separate, this will have to be fixed. */
158 case PTRACE_POKETEXT: /* write the word at location addr. */ 158 case PTRACE_POKETEXT: /* write the word at location addr. */
159 case PTRACE_POKEDATA: 159 case PTRACE_POKEDATA:
160 if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data)) 160 ret = generic_ptrace_pokedata(child, addr, data);
161 goto out_eio;
162 break; 161 break;
163 162
164 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 163 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index f550e614aa78..ef70ca070ce2 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -151,10 +151,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
151 /* when I and D space are separate, this will have to be fixed. */ 151 /* when I and D space are separate, this will have to be fixed. */
152 case PTRACE_POKETEXT: /* write the word at location addr. */ 152 case PTRACE_POKETEXT: /* write the word at location addr. */
153 case PTRACE_POKEDATA: 153 case PTRACE_POKEDATA:
154 ret = 0; 154 ret = generic_ptrace_pokedata(child, addr, data);
155 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
156 break;
157 ret = -EIO;
158 break; 155 break;
159 156
160 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 157 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index af9d0bec8731..893e7bccf226 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -305,11 +305,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
305 /* when I and D space are separate, this will have to be fixed. */ 305 /* when I and D space are separate, this will have to be fixed. */
306 case PTRACE_POKETEXT: /* write the word at location addr. */ 306 case PTRACE_POKETEXT: /* write the word at location addr. */
307 case PTRACE_POKEDATA: 307 case PTRACE_POKEDATA:
308 ret = 0; 308 ret = generic_ptrace_pokedata(child, addr, data);
309 if (access_process_vm(child, addr, &data, sizeof(data), 1)
310 == sizeof(data))
311 break;
312 ret = -EIO;
313 break; 309 break;
314 310
315 case PTRACE_POKEUSR: { 311 case PTRACE_POKEUSR: {
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 581d427148e7..8a177bd9eab4 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -413,11 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
413 /* If I and D space are separate, this will have to be fixed. */ 413 /* If I and D space are separate, this will have to be fixed. */
414 case PTRACE_POKETEXT: /* write the word at location addr. */ 414 case PTRACE_POKETEXT: /* write the word at location addr. */
415 case PTRACE_POKEDATA: 415 case PTRACE_POKEDATA:
416 ret = 0; 416 ret = generic_ptrace_pokedata(child, addr, data);
417 if (access_process_vm(child, addr, &data, sizeof(data), 1)
418 == sizeof(data))
419 break;
420 ret = -EIO;
421 break; 417 break;
422 418
423 /* write the word at location addr in the USER area */ 419 /* write the word at location addr in the USER area */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 28afff4e5d1b..f4503ca27630 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -314,10 +314,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
314 /* Remove high order bit from address (only for 31 bit). */ 314 /* Remove high order bit from address (only for 31 bit). */
315 addr &= PSW_ADDR_INSN; 315 addr &= PSW_ADDR_INSN;
316 /* write the word at location addr. */ 316 /* write the word at location addr. */
317 copied = access_process_vm(child, addr, &data, sizeof(data),1); 317 return generic_ptrace_pokedata(child, addr, data);
318 if (copied != sizeof(data))
319 return -EIO;
320 return 0;
321 318
322 case PTRACE_POKEUSR: 319 case PTRACE_POKEUSR:
323 /* write the word at location addr in the USER area */ 320 /* write the word at location addr in the USER area */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index f23f949576a5..891d1d46c902 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -126,10 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
126 /* when I and D space are separate, this will have to be fixed. */ 126 /* when I and D space are separate, this will have to be fixed. */
127 case PTRACE_POKETEXT: /* write the word at location addr. */ 127 case PTRACE_POKETEXT: /* write the word at location addr. */
128 case PTRACE_POKEDATA: 128 case PTRACE_POKEDATA:
129 ret = 0; 129 ret = generic_ptrace_pokedata(child, addr, data);
130 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
131 break;
132 ret = -EIO;
133 break; 130 break;
134 131
135 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 132 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 12340e499bfb..df06c6477468 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -158,10 +158,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
158 /* when I and D space are separate, this will have to be fixed. */ 158 /* when I and D space are separate, this will have to be fixed. */
159 case PTRACE_POKETEXT: /* write the word at location addr. */ 159 case PTRACE_POKETEXT: /* write the word at location addr. */
160 case PTRACE_POKEDATA: 160 case PTRACE_POKEDATA:
161 ret = 0; 161 ret = generic_ptrace_pokedata(child, addr, data);
162 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
163 break;
164 ret = -EIO;
165 break; 162 break;
166 163
167 case PTRACE_POKEUSR: 164 case PTRACE_POKEUSR:
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 1966da6eb363..6916c8888dba 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -64,11 +64,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
64 /* when I and D space are separate, this will have to be fixed. */ 64 /* when I and D space are separate, this will have to be fixed. */
65 case PTRACE_POKETEXT: /* write the word at location addr. */ 65 case PTRACE_POKETEXT: /* write the word at location addr. */
66 case PTRACE_POKEDATA: 66 case PTRACE_POKEDATA:
67 ret = -EIO; 67 ret = generic_ptrace_pokedata(child, addr, data);
68 if (access_process_vm(child, addr, &data, sizeof(data),
69 1) != sizeof(data))
70 break;
71 ret = 0;
72 break; 68 break;
73 69
74 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 70 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 3bedd144e52d..a458ac941b25 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -126,11 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
126 126
127 case PTRACE_POKETEXT: /* write the word at location addr. */ 127 case PTRACE_POKETEXT: /* write the word at location addr. */
128 case PTRACE_POKEDATA: 128 case PTRACE_POKEDATA:
129 rval = 0; 129 rval = generic_ptrace_pokedata(child, addr, data);
130 if (access_process_vm(child, addr, &data, sizeof(data), 1)
131 == sizeof(data))
132 break;
133 rval = -EIO;
134 goto out; 130 goto out;
135 131
136 /* Read/write the word at location ADDR in the registers. */ 132 /* Read/write the word at location ADDR in the registers. */
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 327ff93a38b6..fa6775ef729f 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -359,10 +359,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
359 /* when I and D space are separate, this will have to be fixed. */ 359 /* when I and D space are separate, this will have to be fixed. */
360 case PTRACE_POKETEXT: /* write the word at location addr. */ 360 case PTRACE_POKETEXT: /* write the word at location addr. */
361 case PTRACE_POKEDATA: 361 case PTRACE_POKEDATA:
362 ret = 0; 362 ret = generic_ptrace_pokedata(child, addr, data);
363 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
364 break;
365 ret = -EIO;
366 break; 363 break;
367 364
368 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 365 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index af182d3a7000..06a13d9b69db 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -128,10 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
128 128
129 case PTRACE_POKETEXT: /* write the word at location addr. */ 129 case PTRACE_POKETEXT: /* write the word at location addr. */
130 case PTRACE_POKEDATA: 130 case PTRACE_POKEDATA:
131 if (access_process_vm(child, addr, &data, sizeof(data), 1) 131 ret = generic_ptrace_pokedata(child, addr, data);
132 == sizeof(data))
133 break;
134 ret = -EIO;
135 goto out; 132 goto out;
136 133
137 case PTRACE_POKEUSR: 134 case PTRACE_POKEUSR:
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 477cc8ed6bcb..ae8146abd746 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -111,6 +111,7 @@ static inline void ptrace_unlink(struct task_struct *child)
111} 111}
112 112
113int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); 113int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
114int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
114 115
115#ifndef force_successful_syscall_return 116#ifndef force_successful_syscall_return
116/* 117/*
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 1653d35419a1..4a1745f1dadf 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -501,3 +501,11 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
501 return -EIO; 501 return -EIO;
502 return put_user(tmp, (unsigned long __user *)data); 502 return put_user(tmp, (unsigned long __user *)data);
503} 503}
504
505int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
506{
507 int copied;
508
509 copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
510 return (copied == sizeof(data)) ? 0 : -EIO;
511}