kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v10 0/9] KVM: Add virtualization support of split lock detection
@ 2020-08-19  6:46 Xiaoyao Li
  2020-08-19  6:46 ` [PATCH v10 1/9] x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED Xiaoyao Li
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:46 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

Hi maintainers,

Please help review this new version and give comments. There is only one
minor change from previous v9, i.e., adding patch 8.

---

This series aims to add the virtualization of split lock detection in
KVM.

Due to the fact that split lock detection is tightly coupled with CPU
model and CPU model is configurable by host VMM, we elect to use
paravirt method to expose and enumerate it for guest.

Changes in v10
 - rebase to v5.9-rc1;
 - Add one patch to move the initialization of cpu_model_supports_sld to
   split_lock_setup();

Changes in v9
https://lkml.kernel.org/r/20200509110542.8159-1-xiaoyao.li@intel.com
 - rebase to v5.7-rc4
 - Add one patch to rename TIF_SLD to TIF_SLD_DISABLED;
 - Add one patch to remove bogus case in handle_guest_split_lock;
 - Introduce flag X86_FEATURE_SPLIT_LOCK_DETECT_FATAL and thus drop
   sld_state;
 - Use X86_FEATURE_SPLIT_LOCK_DETECT and X86_FEATURE_SPLIT_LOCK_DETECT_FATAL
   to determine the SLD state of host;
 - Introduce split_lock_virt_switch() and two wrappers for KVM instead
   of sld_update_to(); 
 - Use paravirt to expose and enumerate split lock detection for guest;
 - Split lock detection can be exposed to guest when host is sld_fatal,
   even though host is SMT available. 

Changes in v8:
https://lkml.kernel.org/r/20200414063129.133630-1-xiaoyao.li@intel.com
 - rebase to v5.7-rc1.
 - basic enabling of split lock detection already merged.
 - When host is sld_warn and nosmt, load guest's sld bit when in KVM
   context, i.e., between vmx_prepare_switch_to_guest() and before
   vmx_prepare_switch_to_host(), KVM uses guest sld setting.  

Changes in v7:
https://lkml.kernel.org/r/20200325030924.132881-1-xiaoyao.li@intel.com
 - only pick patch 1 and patch 2, and hold all the left.
 - Update SLD bit on each processor based on sld_state.

Changes in v6:
https://lkml.kernel.org/r/20200324151859.31068-1-xiaoyao.li@intel.com
 - Drop the sld_not_exist flag and use X86_FEATURE_SPLIT_LOCK_DETECT to
   check whether need to init split lock detection. [tglx]
 - Use tglx's method to verify the existence of split lock detectoin.
 - small optimization of sld_update_msr() that the default value of
   msr_test_ctrl_cache has split_lock_detect bit cleared.
 - Drop the patch3 in v5 that introducing kvm_only option. [tglx]
 - Rebase patch4-8 to kvm/queue.
 - use the new kvm-cpu-cap to expose X86_FEATURE_CORE_CAPABILITIES in
   Patch 6.

Changes in v5:
https://lkml.kernel.org/r/20200315050517.127446-1-xiaoyao.li@intel.com
 - Use X86_FEATURE_SPLIT_LOCK_DETECT flag in kvm to ensure split lock
   detection is really supported.
 - Add and export sld related helper functions in their related usecase 
   kvm patches.

Xiaoyao Li (9):
  x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED
  x86/split_lock: Remove bogus case in handle_guest_split_lock()
  x86/split_lock: Introduce flag X86_FEATURE_SLD_FATAL and drop
    sld_state
  x86/split_lock: Introduce split_lock_virt_switch() and two wrappers
  x86/kvm: Introduce paravirt split lock detection enumeration
  KVM: VMX: Enable MSR TEST_CTRL for guest
  KVM: VMX: virtualize split lock detection
  x86/split_lock: Set cpu_model_supports_sld to true after the existence
    of split lock detection is verified BSP
  x86/split_lock: Enable split lock detection initialization when
    running as a guest on KVM

 Documentation/virt/kvm/cpuid.rst     | 29 +++++++----
 arch/x86/include/asm/cpu.h           | 36 ++++++++++++++
 arch/x86/include/asm/cpufeatures.h   |  1 +
 arch/x86/include/asm/thread_info.h   |  6 +--
 arch/x86/include/uapi/asm/kvm_para.h |  8 ++--
 arch/x86/kernel/cpu/intel.c          | 61 +++++++++++++++--------
 arch/x86/kernel/kvm.c                |  3 ++
 arch/x86/kernel/process.c            |  2 +-
 arch/x86/kvm/cpuid.c                 |  6 +++
 arch/x86/kvm/vmx/vmx.c               | 72 +++++++++++++++++++++++++---
 arch/x86/kvm/vmx/vmx.h               |  3 ++
 arch/x86/kvm/x86.c                   |  6 ++-
 arch/x86/kvm/x86.h                   | 16 +++++++
 13 files changed, 207 insertions(+), 42 deletions(-)

-- 
2.18.4


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v10 1/9] x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
@ 2020-08-19  6:46 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 2/9] x86/split_lock: Remove bogus case in handle_guest_split_lock() Xiaoyao Li
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:46 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

TIF_SLD can only be set if a user space thread hits split lock and
sld_state == sld_warn. This flag is set to indicate SLD (split lock
detection) is turned off for the thread, so rename it to
TIF_SLD_DISABLED, which is pretty self explaining.

Suggested-by: Sean Christopherson <sean.j.christopherson@intel.com>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/include/asm/thread_info.h | 6 +++---
 arch/x86/kernel/cpu/intel.c        | 6 +++---
 arch/x86/kernel/process.c          | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 267701ae3d86..fdb458a74557 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -92,7 +92,7 @@ struct thread_info {
 #define TIF_NOCPUID		15	/* CPUID is not accessible in userland */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* IA32 compatibility process */
-#define TIF_SLD			18	/* Restore split lock detection on context switch */
+#define TIF_SLD_DISABLED	18	/* split lock detection is turned off */
 #define TIF_MEMDIE		20	/* is terminating due to OOM killer */
 #define TIF_POLLING_NRFLAG	21	/* idle is polling for TIF_NEED_RESCHED */
 #define TIF_IO_BITMAP		22	/* uses I/O bitmap */
@@ -122,7 +122,7 @@ struct thread_info {
 #define _TIF_NOCPUID		(1 << TIF_NOCPUID)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
-#define _TIF_SLD		(1 << TIF_SLD)
+#define _TIF_SLD_DISABLED	(1 << TIF_SLD_DISABLED)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
@@ -136,7 +136,7 @@ struct thread_info {
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW_BASE					\
 	(_TIF_NOCPUID | _TIF_NOTSC | _TIF_BLOCKSTEP |		\
-	 _TIF_SSBD | _TIF_SPEC_FORCE_UPDATE | _TIF_SLD)
+	 _TIF_SSBD | _TIF_SPEC_FORCE_UPDATE | _TIF_SLD_DISABLED)
 
 /*
  * Avoid calls to __switch_to_xtra() on UP as STIBP is not evaluated.
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 59a1e3ce3f14..c48b3267c141 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1090,11 +1090,11 @@ static void split_lock_warn(unsigned long ip)
 
 	/*
 	 * Disable the split lock detection for this task so it can make
-	 * progress and set TIF_SLD so the detection is re-enabled via
+	 * progress and set TIF_SLD_DISABLED so the detection is re-enabled via
 	 * switch_to_sld() when the task is scheduled out.
 	 */
 	sld_update_msr(false);
-	set_tsk_thread_flag(current, TIF_SLD);
+	set_tsk_thread_flag(current, TIF_SLD_DISABLED);
 }
 
 bool handle_guest_split_lock(unsigned long ip)
@@ -1132,7 +1132,7 @@ bool handle_user_split_lock(struct pt_regs *regs, long error_code)
  */
 void switch_to_sld(unsigned long tifn)
 {
-	sld_update_msr(!(tifn & _TIF_SLD));
+	sld_update_msr(!(tifn & _TIF_SLD_DISABLED));
 }
 
 /*
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 994d8393f2f7..e9265c6b9256 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -641,7 +641,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
 		__speculation_ctrl_update(~tifn, tifn);
 	}
 
-	if ((tifp ^ tifn) & _TIF_SLD)
+	if ((tifp ^ tifn) & _TIF_SLD_DISABLED)
 		switch_to_sld(tifn);
 }
 
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 2/9] x86/split_lock: Remove bogus case in handle_guest_split_lock()
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
  2020-08-19  6:46 ` [PATCH v10 1/9] x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 3/9] x86/split_lock: Introduce flag X86_FEATURE_SLD_FATAL and drop sld_state Xiaoyao Li
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

