|
@@ -157,6 +157,21 @@ static int enable_single_step(struct task_struct *child)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static void set_task_blockstep(struct task_struct *task, bool on)
|
|
|
+{
|
|
|
+ unsigned long debugctl;
|
|
|
+
|
|
|
+ debugctl = get_debugctlmsr();
|
|
|
+ if (on) {
|
|
|
+ debugctl |= DEBUGCTLMSR_BTF;
|
|
|
+ set_tsk_thread_flag(task, TIF_BLOCKSTEP);
|
|
|
+ } else {
|
|
|
+ debugctl &= ~DEBUGCTLMSR_BTF;
|
|
|
+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
|
|
|
+ }
|
|
|
+ update_debugctlmsr(debugctl);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Enable single or block step.
|
|
|
*/
|
|
@@ -169,19 +184,10 @@ static void enable_step(struct task_struct *child, bool block)
|
|
|
* So no one should try to use debugger block stepping in a program
|
|
|
* that uses user-mode single stepping itself.
|
|
|
*/
|
|
|
- if (enable_single_step(child) && block) {
|
|
|
- unsigned long debugctl = get_debugctlmsr();
|
|
|
-
|
|
|
- debugctl |= DEBUGCTLMSR_BTF;
|
|
|
- update_debugctlmsr(debugctl);
|
|
|
- set_tsk_thread_flag(child, TIF_BLOCKSTEP);
|
|
|
- } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
|
|
|
- unsigned long debugctl = get_debugctlmsr();
|
|
|
-
|
|
|
- debugctl &= ~DEBUGCTLMSR_BTF;
|
|
|
- update_debugctlmsr(debugctl);
|
|
|
- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
|
|
|
- }
|
|
|
+ if (enable_single_step(child) && block)
|
|
|
+ set_task_blockstep(child, true);
|
|
|
+ else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
|
|
|
+ set_task_blockstep(child, false);
|
|
|
}
|
|
|
|
|
|
void user_enable_single_step(struct task_struct *child)
|
|
@@ -199,13 +205,8 @@ void user_disable_single_step(struct task_struct *child)
|
|
|
/*
|
|
|
* Make sure block stepping (BTF) is disabled.
|
|
|
*/
|
|
|
- if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
|
|
|
- unsigned long debugctl = get_debugctlmsr();
|
|
|
-
|
|
|
- debugctl &= ~DEBUGCTLMSR_BTF;
|
|
|
- update_debugctlmsr(debugctl);
|
|
|
- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
|
|
|
- }
|
|
|
+ if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
|
|
|
+ set_task_blockstep(child, false);
|
|
|
|
|
|
/* Always clear TIF_SINGLESTEP... */
|
|
|
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
|