Messages in this thread | | | Date | Wed, 01 Aug 2012 17:12:16 +0200 | From | Sebastian Andrzej Siewior <> | Subject | Re: Q: user_enable_single_step() && update_debugctlmsr() |
| |
On 08/01/2012 05:01 PM, Oleg Nesterov wrote: > On 08/01, Sebastian Andrzej Siewior wrote: >> So a patch like >> --- a/arch/x86/kernel/step.c >> +++ b/arch/x86/kernel/step.c >> @@ -173,8 +173,8 @@ static void enable_step(struct task_struct *child, >> bool block) >> unsigned long debugctl = get_debugctlmsr(); >> >> debugctl |= DEBUGCTLMSR_BTF; >> - update_debugctlmsr(debugctl); >> set_tsk_thread_flag(child, TIF_BLOCKSTEP); >> + update_debugctlmsr(debugctl); >> } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) { >> unsigned long debugctl = get_debugctlmsr(); >> >> should fix the race > > No, I don't think it can fix something ;) or make any difference.
Why? You _first_ set the task flag followed by the CPU register. Now switch_to() would see the bit set and act.
>> and _yes_ I also would follow your suggestion to >> remove this update_debugctlmsr() here since switch_to() should do this. > > Agreed, but once again, uprobes needs it if child == current (but we should > move this code into the trivial helper). If we change (I hope) uprobes to > avoid user_enable_single_step() we will export the helper.
Okay. Looking at TIF_NOTSC I see that it does a preempt_disable() while playing with the bit. So this would be probably more obvious than switching the order :)
> > Oleg.
Sebastian
| |