The bogus case can never happen, i.e., when sld_state == sld_off, guest
won't trigger split lock #AC and of course no handle_guest_split_lock()
will be called.

Besides, drop bogus case also makes future patch easier to remove
sld_state if we reach the alignment that it must be sld_warn or
sld_fatal when handle_guest_split_lock() is called.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
  The alternative would be to remove the "SLD enabled" check from KVM so
  that a truly unexpected/bogus #AC would generate a warn.  It's not clear
  whether or not calling handle_guest_split_lock() iff SLD is enabled was
  intended in the long term.
---
 arch/x86/kernel/cpu/intel.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index c48b3267c141..5dab842ba7e1 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1104,9 +1104,8 @@ bool handle_guest_split_lock(unsigned long ip)
 		return true;
 	}
 
-	pr_warn_once("#AC: %s/%d %s split_lock trap at address: 0x%lx\n",
-		     current->comm, current->pid,
-		     sld_state == sld_fatal ? "fatal" : "bogus", ip);
+	pr_warn_once("#AC: %s/%d fatal split_lock trap at address: 0x%lx\n",
+		     current->comm, current->pid, ip);
 
 	current->thread.error_code = 0;
 	current->thread.trap_nr = X86_TRAP_AC;
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 3/9] x86/split_lock: Introduce flag X86_FEATURE_SLD_FATAL and drop sld_state
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
  2020-08-19  6:46 ` [PATCH v10 1/9] x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 2/9] x86/split_lock: Remove bogus case in handle_guest_split_lock() Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 4/9] x86/split_lock: Introduce split_lock_virt_switch() and two wrappers Xiaoyao Li
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

Introduce a synthetic feature flag X86_FEATURE_SLD_FATAL, which means
kernel is in sld_fatal mode if set.

Now sld_state is not needed any more that the state of SLD can be
inferred from X86_FEATURE_SPLIT_LOCK_DETECT and X86_FEATURE_SLD_FATAL.

Suggested-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/kernel/cpu/intel.c        | 16 ++++++----------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 2901d5df4366..caf9f4e3e876 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -288,6 +288,7 @@
 #define X86_FEATURE_FENCE_SWAPGS_USER	(11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
 #define X86_FEATURE_FENCE_SWAPGS_KERNEL	(11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
 #define X86_FEATURE_SPLIT_LOCK_DETECT	(11*32+ 6) /* #AC for split lock */
+#define X86_FEATURE_SLD_FATAL		(11*32+ 7) /* split lock detection in fatal mode */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 5dab842ba7e1..06de03974e66 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -42,12 +42,6 @@ enum split_lock_detect_state {
 	sld_fatal,
 };
 
-/*
- * Default to sld_off because most systems do not support split lock detection
- * split_lock_setup() will switch this to sld_warn on systems that support
- * split lock detect, unless there is a command line override.
- */
-static enum split_lock_detect_state sld_state __ro_after_init = sld_off;
 static u64 msr_test_ctrl_cache __ro_after_init;
 
 /*
@@ -1058,8 +1052,9 @@ static void __init split_lock_setup(void)
 		return;
 	}
 
-	sld_state = state;
 	setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
+	if (state == sld_fatal)
+		setup_force_cpu_cap(X86_FEATURE_SLD_FATAL);
 }
 
 /*
@@ -1080,7 +1075,7 @@ static void sld_update_msr(bool on)
 static void split_lock_init(void)
 {
 	if (cpu_model_supports_sld)
-		split_lock_verify_msr(sld_state != sld_off);
+		split_lock_verify_msr(boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT));
 }
 
 static void split_lock_warn(unsigned long ip)
@@ -1099,7 +1094,7 @@ static void split_lock_warn(unsigned long ip)
 
 bool handle_guest_split_lock(unsigned long ip)
 {
-	if (sld_state == sld_warn) {
+	if (!boot_cpu_has(X86_FEATURE_SLD_FATAL)) {
 		split_lock_warn(ip);
 		return true;
 	}
@@ -1116,7 +1111,8 @@ EXPORT_SYMBOL_GPL(handle_guest_split_lock);
 
 bool handle_user_split_lock(struct pt_regs *regs, long error_code)
 {
-	if ((regs->flags & X86_EFLAGS_AC) || sld_state == sld_fatal)
+	if ((regs->flags & X86_EFLAGS_AC) ||
+	    boot_cpu_has(X86_FEATURE_SLD_FATAL))
 		return false;
 	split_lock_warn(regs->ip);
 	return true;
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 4/9] x86/split_lock: Introduce split_lock_virt_switch() and two wrappers
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (2 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 3/9] x86/split_lock: Introduce flag X86_FEATURE_SLD_FATAL and drop sld_state Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 5/9] x86/kvm: Introduce paravirt split lock detection enumeration Xiaoyao Li
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

Introduce split_lock_virt_switch(), which is used for toggling split
lock detection setting as well as updating TIF_SLD_DISABLED flag to make
them consistent. Note, it can only be used in sld warn mode, i.e.,
X86_FEATURE_SPLIT_LOCK_DETECT && !X86_FEATURE_SLD_FATAL.

The FATAL check is handled by wrappers, split_lock_set_guest() and
split_lock_restore_host(), that will be used by KVM when virtualizing
split lock detection for guest in the future.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/include/asm/cpu.h  | 34 ++++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel.c | 20 ++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index da78ccbd493b..2971a29d5094 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -45,6 +45,7 @@ extern void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
 extern void switch_to_sld(unsigned long tifn);
 extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
 extern bool handle_guest_split_lock(unsigned long ip);
+extern bool split_lock_virt_switch(bool on);
 #else
 static inline void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) {}
 static inline void switch_to_sld(unsigned long tifn) {}
@@ -57,7 +58,40 @@ static inline bool handle_guest_split_lock(unsigned long ip)
 {
 	return false;
 }
+
+static inline bool split_lock_virt_switch(bool on) { return false; }
 #endif
+
+/**
+ * split_lock_set_guest - Set SLD state for a guest
+ * @guest_sld_on:	If SLD is on in the guest
+ *
+ * returns:		%true if SLD was enabled in the task
+ *
+ * Must be called when X86_FEATURE_SPLIT_LOCK_DETECT is available.
+ */
+static inline bool split_lock_set_guest(bool guest_sld_on)
+{
+	if (static_cpu_has(X86_FEATURE_SLD_FATAL))
+		return true;
+
+	return split_lock_virt_switch(guest_sld_on);
+}
+
+/**
+ * split_lock_restore_host - Restore host SLD state
+ * @host_sld_on:		If SLD is on in the host
+ *
+ * Must be called when X86_FEATURE_SPLIT_LOCK_DETECT is available.
+ */
+static inline void split_lock_restore_host(bool host_sld_on)
+{
+	if (static_cpu_has(X86_FEATURE_SLD_FATAL))
+		return;
+
+	split_lock_virt_switch(host_sld_on);
+}
+
 #ifdef CONFIG_IA32_FEAT_CTL
 void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
 #else
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 06de03974e66..5f44e0de04b9 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1078,6 +1078,26 @@ static void split_lock_init(void)
 		split_lock_verify_msr(boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT));
 }
 
+/*
+ * It should never be called directly but should use split_lock_set_guest()
+ * and split_lock_restore_host() instead.
+ *
+ * The caller needs to be in preemption disabled context to ensure
+ * MSR state and TIF_SLD_DISABLED state consistent.
+ */
+bool split_lock_virt_switch(bool on)
+{
+	bool was_on = !test_thread_flag(TIF_SLD_DISABLED);
+
+	if (on != was_on) {
+		sld_update_msr(on);
+		update_thread_flag(TIF_SLD_DISABLED, !on);
+	}
+
+	return was_on;
+}
+EXPORT_SYMBOL_GPL(split_lock_virt_switch);
+
 static void split_lock_warn(unsigned long ip)
 {
 	pr_warn_ratelimited("#AC: %s/%d took a split_lock trap at address: 0x%lx\n",
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 5/9] x86/kvm: Introduce paravirt split lock detection enumeration
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (3 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 4/9] x86/split_lock: Introduce split_lock_virt_switch() and two wrappers Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 6/9] KVM: VMX: Enable MSR TEST_CTRL for guest Xiaoyao Li
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

Introduce KVM_FEATURE_SPLIT_LOCK_DETECT, with which guests running
on KVM can enumerate the avaliablility of feature split lock detection.

Introduce KVM_HINTS_SLD_FATAL, which tells whether host is sld_fatal mode,
i.e., whether split lock detection is forced on for guest vcpu.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 Documentation/virt/kvm/cpuid.rst     | 29 ++++++++++++++++++++--------
 arch/x86/include/uapi/asm/kvm_para.h |  8 +++++---
 2 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/Documentation/virt/kvm/cpuid.rst b/Documentation/virt/kvm/cpuid.rst
index a7dff9186bed..c214f1c70703 100644
--- a/Documentation/virt/kvm/cpuid.rst
+++ b/Documentation/virt/kvm/cpuid.rst
@@ -92,6 +92,12 @@ KVM_FEATURE_ASYNC_PF_INT          14          guest checks this feature bit
                                               async pf acknowledgment msr
                                               0x4b564d07.
 
+KVM_FEATURE_SPLIT_LOCK_DETECT     15          guest checks this feature bit for
+                                              available of split lock detection.
+
+                                              KVM doesn't support enumerating
+					      split lock detection via CPU model
+
 KVM_FEATURE_CLOCSOURCE_STABLE_BIT 24          host will warn if no guest-side
                                               per-cpu warps are expeced in
                                               kvmclock
@@ -103,11 +109,18 @@ KVM_FEATURE_CLOCSOURCE_STABLE_BIT 24          host will warn if no guest-side
 
 Where ``flag`` here is defined as below:
 
-================== ============ =================================
-flag               value        meaning
-================== ============ =================================
-KVM_HINTS_REALTIME 0            guest checks this feature bit to
-                                determine that vCPUs are never
-                                preempted for an unlimited time
-                                allowing optimizations
-================== ============ =================================
+================================ ============ =================================
+flag                             value        meaning
+================================ ============ =================================
+KVM_HINTS_REALTIME               0            guest checks this feature bit to
+                                              determine that vCPUs are never
+                                              preempted for an unlimited time
+                                              allowing optimizations
+
+KVM_HINTS_SLD_FATAL              1            set if split lock detection is
+                                              forced on in the host, in which
+					      case KVM will kill the guest if it
+					      generates a split lock #AC with
+					      SLD disabled from guest's
+					      perspective
+================================ ============ =================================
diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
index 812e9b4c1114..328ddfaacd7b 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -32,14 +32,16 @@
 #define KVM_FEATURE_POLL_CONTROL	12
 #define KVM_FEATURE_PV_SCHED_YIELD	13
 #define KVM_FEATURE_ASYNC_PF_INT	14
-
-#define KVM_HINTS_REALTIME      0
-
+#define KVM_FEATURE_SPLIT_LOCK_DETECT	15
 /* The last 8 bits are used to indicate how to interpret the flags field
  * in pvclock structure. If no bits are set, all flags are ignored.
  */
 #define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT	24
 
+/* KVM feature hints in CPUID.0x40000001.EDX */
+#define KVM_HINTS_REALTIME	0
+#define KVM_HINTS_SLD_FATAL	1
+
 #define MSR_KVM_WALL_CLOCK  0x11
 #define MSR_KVM_SYSTEM_TIME 0x12
 
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 6/9] KVM: VMX: Enable MSR TEST_CTRL for guest
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (4 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 5/9] x86/kvm: Introduce paravirt split lock detection enumeration Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 7/9] KVM: VMX: virtualize split lock detection Xiaoyao Li
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

Unconditionally allow the guest to read and zero-write MSR TEST_CTRL.

This matches the fact that most Intel CPUs support MSR TEST_CTRL, and
it also alleviates the effort to handle wrmsr/rdmsr when split lock
detection is exposed to the guest in a future patch.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 46ba2e03a892..e113c9171bcc 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1832,6 +1832,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	u32 index;
 
 	switch (msr_info->index) {
+	case MSR_TEST_CTRL:
+		msr_info->data = 0;
+		break;
 #ifdef CONFIG_X86_64
 	case MSR_FS_BASE:
 		msr_info->data = vmcs_readl(GUEST_FS_BASE);
@@ -1995,6 +1998,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	u32 index;
 
 	switch (msr_index) {
+	case MSR_TEST_CTRL:
+		if (data)
+			return 1;
+
+		break;
 	case MSR_EFER:
 		ret = kvm_set_msr_common(vcpu, msr_info);
 		break;
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 7/9] KVM: VMX: virtualize split lock detection
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (5 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 6/9] KVM: VMX: Enable MSR TEST_CTRL for guest Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 8/9] x86/split_lock: Set cpu_model_supports_sld to true after the existence of split lock detection is verified BSP Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 9/9] x86/split_lock: Enable split lock detection initialization when running as a guest on KVM Xiaoyao Li
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

TEST_CTRL MSR is per-core scope, i.e., the sibling threads in the same
physical core share the same MSR. This requires additional constraint
when exposing it to guest.

1) When host SLD state is sld_off (no X86_FEATURE_SPLIT_LOCK_DETECT),
   feature split lock detection is unsupported/disabled.
   Cannot expose it to guest.

2) When host SLD state is sld_warn (has X86_FEATURE_SPLIT_LOCK_DETECT
   but no X86_FEATURE_SLD_FATAL), feature split lock detection can be
   exposed to guest only when nosmt due to the per-core scope.

   In this case, guest's setting can be propagated into real hardware
   MSR. Further, to avoid the potiential MSR_TEST_CTRL.SLD toggling
   overhead during every vm-enter and vm-exit, it loads and keeps
   guest's SLD setting when in vcpu run loop and guest_state_loaded,
   i.e., between vmx_prepare_switch_to_guest() and
   vmx_prepare_switch_to_host().

3) when host SLD state is sld_fatal (has X86_FEATURE_SLD_FATAL),
   feature split lock detection can be exposed to guest regardless of
   SMT but KVM_HINTS_SLD_FATAL needs to be set.

   In this case, guest can still set and clear MSR_TEST_CTRL.SLD bit,
   but the bit value never be propagated to real MSR. KVM always keeps
   SLD bit turned on for guest vcpu. The reason why not force guest
   MSR_CTRL.SLD bit to 1 is that guest needs to set this bit to 1 itself
   to tell KVM it's SLD-aware.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/kvm/cpuid.c   |  6 ++++
 arch/x86/kvm/vmx/vmx.c | 68 ++++++++++++++++++++++++++++++++++++------
 arch/x86/kvm/vmx/vmx.h |  3 ++
 arch/x86/kvm/x86.c     |  6 +++-
 arch/x86/kvm/x86.h     | 16 ++++++++++
 5 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 3fd6eec202d7..58d902fb12c0 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -751,9 +751,15 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 		if (sched_info_on())
 			entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
 
+		if (kvm_split_lock_detect_supported())
+			entry->eax |= (1 << KVM_FEATURE_SPLIT_LOCK_DETECT);
+
 		entry->ebx = 0;
 		entry->ecx = 0;
 		entry->edx = 0;
+
+		if (boot_cpu_has(X86_FEATURE_SLD_FATAL))
+			entry->edx |= (1 << KVM_HINTS_SLD_FATAL);
 		break;
 	case 0x80000000:
 		entry->eax = min(entry->eax, 0x8000001f);
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index e113c9171bcc..e806c2855c9e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1123,6 +1123,29 @@ void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
 	}
 }
 
+static inline u64 vmx_msr_test_ctrl_valid_bits(struct vcpu_vmx *vmx)
+{
+	u64 valid_bits = 0;
+
+	if (vmx->guest_has_sld)
+		valid_bits |= MSR_TEST_CTRL_SPLIT_LOCK_DETECT;
+
+	return valid_bits;
+}
+
+static inline bool guest_sld_on(struct vcpu_vmx *vmx)
+{
+	return vmx->msr_test_ctrl & MSR_TEST_CTRL_SPLIT_LOCK_DETECT;
+}
+
+static inline void vmx_update_guest_sld(struct vcpu_vmx *vmx)
+{
+	preempt_disable();
+	if (vmx->guest_state_loaded)
+		split_lock_set_guest(guest_sld_on(vmx));
+	preempt_enable();
+}
+
 void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1191,6 +1214,10 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 #endif
 
 	vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
+
+	if (static_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) && vmx->guest_has_sld)
+		vmx->host_sld_on = split_lock_set_guest(guest_sld_on(vmx));
+
 	vmx->guest_state_loaded = true;
 }
 
@@ -1229,6 +1256,10 @@ static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx)
 	wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
 #endif
 	load_fixmap_gdt(raw_smp_processor_id());
+
+	if (static_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) && vmx->guest_has_sld)
+		split_lock_restore_host(vmx->host_sld_on);
+
 	vmx->guest_state_loaded = false;
 	vmx->guest_msrs_ready = false;
 }
@@ -1833,7 +1864,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
 	switch (msr_info->index) {
 	case MSR_TEST_CTRL:
-		msr_info->data = 0;
+		msr_info->data = vmx->msr_test_ctrl;
 		break;
 #ifdef CONFIG_X86_64
 	case MSR_FS_BASE:
@@ -1999,9 +2030,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
 	switch (msr_index) {
 	case MSR_TEST_CTRL:
-		if (data)
+		if (data & ~vmx_msr_test_ctrl_valid_bits(vmx))
 			return 1;
 
+		vmx->msr_test_ctrl = data;
+		vmx_update_guest_sld(vmx);
+
 		break;
 	case MSR_EFER:
 		ret = kvm_set_msr_common(vcpu, msr_info);
@@ -4380,7 +4414,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 
 	vmx->rmode.vm86_active = 0;
 	vmx->spec_ctrl = 0;
-
+	vmx->msr_test_ctrl = 0;
 	vmx->msr_ia32_umwait_control = 0;
 
 	vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
@@ -4731,24 +4765,32 @@ static int handle_machine_check(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
+static inline bool guest_alignment_check_enabled(struct kvm_vcpu *vcpu)
+{
+	return vmx_get_cpl(vcpu) == 3 && kvm_read_cr0_bits(vcpu, X86_CR0_AM) &&
+	       (kvm_get_rflags(vcpu) & X86_EFLAGS_AC);
+}
+
 /*
  * If the host has split lock detection disabled, then #AC is
  * unconditionally injected into the guest, which is the pre split lock
  * detection behaviour.
  *
  * If the host has split lock detection enabled then #AC is
- * only injected into the guest when:
- *  - Guest CPL == 3 (user mode)
- *  - Guest has #AC detection enabled in CR0
- *  - Guest EFLAGS has AC bit set
+ * injected into the guest when:
+ * 1) guest has alignment check enabled;
+ * or 2) guest has split lock detection enabled;
  */
 static inline bool guest_inject_ac(struct kvm_vcpu *vcpu)
 {
 	if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
 		return true;
 
-	return vmx_get_cpl(vcpu) == 3 && kvm_read_cr0_bits(vcpu, X86_CR0_AM) &&
-	       (kvm_get_rflags(vcpu) & X86_EFLAGS_AC);
+	/*
+	 * A split lock access must be an unaligned access, so we should check
+	 * guest_cpu_alignent_check_enabled() fisrt.
+	 */
+	return guest_alignment_check_enabled(vcpu) || guest_sld_on(to_vmx(vcpu));
 }
 
 static int handle_exception_nmi(struct kvm_vcpu *vcpu)
@@ -7316,6 +7358,7 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu)
 static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	struct kvm_cpuid_entry2 *best;
 
 	/* xsaves_enabled is recomputed in vmx_compute_secondary_exec_control(). */
 	vcpu->arch.xsaves_enabled = false;
@@ -7351,6 +7394,13 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 			vmx_set_guest_msr(vmx, msr, enabled ? 0 : TSX_CTRL_RTM_DISABLE);
 		}
 	}
+
+	vmx->guest_has_sld = false;
+	if (kvm_split_lock_detect_supported()) {
+		best = kvm_find_cpuid_entry(vcpu, KVM_CPUID_FEATURES, 0);
+		if (best && (best->eax & 1 << KVM_FEATURE_SPLIT_LOCK_DETECT))
+			vmx->guest_has_sld = true;
+	}
 }
 
 static __init void vmx_set_cpu_caps(void)
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 26175a4759fa..0714b183ebd2 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -222,12 +222,15 @@ struct vcpu_vmx {
 	int                   nmsrs;
 	int                   save_nmsrs;
 	bool                  guest_msrs_ready;
+	bool                  guest_has_sld;
+	bool                  host_sld_on;
 #ifdef CONFIG_X86_64
 	u64		      msr_host_kernel_gs_base;
 	u64		      msr_guest_kernel_gs_base;
 #endif
 
 	u64		      spec_ctrl;
+	u64                   msr_test_ctrl;
 	u32		      msr_ia32_umwait_control;
 
 	u32 secondary_exec_control;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 599d73206299..36a16a5d924f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1203,7 +1203,7 @@ static const u32 msrs_to_save_all[] = {
 #endif
 	MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
 	MSR_IA32_FEAT_CTL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
-	MSR_IA32_SPEC_CTRL,
+	MSR_IA32_SPEC_CTRL, MSR_TEST_CTRL,
 	MSR_IA32_RTIT_CTL, MSR_IA32_RTIT_STATUS, MSR_IA32_RTIT_CR3_MATCH,
 	MSR_IA32_RTIT_OUTPUT_BASE, MSR_IA32_RTIT_OUTPUT_MASK,
 	MSR_IA32_RTIT_ADDR0_A, MSR_IA32_RTIT_ADDR0_B,
@@ -5377,6 +5377,10 @@ static void kvm_init_msr_list(void)
 		 * to the guests in some cases.
 		 */
 		switch (msrs_to_save_all[i]) {
+		case MSR_TEST_CTRL:
+			if (!kvm_split_lock_detect_supported())
+				continue;
+			break;
 		case MSR_IA32_BNDCFGS:
 			if (!kvm_mpx_supported())
 				continue;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 995ab696dcf0..c65871fe3661 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -367,6 +367,22 @@ static inline bool kvm_dr6_valid(u64 data)
 	return !(data >> 32);
 }
 
+/*
+ * Since MSR_TEST is per-core scope, feature split lock detection cannot be
+ * exposed to guest when smt is possible() and !X86_FEATURE_SLD_FATAL. In this
+ * case, kvm needs to prograte the guest's value to real hardware MSR which
+ * can change the value of sibling threads.
+ *
+ * When X86_FEATURE_SLD_FATAL, we don't need to worry about the smt issue.
+ * Because in this case, the hardware MSR_TEST_CTRL.SLD bit is always set.
+ */
+static inline bool kvm_split_lock_detect_supported(void)
+{
+	return boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT) &&
+	       (boot_cpu_has(X86_FEATURE_SLD_FATAL) ||
+		!cpu_smt_possible());
+}
+
 void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu);
 void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu);
 int kvm_spec_ctrl_test_value(u64 value);
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 8/9] x86/split_lock: Set cpu_model_supports_sld to true after the existence of split lock detection is verified BSP
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (6 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 7/9] KVM: VMX: virtualize split lock detection Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  2020-08-19  6:47 ` [PATCH v10 9/9] x86/split_lock: Enable split lock detection initialization when running as a guest on KVM Xiaoyao Li
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

