diff options
| -rw-r--r-- | arch/x86/kernel/step.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index c346d1161488..7a514986ca09 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c | |||
| @@ -157,6 +157,21 @@ static int enable_single_step(struct task_struct *child) | |||
| 157 | return 1; | 157 | return 1; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static void set_task_blockstep(struct task_struct *task, bool on) | ||
| 161 | { | ||
| 162 | unsigned long debugctl; | ||
| 163 | |||
| 164 | debugctl = get_debugctlmsr(); | ||
| 165 | if (on) { | ||
| 166 | debugctl |= DEBUGCTLMSR_BTF; | ||
| 167 | set_tsk_thread_flag(task, TIF_BLOCKSTEP); | ||
| 168 | } else { | ||
| 169 | debugctl &= ~DEBUGCTLMSR_BTF; | ||
| 170 | clear_tsk_thread_flag(task, TIF_BLOCKSTEP); | ||
| 171 | } | ||
| 172 | update_debugctlmsr(debugctl); | ||
| 173 | } | ||
| 174 | |||
| 160 | /* | 175 | /* |
| 161 | * Enable single or block step. | 176 | * Enable single or block step. |
| 162 | */ | 177 | */ |
| @@ -169,19 +184,10 @@ static void enable_step(struct task_struct *child, bool block) | |||
| 169 | * So no one should try to use debugger block stepping in a program | 184 | * So no one should try to use debugger block stepping in a program |
| 170 | * that uses user-mode single stepping itself. | 185 | * that uses user-mode single stepping itself. |
| 171 | */ | 186 | */ |
| 172 | if (enable_single_step(child) && block) { | 187 | if (enable_single_step(child) && block) |
| 173 | unsigned long debugctl = get_debugctlmsr(); | 188 | set_task_blockstep(child, true); |
| 174 | 189 | else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) | |
| 175 | debugctl |= DEBUGCTLMSR_BTF; | 190 | set_task_blockstep(child, false); |
| 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 | } | ||
| 185 | } | 191 | } |
| 186 | 192 | ||
| 187 | void user_enable_single_step(struct task_struct *child) | 193 | void user_enable_single_step(struct task_struct *child) |
| @@ -199,13 +205,8 @@ void user_disable_single_step(struct task_struct *child) | |||
| 199 | /* | 205 | /* |
| 200 | * Make sure block stepping (BTF) is disabled. | 206 | * Make sure block stepping (BTF) is disabled. |
| 201 | */ | 207 | */ |
| 202 | if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { | 208 | if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) |
| 203 | unsigned long debugctl = get_debugctlmsr(); | 209 | set_task_blockstep(child, false); |
| 204 | |||
| 205 | debugctl &= ~DEBUGCTLMSR_BTF; | ||
| 206 | update_debugctlmsr(debugctl); | ||
| 207 | clear_tsk_thread_flag(child, TIF_BLOCKSTEP); | ||
| 208 | } | ||
| 209 | 210 | ||
| 210 | /* Always clear TIF_SINGLESTEP... */ | 211 | /* Always clear TIF_SINGLESTEP... */ |
| 211 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | 212 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); |
