diff options
Diffstat (limited to 'arch/x86/kernel/ptrace_32.c')
-rw-r--r-- | arch/x86/kernel/ptrace_32.c | 29 |
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 | */ |
134 | static unsigned long ptrace_get_debugreg(struct task_struct *child, int n) | 134 | static 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 | ||
139 | static int ptrace_set_debugreg(struct task_struct *child, | 147 | static 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 | ||