diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-08-03 11:31:46 -0400 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2012-09-15 11:37:28 -0400 |
commit | 848e8f5f0ad3169560c516fff6471be65f76e69f (patch) | |
tree | 9dac513988974bcbe948529f1565db03d981727b /arch/x86/kernel/step.c | |
parent | bdc1e47217315be14ba04881b0a4c8ecb3ff320c (diff) |
ptrace/x86: Introduce set_task_blockstep() helper
No functional changes, preparation for the next fix and for uprobes
single-step fixes.
Move the code playing with TIF_BLOCKSTEP/DEBUGCTLMSR_BTF into the
new helper, set_task_blockstep().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'arch/x86/kernel/step.c')
-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); |