x86/process: Correct and optimize TIF_BLOCKSTEP switch
authorKyle Huey <me@kylehuey.com>
Tue, 14 Feb 2017 08:11:03 +0000 (00:11 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 May 2018 14:58:00 +0000 (16:58 +0200)
commit439f2ef884306976f22b42f709c1ccdf04278987
treec80e0fc649432fa18c7509f1ecded7a0a52cd225
parentfd01e82efa269b7e295533ec7b2d93aa8adf670a
x86/process: Correct and optimize TIF_BLOCKSTEP switch

commit b9894a2f5bd18b1691cb6872c9afe32b148d0132 upstream

The debug control MSR is "highly magical" as the blockstep bit can be
cleared by hardware under not well documented circumstances.

So a task switch relying on the bit set by the previous task (according to
the previous tasks thread flags) can trip over this and not update the flag
for the next task.

To fix this its required to handle DEBUGCTLMSR_BTF when either the previous
or the next or both tasks have the TIF_BLOCKSTEP flag set.

While at it avoid branching within the TIF_BLOCKSTEP case and evaluating
boot_cpu_data twice in kernels without CONFIG_X86_DEBUGCTLMSR.

x86_64: arch/x86/kernel/process.o
text data bss dec  hex
3024    8577    16      11617    2d61 Before
3008 8577 16 11601  2d51 After

i386: No change

[ tglx: Made the shift value explicit, use a local variable to make the
code readable and massaged changelog]

Originally-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Link: http://lkml.kernel.org/r/20170214081104.9244-3-khuey@kylehuey.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/msr-index.h
arch/x86/kernel/process.c