diff options
Diffstat (limited to 'arch/x86/kernel/step.c')
-rw-r--r-- | arch/x86/kernel/step.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 7beba0769a8c..58de45ee08b6 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c | |||
@@ -169,9 +169,19 @@ static void enable_step(struct task_struct *child, bool block) | |||
169 | * So noone should try to use debugger block stepping in a program | 169 | * So noone should try to use debugger block stepping in a program |
170 | * that uses user-mode single stepping itself. | 170 | * that uses user-mode single stepping itself. |
171 | */ | 171 | */ |
172 | if (!enable_single_step(child)) | 172 | if (enable_single_step(child) && block) { |
173 | return; | 173 | unsigned long debugctl = get_debugctlmsr(); |
174 | /* XXX */ | 174 | |
175 | debugctl |= DEBUGCTLMSR_BTF; | ||
176 | update_debugctlmsr(debugctl); | ||
177 | set_tsk_thread_flag(child, TIF_BLOCKSTEP); | ||
178 | } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { | ||
179 | unsigned long debugctl = get_debugctlmsr(); | ||
180 | |||
181 | debugctl &= ~DEBUGCTLMSR_BTF; | ||
182 | update_debugctlmsr(debugctl); | ||
183 | clear_tsk_thread_flag(child, TIF_BLOCKSTEP); | ||
184 | } | ||
175 | } | 185 | } |
176 | 186 | ||
177 | void user_enable_single_step(struct task_struct *child) | 187 | void user_enable_single_step(struct task_struct *child) |
@@ -189,7 +199,13 @@ void user_disable_single_step(struct task_struct *child) | |||
189 | /* | 199 | /* |
190 | * Make sure block stepping (BTF) is disabled. | 200 | * Make sure block stepping (BTF) is disabled. |
191 | */ | 201 | */ |
192 | /* XXX */ | 202 | if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { |
203 | unsigned long debugctl = get_debugctlmsr(); | ||
204 | |||
205 | debugctl &= ~DEBUGCTLMSR_BTF; | ||
206 | update_debugctlmsr(debugctl); | ||
207 | clear_tsk_thread_flag(child, TIF_BLOCKSTEP); | ||
208 | } | ||
193 | 209 | ||
194 | /* Always clear TIF_SINGLESTEP... */ | 210 | /* Always clear TIF_SINGLESTEP... */ |
195 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | 211 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); |