aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ptrace_32.c')
-rw-r--r--arch/x86/kernel/ptrace_32.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 26071305de2c..fed83d066135 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -133,19 +133,39 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
133 */ 133 */
134static unsigned long ptrace_get_debugreg(struct task_struct *child, int n) 134static unsigned long ptrace_get_debugreg(struct task_struct *child, int n)
135{ 135{
136 return child->thread.debugreg[n]; 136 switch (n) {
137 case 0: return child->thread.debugreg0;
138 case 1: return child->thread.debugreg1;
139 case 2: return child->thread.debugreg2;
140 case 3: return child->thread.debugreg3;
141 case 6: return child->thread.debugreg6;
142 case 7: return child->thread.debugreg7;
143 }
144 return 0;
137} 145}
138 146
139static int ptrace_set_debugreg(struct task_struct *child, 147static int ptrace_set_debugreg(struct task_struct *child,
140 int n, unsigned long data) 148 int n, unsigned long data)
141{ 149{
150 int i;
151
142 if (unlikely(n == 4 || n == 5)) 152 if (unlikely(n == 4 || n == 5))
143 return -EIO; 153 return -EIO;
144 154
145 if (n < 4 && unlikely(data >= TASK_SIZE - 3)) 155 if (n < 4 && unlikely(data >= TASK_SIZE - 3))
146 return -EIO; 156 return -EIO;
147 157
148 if (n == 7) { 158 switch (n) {
159 case 0: child->thread.debugreg0 = data; break;
160 case 1: child->thread.debugreg1 = data; break;
161 case 2: child->thread.debugreg2 = data; break;
162 case 3: child->thread.debugreg3 = data; break;
163
164 case 6:
165 child->thread.debugreg6 = data;
166 break;
167
168 case 7:
149 /* 169 /*
150 * Sanity-check data. Take one half-byte at once with 170 * Sanity-check data. Take one half-byte at once with
151 * check = (val >> (16 + 4*i)) & 0xf. It contains the 171 * check = (val >> (16 + 4*i)) & 0xf. It contains the
@@ -176,19 +196,18 @@ static int ptrace_set_debugreg(struct task_struct *child,
176 * 64-bit kernel), so the x86_64 mask value is 0x5454. 196 * 64-bit kernel), so the x86_64 mask value is 0x5454.
177 * See the AMD manual no. 24593 (AMD64 System Programming) 197 * See the AMD manual no. 24593 (AMD64 System Programming)
178 */ 198 */
179 int i;
180 data &= ~DR_CONTROL_RESERVED; 199 data &= ~DR_CONTROL_RESERVED;
181 for (i = 0; i < 4; i++) 200 for (i = 0; i < 4; i++)
182 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1) 201 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
183 return -EIO; 202 return -EIO;
203 child->thread.debugreg7 = data;
184 if (data) 204 if (data)
185 set_tsk_thread_flag(child, TIF_DEBUG); 205 set_tsk_thread_flag(child, TIF_DEBUG);
186 else 206 else
187 clear_tsk_thread_flag(child, TIF_DEBUG); 207 clear_tsk_thread_flag(child, TIF_DEBUG);
208 break;
188 } 209 }
189 210
190 child->thread.debugreg[n] = data;
191
192 return 0; 211 return 0;
193} 212}
194 213