It should be more resonable to set cpu_model_supports_sld to true after
BSP is verified to have feature split lock detection.

It also avoids externing the cpu_model_supports_sld when enumerate the
split lock detection in a guest via PV interface in a future patch.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/kernel/cpu/intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 5f44e0de04b9..b16f3dd9b9c2 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1052,6 +1052,7 @@ static void __init split_lock_setup(void)
 		return;
 	}
 
+	cpu_model_supports_sld = true;
 	setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
 	if (state == sld_fatal)
 		setup_force_cpu_cap(X86_FEATURE_SLD_FATAL);
@@ -1203,6 +1204,5 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
 		return;
 	}
 
-	cpu_model_supports_sld = true;
 	split_lock_setup();
 }
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v10 9/9] x86/split_lock: Enable split lock detection initialization when running as a guest on KVM
  2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
                   ` (7 preceding siblings ...)
  2020-08-19  6:47 ` [PATCH v10 8/9] x86/split_lock: Set cpu_model_supports_sld to true after the existence of split lock detection is verified BSP Xiaoyao Li
@ 2020-08-19  6:47 ` Xiaoyao Li
  8 siblings, 0 replies; 10+ messages in thread
From: Xiaoyao Li @ 2020-08-19  6:47 UTC (permalink / raw)
  To: Thomas Gleixner, Paolo Bonzini, Sean Christopherson, kvm
  Cc: linux-kernel, x86, Ingo Molnar, Borislav Petkov, Andy Lutomirski,
	peterz, Arvind Sankar, Tony Luck, Fenghua Yu, Xiaoyao Li

When running as guest, enumerating feature split lock detection through
CPU model is not easy since CPU model is configurable by host VMM.

If running upon KVM, it can be enumerated through
KVM_FEATURE_SPLIT_LOCK_DETECT, and if KVM_HINTS_SLD_FATAL is set, it
needs to be set to sld_fatal mode.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
---
 arch/x86/include/asm/cpu.h  |  2 ++
 arch/x86/kernel/cpu/intel.c | 12 ++++++++++--
 arch/x86/kernel/kvm.c       |  3 +++
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 2971a29d5094..5520cc1cbb68 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -42,12 +42,14 @@ unsigned int x86_model(unsigned int sig);
 unsigned int x86_stepping(unsigned int sig);
 #ifdef CONFIG_CPU_SUP_INTEL
 extern void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c);
+extern void __init split_lock_setup(bool fatal);
 extern void switch_to_sld(unsigned long tifn);
 extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
 extern bool handle_guest_split_lock(unsigned long ip);
 extern bool split_lock_virt_switch(bool on);
 #else
 static inline void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c) {}
+static inline void __init split_lock_setup(bool fatal) {}
 static inline void switch_to_sld(unsigned long tifn) {}
 static inline bool handle_user_split_lock(struct pt_regs *regs, long error_code)
 {
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index b16f3dd9b9c2..8cadd2fd8be6 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -1011,12 +1011,18 @@ static bool split_lock_verify_msr(bool on)
 	return ctrl == tmp;
 }
 
-static void __init split_lock_setup(void)
+void __init split_lock_setup(bool fatal)
 {
 	enum split_lock_detect_state state = sld_warn;
 	char arg[20];
 	int i, ret;
 
+	if (fatal) {
+		state = sld_fatal;
+		pr_info("forced on, sending SIGBUS on user-space split_locks\n");
+		goto set_cap;
+	}
+
 	if (!split_lock_verify_msr(false)) {
 		pr_info("MSR access failed: Disabled\n");
 		return;
@@ -1052,6 +1058,7 @@ static void __init split_lock_setup(void)
 		return;
 	}
 
+set_cap:
 	cpu_model_supports_sld = true;
 	setup_force_cpu_cap(X86_FEATURE_SPLIT_LOCK_DETECT);
 	if (state == sld_fatal)
@@ -1183,6 +1190,7 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
 	const struct x86_cpu_id *m;
 	u64 ia32_core_caps;
 
+	/* Note, paravirt support can enable SLD, e.g., see kvm_guest_init(). */
 	if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
 		return;
 
@@ -1204,5 +1212,5 @@ void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
 		return;
 	}
 
-	split_lock_setup();
+	split_lock_setup(false);
 }
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 08320b0b2b27..25cd5d7f1e51 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -687,6 +687,9 @@ static void __init kvm_guest_init(void)
 	 * overcommitted.
 	 */
 	hardlockup_detector_disable();
+
+	if (kvm_para_has_feature(KVM_FEATURE_SPLIT_LOCK_DETECT))
+		split_lock_setup(kvm_para_has_hint(KVM_HINTS_SLD_FATAL));
 }
 
 static noinline uint32_t __kvm_cpuid_base(void)
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-08-19  6:49 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-19  6:46 [PATCH v10 0/9] KVM: Add virtualization support of split lock detection Xiaoyao Li
2020-08-19  6:46 ` [PATCH v10 1/9] x86/split_lock: Rename TIF_SLD to TIF_SLD_DISABLED Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 2/9] x86/split_lock: Remove bogus case in handle_guest_split_lock() Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 3/9] x86/split_lock: Introduce flag X86_FEATURE_SLD_FATAL and drop sld_state Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 4/9] x86/split_lock: Introduce split_lock_virt_switch() and two wrappers Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 5/9] x86/kvm: Introduce paravirt split lock detection enumeration Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 6/9] KVM: VMX: Enable MSR TEST_CTRL for guest Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 7/9] KVM: VMX: virtualize split lock detection Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 8/9] x86/split_lock: Set cpu_model_supports_sld to true after the existence of split lock detection is verified BSP Xiaoyao Li
2020-08-19  6:47 ` [PATCH v10 9/9] x86/split_lock: Enable split lock detection initialization when running as a guest on KVM Xiaoyao Li

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).