On Tue, Mar 12, 2019 at 04:51:22PM -0700, Dave Hansen wrote: > On 3/12/19 4:00 PM, Fenghua Yu wrote: > I don't see any feature checking here. Don't we need to see if this MSR > is supported? > > Shouldn't the code here on systems that don't support split lock > disabling be the same as on CONFIG_CPU_SUP_INTEL=n systems? You are right. Is the following #AC handler code better? diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index d26f9e9c3d83..5296021509c7 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -61,6 +61,7 @@ #include <asm/mpx.h> #include <asm/vm86.h> #include <asm/umip.h> +#include <asm/cpu.h> #ifdef CONFIG_X86_64 #include <asm/x86_init.h> @@ -293,7 +294,37 @@ DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, 0, NULL, "coprocessor segment overru DO_ERROR(X86_TRAP_TS, SIGSEGV, 0, NULL, "invalid TSS", invalid_TSS) DO_ERROR(X86_TRAP_NP, SIGBUS, 0, NULL, "segment not present", segment_not_present) DO_ERROR(X86_TRAP_SS, SIGBUS, 0, NULL, "stack segment", stack_segment) -DO_ERROR(X86_TRAP_AC, SIGBUS, BUS_ADRALN, NULL, "alignment check", alignment_check) +dotraplinkage void do_alignment_check(struct pt_regs *regs, long error_code) +{ + unsigned int trapnr = X86_TRAP_AC; + char str[] = "alignment check"; + int signr = SIGBUS; + + RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); + + if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != + NOTIFY_STOP) { + cond_local_irq_enable(regs); + if (!user_mode(regs)) { + if (!this_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) + return; + + /* + * Only split lock can generate #AC from kernel. Warn + * and disable #AC for split lock on current CPU. + */ + msr_clear_bit(MSR_TEST_CTL, + TEST_CTL_ENABLE_SPLIT_LOCK_DETECT_SHIFT); + WARN_ONCE(1, "A split lock issue is detected.\n"); + + + return; + } + /* Handle #AC generated from user code. */ + do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs, + error_code, BUS_ADRALN, NULL); + } +} #undef IP #ifdef CONFIG_VMAP_STACK