aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/step.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2012-08-03 11:31:46 -0400
committerOleg Nesterov <oleg@redhat.com>2012-09-15 11:37:28 -0400
commit848e8f5f0ad3169560c516fff6471be65f76e69f (patch)
tree9dac513988974bcbe948529f1565db03d981727b /arch/x86/kernel/step.c
parentbdc1e47217315be14ba04881b0a4c8ecb3ff320c (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.c41
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
160static 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
187void user_enable_single_step(struct task_struct *child) 193void 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);