From a7fa55938015ae392c096c194299a862f7fd5d8b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sat, 11 Aug 2012 18:06:42 +0200 Subject: [PATCH] --- yaml --- r: 323850 b: refs/heads/master c: 95cf00fa5d5e2a200a2c044c84bde8389a237e02 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/step.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 6a1e53d1719a..397188fd5702 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 848e8f5f0ad3169560c516fff6471be65f76e69f +refs/heads/master: 95cf00fa5d5e2a200a2c044c84bde8389a237e02 diff --git a/trunk/arch/x86/kernel/step.c b/trunk/arch/x86/kernel/step.c index 7a514986ca09..f89cdc6ccd5b 100644 --- a/trunk/arch/x86/kernel/step.c +++ b/trunk/arch/x86/kernel/step.c @@ -161,6 +161,16 @@ static void set_task_blockstep(struct task_struct *task, bool on) { unsigned long debugctl; + /* + * Ensure irq/preemption can't change debugctl in between. + * Note also that both TIF_BLOCKSTEP and debugctl should + * be changed atomically wrt preemption. + * FIXME: this means that set/clear TIF_BLOCKSTEP is simply + * wrong if task != current, SIGKILL can wakeup the stopped + * tracee and set/clear can play with the running task, this + * can confuse the next __switch_to_xtra(). + */ + local_irq_disable(); debugctl = get_debugctlmsr(); if (on) { debugctl |= DEBUGCTLMSR_BTF; @@ -169,7 +179,9 @@ static void set_task_blockstep(struct task_struct *task, bool on) debugctl &= ~DEBUGCTLMSR_BTF; clear_tsk_thread_flag(task, TIF_BLOCKSTEP); } - update_debugctlmsr(debugctl); + if (task == current) + update_debugctlmsr(debugctl); + local_irq_enable(); } /*