Re: [PATCH v5 09/18] x86/split_lock: Handle #AC exception for split lock

From: Fenghua Yu
Date: Tue Mar 12 2019 - 20:57:14 EST


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