From: Fenghua Yu <fenghua.yu@intel.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>, "H Peter Anvin" <hpa@zytor.com>,
"Peter Zijlstra" <peterz@infradead.org>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Dave Hansen" <dave.hansen@intel.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Radim Krcmar" <rkrcmar@redhat.com>,
"Christopherson Sean J" <sean.j.christopherson@intel.com>,
"Ashok Raj" <ashok.raj@intel.com>,
"Tony Luck" <tony.luck@intel.com>,
"Dan Williams" <dan.j.williams@intel.com>,
"Xiaoyao Li " <xiaoyao.li@intel.com>,
"Sai Praneeth Prakhya" <sai.praneeth.prakhya@intel.com>,
"Ravi V Shankar" <ravi.v.shankar@intel.com>
Cc: "linux-kernel" <linux-kernel@vger.kernel.org>,
"x86" <x86@kernel.org>,
kvm@vger.kernel.org, Fenghua Yu <fenghua.yu@intel.com>
Subject: [PATCH v9 09/17] x86/split_lock: Handle #AC exception for split lock
Date: Tue, 18 Jun 2019 15:41:11 -0700 [thread overview]
Message-ID: <1560897679-228028-10-git-send-email-fenghua.yu@intel.com> (raw)
In-Reply-To: <1560897679-228028-1-git-send-email-fenghua.yu@intel.com>
There may be different considerations on how to handle #AC for split lock,
e.g. how to handle system hang caused by split lock issue in firmware,
how to emulate faulting instruction, etc. We use a simple method to
handle user and kernel split lock and may extend the method in the future.
When #AC exception for split lock is triggered from user process, the
process is killed by SIGBUS. To execute the process properly, a user
application developer needs to fix the split lock issue.
When #AC exception for split lock is triggered from a kernel instruction,
disable split lock detection on local CPU and warn the split lock issue.
After the exception, the faulting instruction will be executed and kernel
execution continues. Split lock detection is only disabled on the local
CPU, not globally. It will be re-enabled if the CPU is offline and then
online or through debugfs interface.
A kernel/driver developer should check the warning, which contains helpful
faulting address, context, and callstack info, and fix the split lock
issues. Then further split lock issues may be captured and fixed.
After bit 29 in MSR_TEST_CTL is set to 1 in kernel, firmware inherits
the setting when firmware is executed in S4, S5, run time services, SMI,
etc. If there is a split lock operation in firmware, it will triggers
#AC and may hang the system depending on how firmware handles the #AC.
It's up to a firmware developer to fix split lock issues in firmware.
MSR TEST_CTL value is cached in per CPU msr_test_ctl_cached which will be
used in virtualization to avoid costly MSR read.
Ingo suggests to use global split_lock_debug flag to allow only one CPU to
print split lock warning in the #AC handler because WARN_ONCE() and
underlying BUGFLAG_ONCE mechanism are not atomic. This also solves
the race if the split-lock #AC fault is re-triggered by NMI of perf
context interrupting one split-lock warning execution while the original
WARN_ON() is executing.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
arch/x86/include/asm/cpu.h | 3 +++
arch/x86/kernel/cpu/intel.c | 38 +++++++++++++++++++++++++++++++++
arch/x86/kernel/traps.c | 42 ++++++++++++++++++++++++++++++++++++-
3 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 4e03f53fc079..81710f2a3eea 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -42,7 +42,10 @@ unsigned int x86_model(unsigned int sig);
unsigned int x86_stepping(unsigned int sig);
#ifdef CONFIG_CPU_SUP_INTEL
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
+DECLARE_PER_CPU(u64, msr_test_ctl_cached);
+void split_lock_disable(void);
#else
static inline void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) {}
+static inline void split_lock_disable(void) {}
#endif
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 7ae6cc22657d..16cf1631b7f9 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -31,6 +31,9 @@
#include <asm/apic.h>
#endif
+DEFINE_PER_CPU(u64, msr_test_ctl_cached);
+EXPORT_PER_CPU_SYMBOL_GPL(msr_test_ctl_cached);
+
/*
* Just in case our CPU detection goes bad, or you have a weird system,
* allow a way to override the automatic disabling of MPX.
@@ -624,6 +627,17 @@ static void init_intel_misc_features(struct cpuinfo_x86 *c)
wrmsrl(MSR_MISC_FEATURES_ENABLES, msr);
}
+static void split_lock_init(struct cpuinfo_x86 *c)
+{
+ if (cpu_has(c, X86_FEATURE_SPLIT_LOCK_DETECT)) {
+ u64 test_ctl_val;
+
+ /* Cache MSR TEST_CTL */
+ rdmsrl(MSR_TEST_CTL, test_ctl_val);
+ this_cpu_write(msr_test_ctl_cached, test_ctl_val);
+ }
+}
+
static void init_intel(struct cpuinfo_x86 *c)
{
early_init_intel(c);
@@ -734,6 +748,8 @@ static void init_intel(struct cpuinfo_x86 *c)
detect_tme(c);
init_intel_misc_features(c);
+
+ split_lock_init(c);
}
#ifdef CONFIG_X86_32
@@ -1027,3 +1043,25 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
if (ia32_core_cap & MSR_IA32_CORE_CAP_SPLIT_LOCK_DETECT)
split_lock_setup();
}
+
+static atomic_t split_lock_debug;
+
+void split_lock_disable(void)
+{
+ /* Disable split lock detection on this CPU */
+ this_cpu_and(msr_test_ctl_cached, ~MSR_TEST_CTL_SPLIT_LOCK_DETECT);
+ wrmsrl(MSR_TEST_CTL, this_cpu_read(msr_test_ctl_cached));
+
+ /*
+ * Use the atomic variable split_lock_debug to ensure only the
+ * first CPU hitting split lock issue prints one single complete
+ * warning. This also solves the race if the split-lock #AC fault
+ * is re-triggered by NMI of perf context interrupting one
+ * split-lock warning execution while the original WARN_ONCE() is
+ * executing.
+ */
+ if (atomic_cmpxchg(&split_lock_debug, 0, 1) == 0) {
+ WARN_ONCE(1, "split lock operation detected\n");
+ atomic_set(&split_lock_debug, 0);
+ }
+}
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 8b6d03e55d2f..38143c028f5a 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,9 +294,48 @@ 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)
#undef IP
+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)
+ return;
+
+ cond_local_irq_enable(regs);
+ if (!user_mode(regs) && static_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) {
+ /*
+ * Only split locks can generate #AC from kernel mode.
+ *
+ * The split-lock detection feature is a one-shot
+ * debugging facility, so we disable it immediately and
+ * print a warning.
+ *
+ * This also solves the instruction restart problem: we
+ * return the faulting instruction right after this it
+ * will be executed without generating another #AC fault
+ * and getting into an infinite loop, instead it will
+ * continue without side effects to the interrupted
+ * execution context.
+ *
+ * Split-lock detection will remain disabled after this,
+ * until the next reboot.
+ */
+ split_lock_disable();
+
+ return;
+ }
+
+ /* Handle #AC generated in any other cases. */
+ do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs,
+ error_code, BUS_ADRALN, NULL);
+}
+
#ifdef CONFIG_VMAP_STACK
__visible void __noreturn handle_stack_overflow(const char *message,
struct pt_regs *regs,
--
2.19.1
next prev parent reply other threads:[~2019-06-18 22:51 UTC|newest]
Thread overview: 85+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-18 22:41 [PATCH v9 00/17] x86/split_lock: Enable split lock detection Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 01/17] x86/common: Align cpu_caps_cleared and cpu_caps_set to unsigned long Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 02/17] drivers/net/b44: Align pwol_mask to unsigned long for better performance Fenghua Yu
2019-06-24 15:12 ` David Laight
2019-06-24 18:43 ` Paolo Bonzini
2019-06-18 22:41 ` [PATCH v9 03/17] x86/split_lock: Align x86_capability to unsigned long to avoid split locked access Fenghua Yu
2019-06-24 15:12 ` David Laight
2019-06-25 23:54 ` Fenghua Yu
2019-06-26 19:15 ` Thomas Gleixner
2019-06-18 22:41 ` [PATCH v9 04/17] x86/msr-index: Define MSR_IA32_CORE_CAP and split lock detection bit Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 05/17] x86/cpufeatures: Enumerate MSR_IA32_CORE_CAP Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 06/17] x86/split_lock: Enumerate split lock detection by MSR_IA32_CORE_CAP Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 07/17] x86/split_lock: Enumerate split lock detection on Icelake mobile processor Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 08/17] x86/split_lock: Define MSR TEST_CTL register Fenghua Yu
2019-06-18 22:41 ` Fenghua Yu [this message]
2019-06-26 20:20 ` [PATCH v9 09/17] x86/split_lock: Handle #AC exception for split lock Thomas Gleixner
2019-06-26 20:36 ` Fenghua Yu
2019-06-26 21:47 ` Thomas Gleixner
2019-09-25 18:09 ` Sean Christopherson
2019-10-16 6:58 ` Xiaoyao Li
2019-10-16 9:29 ` Thomas Gleixner
2019-10-16 15:59 ` Sean Christopherson
2019-10-16 9:40 ` Paolo Bonzini
2019-10-16 9:47 ` Thomas Gleixner
2019-10-16 10:16 ` Paolo Bonzini
2019-10-16 11:23 ` Xiaoyao Li
2019-10-16 11:26 ` Paolo Bonzini
2019-10-16 13:13 ` Xiaoyao Li
2019-10-16 14:43 ` Thomas Gleixner
2019-10-16 15:37 ` Paolo Bonzini
2019-10-16 16:25 ` Xiaoyao Li
2019-10-16 16:38 ` Paolo Bonzini
2019-10-17 12:29 ` [RFD] x86/split_lock: Request to Intel Thomas Gleixner
2019-10-17 17:23 ` Sean Christopherson
2019-10-17 21:31 ` Thomas Gleixner
2019-10-17 23:38 ` Sean Christopherson
2019-10-17 23:28 ` Luck, Tony
2019-10-18 10:45 ` David Laight
2019-10-18 21:03 ` hpa
2019-10-18 2:36 ` Xiaoyao Li
2019-10-18 9:02 ` Thomas Gleixner
2019-10-18 10:20 ` Xiaoyao Li
2019-10-18 10:43 ` Peter Zijlstra
2019-10-16 11:49 ` [PATCH v9 09/17] x86/split_lock: Handle #AC exception for split lock Thomas Gleixner
2019-10-16 11:58 ` Paolo Bonzini
2019-10-16 13:51 ` Xiaoyao Li
2019-10-16 14:08 ` Paolo Bonzini
2019-10-16 14:14 ` David Laight
2019-10-16 15:03 ` Thomas Gleixner
2019-10-16 15:41 ` Sean Christopherson
2019-10-16 15:43 ` Paolo Bonzini
2019-10-16 16:23 ` Sean Christopherson
2019-10-16 17:42 ` Sean Christopherson
2019-10-17 1:23 ` Xiaoyao Li
2019-10-21 13:06 ` Paolo Bonzini
2019-10-21 13:03 ` Paolo Bonzini
2019-10-21 13:02 ` Paolo Bonzini
2019-10-16 14:50 ` Thomas Gleixner
2019-06-18 22:41 ` [PATCH v9 10/17] kvm/x86: Emulate MSR IA32_CORE_CAPABILITY Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 11/17] kvm/vmx: Emulate MSR TEST_CTL Fenghua Yu
2019-06-27 2:24 ` Xiaoyao Li
2019-06-27 7:12 ` Thomas Gleixner
2019-06-27 7:58 ` Xiaoyao Li
2019-06-27 12:11 ` Thomas Gleixner
2019-06-27 12:22 ` Xiaoyao Li
2019-06-18 22:41 ` [PATCH v9 12/17] x86/split_lock: Enable split lock detection by default Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 13/17] x86/split_lock: Disable split lock detection by kernel parameter "nosplit_lock_detect" Fenghua Yu
2019-06-26 20:34 ` Thomas Gleixner
2019-06-26 20:37 ` Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 14/17] x86/split_lock: Add a debugfs interface to enable/disable split lock detection during run time Fenghua Yu
2019-06-26 21:37 ` Thomas Gleixner
2019-06-18 22:41 ` [PATCH v9 15/17] x86/split_lock: Add documentation for split lock detection interface Fenghua Yu
2019-06-26 21:51 ` Thomas Gleixner
2019-06-18 22:41 ` [PATCH v9 16/17] x86/split_lock: Reorganize few header files in order to call WARN_ON_ONCE() in atomic bit ops Fenghua Yu
2019-06-18 22:41 ` [PATCH v9 17/17] x86/split_lock: Warn on unaligned address in atomic bit operations Fenghua Yu
2019-06-26 22:00 ` Thomas Gleixner
2019-09-16 22:39 ` [PATCH 0/3] Fix some 4-byte vs. 8-byte alignment issues Tony Luck
2019-09-16 22:39 ` [PATCH 1/3] x86/common: Align cpu_caps_cleared and cpu_caps_set to unsigned long Tony Luck
2019-11-15 19:26 ` [tip: x86/cpu] x86/cpu: " tip-bot2 for Fenghua Yu
2019-09-16 22:39 ` [PATCH 2/3] drivers/net/b44: Align pwol_mask to unsigned long for better performance Tony Luck
2019-09-16 22:39 ` [PATCH 3/3] x86/split_lock: Align the x86_capability array to size of unsigned long Tony Luck
2019-09-17 8:29 ` David Laight
2019-09-17 19:14 ` Luck, Tony
2019-09-18 8:54 ` David Laight
2019-11-15 19:26 ` [tip: x86/cpu] x86/cpu: " tip-bot2 for Fenghua Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1560897679-228028-10-git-send-email-fenghua.yu@intel.com \
--to=fenghua.yu@intel.com \
--cc=akpm@linux-foundation.org \
--cc=ashok.raj@intel.com \
--cc=bp@alien8.de \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=ravi.v.shankar@intel.com \
--cc=rkrcmar@redhat.com \
--cc=sai.praneeth.prakhya@intel.com \
--cc=sean.j.christopherson@intel.com \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).