diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0036-x86-process-Correct-and-optimize-TIF_BLOCKSTEP-switc.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0036-x86-process-Correct-and-optimize-TIF_BLOCKSTEP-switc.patch | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0036-x86-process-Correct-and-optimize-TIF_BLOCKSTEP-switc.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0036-x86-process-Correct-and-optimize-TIF_BLOCKSTEP-switc.patch new file mode 100644 index 00000000..9fd2ab23 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0036-x86-process-Correct-and-optimize-TIF_BLOCKSTEP-switc.patch @@ -0,0 +1,84 @@ +From 19f795b97249d2e81ea918644577ab9669704c28 Mon Sep 17 00:00:00 2001 +From: Kyle Huey <me@kylehuey.com> +Date: Tue, 14 Feb 2017 00:11:03 -0800 +Subject: [PATCH 36/93] 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 | 1 + + arch/x86/kernel/process.c | 12 +++++++----- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h +index 9f014c1..4027c33 100644 +--- a/arch/x86/include/asm/msr-index.h ++++ b/arch/x86/include/asm/msr-index.h +@@ -141,6 +141,7 @@ + + /* DEBUGCTLMSR bits (others vary by model): */ + #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ ++#define DEBUGCTLMSR_BTF_SHIFT 1 + #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ + #define DEBUGCTLMSR_TR (1UL << 6) + #define DEBUGCTLMSR_BTS (1UL << 7) +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index 0e1999e..496eef6 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -227,13 +227,15 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, + + propagate_user_return_notify(prev_p, next_p); + +- if ((tifp ^ tifn) & _TIF_BLOCKSTEP) { +- unsigned long debugctl = get_debugctlmsr(); ++ if ((tifp & _TIF_BLOCKSTEP || tifn & _TIF_BLOCKSTEP) && ++ arch_has_block_step()) { ++ unsigned long debugctl, msk; + ++ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + debugctl &= ~DEBUGCTLMSR_BTF; +- if (tifn & _TIF_BLOCKSTEP) +- debugctl |= DEBUGCTLMSR_BTF; +- update_debugctlmsr(debugctl); ++ msk = tifn & _TIF_BLOCKSTEP; ++ debugctl |= (msk >> TIF_BLOCKSTEP) << DEBUGCTLMSR_BTF_SHIFT; ++ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + } + + if ((tifp ^ tifn) & _TIF_NOTSC) { +-- +2.7.4 + |