Messages in this thread | | | Date | Wed, 1 Aug 2012 15:01:18 +0200 | From | Oleg Nesterov <> | Subject | Q: user_enable_single_step() && update_debugctlmsr() |
| |
On 08/01, Oleg Nesterov wrote: > > And btw, this is offtopic, but the usage of update_debugctlmsr() > doesn't look right to me (I can be easily wrong though). I'll write > another email.
user_enable_single_step() does
if (enable_single_step(child) && block) { unsigned long debugctl = get_debugctlmsr();
debugctl |= DEBUGCTLMSR_BTF; update_debugctlmsr(debugctl); set_tsk_thread_flag(child, TIF_BLOCKSTEP); }
and I do not understand update_debugctlmsr() above (and other callsites).
Lets ignore uprobes which needs the changes anyway. This is only used by ptrace and the task is stopped. So, unless I missed something obvious, this update_debugctlmsr() is simply unneeded, __switch_to/__switch_to_xtra should notice _TIF_BLOCKSTEP and do update_debugctlmsr(DEBUGCTLMSR_BTF).
But, worse, isn't it wrong? Suppose that debugger switches to another TIF_SINGLESTEP && !TIF_BLOCKSTEP task, in this case we "leak" DEBUGCTLMSR_BTF, no?
IOW, it seems to me we could safely remove update_debugctlmsr() arch/x86/kernel/step.c. However, if we want to re-use this code in uprobes, then we probably need to add "if (child == current)".
Or I am totally confused. Help!
Oleg.
| |