All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, KarimAllah Ahmed <karahmed@amazon.de>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Thomas Gleixner <tglx@linutronix.de>,
	Darren Kenny <darren.kenny@oracle.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Jim Mattson <jmattson@google.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Andi Kleen <ak@linux.intel.com>,
	Jun Nakajima <jun.nakajima@intel.com>,
	kvm@vger.kernel.org, Dave Hansen <dave.hansen@intel.com>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Asit Mallick <asit.k.mallick@intel.com>,
	Arjan Van De Ven <arjan.van.de.ven@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Linus Torvalds <torvalds@linux-foundatio
Subject: [PATCH 4.9 84/92] KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
Date: Fri,  9 Feb 2018 14:39:53 +0100	[thread overview]
Message-ID: <20180209133937.218820152@linuxfoundation.org> (raw)
In-Reply-To: <20180209133931.211869118@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: KarimAllah Ahmed <karahmed@amazon.de>


(cherry picked from commit d28b387fb74da95d69d2615732f50cceb38e9a4d)

[ Based on a patch from Ashok Raj <ashok.raj@intel.com> ]

Add direct access to MSR_IA32_SPEC_CTRL for guests. This is needed for
guests that will only mitigate Spectre V2 through IBRS+IBPB and will not
be using a retpoline+IBPB based approach.

To avoid the overhead of saving and restoring the MSR_IA32_SPEC_CTRL for
guests that do not actually use the MSR, only start saving and restoring
when a non-zero is written to it.

No attempt is made to handle STIBP here, intentionally. Filtering STIBP
may be added in a future patch, which may require trapping all writes
if we don't want to pass it through directly to the guest.

[dwmw2: Clean up CPUID bits, save/restore manually, handle reset]

Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: kvm@vger.kernel.org
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Asit Mallick <asit.k.mallick@intel.com>
Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Link: https://lkml.kernel.org/r/1517522386-18410-5-git-send-email-karahmed@amazon.de
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/cpuid.c |    8 ++-
 arch/x86/kvm/cpuid.h |   11 +++++
 arch/x86/kvm/vmx.c   |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/x86.c   |    2 
 4 files changed, 118 insertions(+), 6 deletions(-)

--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -357,7 +357,7 @@ static inline int __do_cpuid_ent(struct
 
 	/* cpuid 0x80000008.ebx */
 	const u32 kvm_cpuid_8000_0008_ebx_x86_features =
-		F(IBPB);
+		F(IBPB) | F(IBRS);
 
 	/* cpuid 0xC0000001.edx */
 	const u32 kvm_cpuid_C000_0001_edx_x86_features =
@@ -382,7 +382,7 @@ static inline int __do_cpuid_ent(struct
 
 	/* cpuid 7.0.edx*/
 	const u32 kvm_cpuid_7_0_edx_x86_features =
-		F(ARCH_CAPABILITIES);
+		F(SPEC_CTRL) | F(ARCH_CAPABILITIES);
 
 	/* all calls to cpuid_count() should be made on the same cpu */
 	get_cpu();
@@ -618,9 +618,11 @@ static inline int __do_cpuid_ent(struct
 			g_phys_as = phys_as;
 		entry->eax = g_phys_as | (virt_as << 8);
 		entry->edx = 0;
-		/* IBPB isn't necessarily present in hardware cpuid */
+		/* IBRS and IBPB aren't necessarily present in hardware cpuid */
 		if (boot_cpu_has(X86_FEATURE_IBPB))
 			entry->ebx |= F(IBPB);
+		if (boot_cpu_has(X86_FEATURE_IBRS))
+			entry->ebx |= F(IBRS);
 		entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
 		cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
 		break;
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -171,6 +171,17 @@ static inline bool guest_cpuid_has_ibpb(
 	return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
 }
 
+static inline bool guest_cpuid_has_ibrs(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+
+	best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+	if (best && (best->ebx & bit(X86_FEATURE_IBRS)))
+		return true;
+	best = kvm_find_cpuid_entry(vcpu, 7, 0);
+	return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+}
+
 static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *best;
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -552,6 +552,7 @@ struct vcpu_vmx {
 #endif
 
 	u64 		      arch_capabilities;
+	u64 		      spec_ctrl;
 
 	u32 vm_entry_controls_shadow;
 	u32 vm_exit_controls_shadow;
@@ -1852,6 +1853,29 @@ static void update_exception_bitmap(stru
 }
 
 /*
+ * Check if MSR is intercepted for currently loaded MSR bitmap.
+ */
+static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
+{
+	unsigned long *msr_bitmap;
+	int f = sizeof(unsigned long);
+
+	if (!cpu_has_vmx_msr_bitmap())
+		return true;
+
+	msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap;
+
+	if (msr <= 0x1fff) {
+		return !!test_bit(msr, msr_bitmap + 0x800 / f);
+	} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
+		msr &= 0x1fff;
+		return !!test_bit(msr, msr_bitmap + 0xc00 / f);
+	}
+
+	return true;
+}
+
+/*
  * Check if MSR is intercepted for L01 MSR bitmap.
  */
 static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr)
@@ -2981,6 +3005,13 @@ static int vmx_get_msr(struct kvm_vcpu *
 	case MSR_IA32_TSC:
 		msr_info->data = guest_read_tsc(vcpu);
 		break;
+	case MSR_IA32_SPEC_CTRL:
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has_ibrs(vcpu))
+			return 1;
+
+		msr_info->data = to_vmx(vcpu)->spec_ctrl;
+		break;
 	case MSR_IA32_ARCH_CAPABILITIES:
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has_arch_capabilities(vcpu))
@@ -3091,6 +3122,36 @@ static int vmx_set_msr(struct kvm_vcpu *
 	case MSR_IA32_TSC:
 		kvm_write_tsc(vcpu, msr_info);
 		break;
+	case MSR_IA32_SPEC_CTRL:
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has_ibrs(vcpu))
+			return 1;
+
+		/* The STIBP bit doesn't fault even if it's not advertised */
+		if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
+			return 1;
+
+		vmx->spec_ctrl = data;
+
+		if (!data)
+			break;
+
+		/*
+		 * For non-nested:
+		 * When it's written (to non-zero) for the first time, pass
+		 * it through.
+		 *
+		 * For nested:
+		 * The handling of the MSR bitmap for L2 guests is done in
+		 * nested_vmx_merge_msr_bitmap. We should not touch the
+		 * vmcs02.msr_bitmap here since it gets completely overwritten
+		 * in the merging. We update the vmcs01 here for L1 as well
+		 * since it will end up touching the MSR anyway now.
+		 */
+		vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap,
+					      MSR_IA32_SPEC_CTRL,
+					      MSR_TYPE_RW);
+		break;
 	case MSR_IA32_PRED_CMD:
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has_ibpb(vcpu))
@@ -5239,6 +5300,7 @@ static void vmx_vcpu_reset(struct kvm_vc
 	u64 cr0;
 
 	vmx->rmode.vm86_active = 0;
+	vmx->spec_ctrl = 0;
 
 	vmx->soft_vnmi_blocked = 0;
 
@@ -8824,6 +8886,15 @@ static void __noclone vmx_vcpu_run(struc
 
 	vmx_arm_hv_timer(vcpu);
 
+	/*
+	 * If this vCPU has touched SPEC_CTRL, restore the guest's value if
+	 * it's non-zero. Since vmentry is serialising on affected CPUs, there
+	 * is no need to worry about the conditional branch over the wrmsr
+	 * being speculatively taken.
+	 */
+	if (vmx->spec_ctrl)
+		wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+
 	vmx->__launched = vmx->loaded_vmcs->launched;
 	asm(
 		/* Store host registers */
@@ -8942,6 +9013,27 @@ static void __noclone vmx_vcpu_run(struc
 #endif
 	      );
 
+	/*
+	 * We do not use IBRS in the kernel. If this vCPU has used the
+	 * SPEC_CTRL MSR it may have left it on; save the value and
+	 * turn it off. This is much more efficient than blindly adding
+	 * it to the atomic save/restore list. Especially as the former
+	 * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
+	 *
+	 * For non-nested case:
+	 * If the L01 MSR bitmap does not intercept the MSR, then we need to
+	 * save it.
+	 *
+	 * For nested case:
+	 * If the L02 MSR bitmap does not intercept the MSR, then we need to
+	 * save it.
+	 */
+	if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+		rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+
+	if (vmx->spec_ctrl)
+		wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+
 	/* Eliminate branch target predictions from guest mode */
 	vmexit_fill_RSB();
 
@@ -9501,7 +9593,7 @@ static inline bool nested_vmx_merge_msr_
 	unsigned long *msr_bitmap_l1;
 	unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
 	/*
-	 * pred_cmd is trying to verify two things:
+	 * pred_cmd & spec_ctrl are trying to verify two things:
 	 *
 	 * 1. L0 gave a permission to L1 to actually passthrough the MSR. This
 	 *    ensures that we do not accidentally generate an L02 MSR bitmap
@@ -9514,9 +9606,10 @@ static inline bool nested_vmx_merge_msr_
 	 *    the MSR.
 	 */
 	bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
+	bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
 
 	if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
-	    !pred_cmd)
+	    !pred_cmd && !spec_ctrl)
 		return false;
 
 	page = nested_get_page(vcpu, vmcs12->msr_bitmap);
@@ -9550,6 +9643,12 @@ static inline bool nested_vmx_merge_msr_
 		}
 	}
 
+	if (spec_ctrl)
+		nested_vmx_disable_intercept_for_msr(
+					msr_bitmap_l1, msr_bitmap_l0,
+					MSR_IA32_SPEC_CTRL,
+					MSR_TYPE_R | MSR_TYPE_W);
+
 	if (pred_cmd)
 		nested_vmx_disable_intercept_for_msr(
 					msr_bitmap_l1, msr_bitmap_l0,
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -975,7 +975,7 @@ static u32 msrs_to_save[] = {
 #endif
 	MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
 	MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
-	MSR_IA32_ARCH_CAPABILITIES
+	MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES
 };
 
 static unsigned num_msrs_to_save;

WARNING: multiple messages have this Message-ID (diff)
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, KarimAllah Ahmed <karahmed@amazon.de>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Thomas Gleixner <tglx@linutronix.de>,
	Darren Kenny <darren.kenny@oracle.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Jim Mattson <jmattson@google.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Andi Kleen <ak@linux.intel.com>,
	Jun Nakajima <jun.nakajima@intel.com>,
	kvm@vger.kernel.org, Dave Hansen <dave.hansen@intel.com>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Asit Mallick <asit.k.mallick@intel.com>,
	Arjan Van De Ven <arjan.van.de.ven@intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Ashok Raj <ashok.raj@intel.com>
Subject: [PATCH 4.9 84/92] KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
Date: Fri,  9 Feb 2018 14:39:53 +0100	[thread overview]
Message-ID: <20180209133937.218820152@linuxfoundation.org> (raw)
In-Reply-To: <20180209133931.211869118@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: KarimAllah Ahmed <karahmed@amazon.de>


(cherry picked from commit d28b387fb74da95d69d2615732f50cceb38e9a4d)

[ Based on a patch from Ashok Raj <ashok.raj@intel.com> ]

Add direct access to MSR_IA32_SPEC_CTRL for guests. This is needed for
guests that will only mitigate Spectre V2 through IBRS+IBPB and will not
be using a retpoline+IBPB based approach.

To avoid the overhead of saving and restoring the MSR_IA32_SPEC_CTRL for
guests that do not actually use the MSR, only start saving and restoring
when a non-zero is written to it.

No attempt is made to handle STIBP here, intentionally. Filtering STIBP
may be added in a future patch, which may require trapping all writes
if we don't want to pass it through directly to the guest.

[dwmw2: Clean up CPUID bits, save/restore manually, handle reset]

Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jun Nakajima <jun.nakajima@intel.com>
Cc: kvm@vger.kernel.org
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Asit Mallick <asit.k.mallick@intel.com>
Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ashok Raj <ashok.raj@intel.com>
Link: https://lkml.kernel.org/r/1517522386-18410-5-git-send-email-karahmed@amazon.de
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/cpuid.c |    8 ++-
 arch/x86/kvm/cpuid.h |   11 +++++
 arch/x86/kvm/vmx.c   |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 arch/x86/kvm/x86.c   |    2 
 4 files changed, 118 insertions(+), 6 deletions(-)

--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -357,7 +357,7 @@ static inline int __do_cpuid_ent(struct
 
 	/* cpuid 0x80000008.ebx */
 	const u32 kvm_cpuid_8000_0008_ebx_x86_features =
-		F(IBPB);
+		F(IBPB) | F(IBRS);
 
 	/* cpuid 0xC0000001.edx */
 	const u32 kvm_cpuid_C000_0001_edx_x86_features =
@@ -382,7 +382,7 @@ static inline int __do_cpuid_ent(struct
 
 	/* cpuid 7.0.edx*/
 	const u32 kvm_cpuid_7_0_edx_x86_features =
-		F(ARCH_CAPABILITIES);
+		F(SPEC_CTRL) | F(ARCH_CAPABILITIES);
 
 	/* all calls to cpuid_count() should be made on the same cpu */
 	get_cpu();
@@ -618,9 +618,11 @@ static inline int __do_cpuid_ent(struct
 			g_phys_as = phys_as;
 		entry->eax = g_phys_as | (virt_as << 8);
 		entry->edx = 0;
-		/* IBPB isn't necessarily present in hardware cpuid */
+		/* IBRS and IBPB aren't necessarily present in hardware cpuid */
 		if (boot_cpu_has(X86_FEATURE_IBPB))
 			entry->ebx |= F(IBPB);
+		if (boot_cpu_has(X86_FEATURE_IBRS))
+			entry->ebx |= F(IBRS);
 		entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
 		cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
 		break;
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -171,6 +171,17 @@ static inline bool guest_cpuid_has_ibpb(
 	return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
 }
 
+static inline bool guest_cpuid_has_ibrs(struct kvm_vcpu *vcpu)
+{
+	struct kvm_cpuid_entry2 *best;
+
+	best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+	if (best && (best->ebx & bit(X86_FEATURE_IBRS)))
+		return true;
+	best = kvm_find_cpuid_entry(vcpu, 7, 0);
+	return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+}
+
 static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *best;
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -552,6 +552,7 @@ struct vcpu_vmx {
 #endif
 
 	u64 		      arch_capabilities;
+	u64 		      spec_ctrl;
 
 	u32 vm_entry_controls_shadow;
 	u32 vm_exit_controls_shadow;
@@ -1852,6 +1853,29 @@ static void update_exception_bitmap(stru
 }
 
 /*
+ * Check if MSR is intercepted for currently loaded MSR bitmap.
+ */
+static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
+{
+	unsigned long *msr_bitmap;
+	int f = sizeof(unsigned long);
+
+	if (!cpu_has_vmx_msr_bitmap())
+		return true;
+
+	msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap;
+
+	if (msr <= 0x1fff) {
+		return !!test_bit(msr, msr_bitmap + 0x800 / f);
+	} else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
+		msr &= 0x1fff;
+		return !!test_bit(msr, msr_bitmap + 0xc00 / f);
+	}
+
+	return true;
+}
+
+/*
  * Check if MSR is intercepted for L01 MSR bitmap.
  */
 static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr)
@@ -2981,6 +3005,13 @@ static int vmx_get_msr(struct kvm_vcpu *
 	case MSR_IA32_TSC:
 		msr_info->data = guest_read_tsc(vcpu);
 		break;
+	case MSR_IA32_SPEC_CTRL:
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has_ibrs(vcpu))
+			return 1;
+
+		msr_info->data = to_vmx(vcpu)->spec_ctrl;
+		break;
 	case MSR_IA32_ARCH_CAPABILITIES:
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has_arch_capabilities(vcpu))
@@ -3091,6 +3122,36 @@ static int vmx_set_msr(struct kvm_vcpu *
 	case MSR_IA32_TSC:
 		kvm_write_tsc(vcpu, msr_info);
 		break;
+	case MSR_IA32_SPEC_CTRL:
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has_ibrs(vcpu))
+			return 1;
+
+		/* The STIBP bit doesn't fault even if it's not advertised */
+		if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
+			return 1;
+
+		vmx->spec_ctrl = data;
+
+		if (!data)
+			break;
+
+		/*
+		 * For non-nested:
+		 * When it's written (to non-zero) for the first time, pass
+		 * it through.
+		 *
+		 * For nested:
+		 * The handling of the MSR bitmap for L2 guests is done in
+		 * nested_vmx_merge_msr_bitmap. We should not touch the
+		 * vmcs02.msr_bitmap here since it gets completely overwritten
+		 * in the merging. We update the vmcs01 here for L1 as well
+		 * since it will end up touching the MSR anyway now.
+		 */
+		vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap,
+					      MSR_IA32_SPEC_CTRL,
+					      MSR_TYPE_RW);
+		break;
 	case MSR_IA32_PRED_CMD:
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has_ibpb(vcpu))
@@ -5239,6 +5300,7 @@ static void vmx_vcpu_reset(struct kvm_vc
 	u64 cr0;
 
 	vmx->rmode.vm86_active = 0;
+	vmx->spec_ctrl = 0;
 
 	vmx->soft_vnmi_blocked = 0;
 
@@ -8824,6 +8886,15 @@ static void __noclone vmx_vcpu_run(struc
 
 	vmx_arm_hv_timer(vcpu);
 
+	/*
+	 * If this vCPU has touched SPEC_CTRL, restore the guest's value if
+	 * it's non-zero. Since vmentry is serialising on affected CPUs, there
+	 * is no need to worry about the conditional branch over the wrmsr
+	 * being speculatively taken.
+	 */
+	if (vmx->spec_ctrl)
+		wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+
 	vmx->__launched = vmx->loaded_vmcs->launched;
 	asm(
 		/* Store host registers */
@@ -8942,6 +9013,27 @@ static void __noclone vmx_vcpu_run(struc
 #endif
 	      );
 
+	/*
+	 * We do not use IBRS in the kernel. If this vCPU has used the
+	 * SPEC_CTRL MSR it may have left it on; save the value and
+	 * turn it off. This is much more efficient than blindly adding
+	 * it to the atomic save/restore list. Especially as the former
+	 * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
+	 *
+	 * For non-nested case:
+	 * If the L01 MSR bitmap does not intercept the MSR, then we need to
+	 * save it.
+	 *
+	 * For nested case:
+	 * If the L02 MSR bitmap does not intercept the MSR, then we need to
+	 * save it.
+	 */
+	if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+		rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+
+	if (vmx->spec_ctrl)
+		wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+
 	/* Eliminate branch target predictions from guest mode */
 	vmexit_fill_RSB();
 
@@ -9501,7 +9593,7 @@ static inline bool nested_vmx_merge_msr_
 	unsigned long *msr_bitmap_l1;
 	unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
 	/*
-	 * pred_cmd is trying to verify two things:
+	 * pred_cmd & spec_ctrl are trying to verify two things:
 	 *
 	 * 1. L0 gave a permission to L1 to actually passthrough the MSR. This
 	 *    ensures that we do not accidentally generate an L02 MSR bitmap
@@ -9514,9 +9606,10 @@ static inline bool nested_vmx_merge_msr_
 	 *    the MSR.
 	 */
 	bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
+	bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
 
 	if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
-	    !pred_cmd)
+	    !pred_cmd && !spec_ctrl)
 		return false;
 
 	page = nested_get_page(vcpu, vmcs12->msr_bitmap);
@@ -9550,6 +9643,12 @@ static inline bool nested_vmx_merge_msr_
 		}
 	}
 
+	if (spec_ctrl)
+		nested_vmx_disable_intercept_for_msr(
+					msr_bitmap_l1, msr_bitmap_l0,
+					MSR_IA32_SPEC_CTRL,
+					MSR_TYPE_R | MSR_TYPE_W);
+
 	if (pred_cmd)
 		nested_vmx_disable_intercept_for_msr(
 					msr_bitmap_l1, msr_bitmap_l0,
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -975,7 +975,7 @@ static u32 msrs_to_save[] = {
 #endif
 	MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
 	MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
-	MSR_IA32_ARCH_CAPABILITIES
+	MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES
 };
 
 static unsigned num_msrs_to_save;

  parent reply	other threads:[~2018-02-09 13:39 UTC|newest]

Thread overview: 127+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-09 13:38 [PATCH 4.9 00/92] 4.9.81-stable review Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 01/92] powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 02/92] powerpc/64: Add macros for annotating the destination of rfid/hrfid Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 03/92] powerpc/64: Convert fast_exception_return to use RFI_TO_USER/KERNEL Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 04/92] powerpc/64: Convert the syscall exit path " Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 05/92] powerpc/64s: Convert slb_miss_common " Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 06/92] powerpc/64s: Add support for RFI flush of L1-D cache Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 07/92] powerpc/64s: Support disabling RFI flush with no_rfi_flush and nopti Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 08/92] powerpc/pseries: Query hypervisor for RFI flush settings Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 09/92] powerpc/powernv: Check device-tree " Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 10/92] powerpc/64s: Wire up cpu_show_meltdown() Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 11/92] powerpc/64s: Allow control of RFI flush via debugfs Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 12/92] auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 13/92] pinctrl: pxa: pxa2xx: " Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 14/92] ASoC: pcm512x: " Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 15/92] kaiser: fix intel_bts perf crashes Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 16/92] x86/pti: Make unpoison of pgd for trusted boot work for real Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 17/92] kaiser: allocate pgd with order 0 when pti=off Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 18/92] serial: core: mark port as initialized after successful IRQ change Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 19/92] ip6mr: fix stale iterator Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 20/92] net: igmp: add a missing rcu locking section Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 21/92] qlcnic: fix deadlock bug Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 22/92] qmi_wwan: Add support for Quectel EP06 Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 23/92] r8169: fix RTL8168EP take too long to complete driver initialization Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 24/92] tcp: release sk_frag.page in tcp_disconnect Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 25/92] vhost_net: stop device during reset owner Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 26/92] tcp_bbr: fix pacing_gain to always be unity when using lt_bw Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 27/92] cls_u32: add missing RCU annotation Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 28/92] ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 29/92] soreuseport: fix mem leak in reuseport_add_sock() Greg Kroah-Hartman
2018-02-09 13:38 ` [PATCH 4.9 30/92] x86/asm: Fix inline asm call constraints for GCC 4.4 Greg Kroah-Hartman
2018-02-09 13:38   ` Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 31/92] x86/microcode/AMD: Do not load when running on a hypervisor Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 32/92] media: soc_camera: soc_scale_crop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 33/92] b43: Add missing MODULE_FIRMWARE() Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 34/92] KEYS: encrypted: fix buffer overread in valid_master_desc() Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 35/92] x86/retpoline: Remove the esp/rsp thunk Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 36/92] KVM: x86: Make indirect calls in emulator speculation safe Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 37/92] KVM: VMX: Make indirect call " Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 38/92] module/retpoline: Warn about missing retpoline in module Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 39/92] x86/cpufeatures: Add CPUID_7_EDX CPUID leaf Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 40/92] x86/cpufeatures: Add Intel feature bits for Speculation Control Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 41/92] x86/cpufeatures: Add AMD " Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 42/92] x86/msr: Add definitions for new speculation control MSRs Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 43/92] x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown Greg Kroah-Hartman
2018-02-13 13:34   ` Nick Lowe
2018-02-13 15:00     ` Greg Kroah-Hartman
2018-02-13 15:09       ` Arjan van de Ven
2018-02-13 15:27         ` Nick Lowe
2018-02-13 16:32           ` Greg Kroah-Hartman
2018-02-16 13:15             ` Nick Lowe
2018-02-16 16:56               ` Nick Lowe
2018-02-13 15:56         ` Andi Kleen
2018-02-13 16:02           ` Thomas Gleixner
2018-02-13 16:10             ` Borislav Petkov
2018-02-13 16:18           ` Dave Hansen
2018-02-09 13:39 ` [PATCH 4.9 44/92] x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 45/92] x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 46/92] x86/alternative: Print unadorned pointers Greg Kroah-Hartman
2018-02-09 22:01   ` Kees Cook
2018-02-10  7:23     ` Greg Kroah-Hartman
2018-02-10 19:14       ` Kees Cook
2018-02-10 19:21         ` Borislav Petkov
2018-02-13  9:16           ` Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 47/92] x86/nospec: Fix header guards names Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 48/92] x86/bugs: Drop one "mitigation" from dmesg Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 49/92] x86/cpu/bugs: Make retpoline module warning conditional Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 50/92] x86/cpufeatures: Clean up Spectre v2 related CPUID flags Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 51/92] x86/retpoline: Simplify vmexit_fill_RSB() Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 52/92] x86/spectre: Check CONFIG_RETPOLINE in command line parser Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 53/92] x86/entry/64: Remove the SYSCALL64 fast path Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 54/92] x86/entry/64: Push extra regs right away Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 55/92] x86/asm: Move status from thread_struct to thread_info Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 56/92] Documentation: Document array_index_nospec Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 57/92] array_index_nospec: Sanitize speculative array de-references Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 58/92] x86: Implement array_index_mask_nospec Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 59/92] x86: Introduce barrier_nospec Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 60/92] x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 61/92] x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end} Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 62/92] x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 63/92] x86/get_user: Use pointer masking to limit speculation Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 64/92] x86/syscall: Sanitize syscall table de-references under speculation Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 65/92] vfs, fdtable: Prevent bounds-check bypass via speculative execution Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 66/92] nl80211: Sanitize array index in parse_txq_params Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 67/92] x86/spectre: Report get_user mitigation for spectre_v1 Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 68/92] x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable" Greg Kroah-Hartman
2018-02-09 13:39   ` Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 69/92] x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 70/92] x86/paravirt: Remove noreplace-paravirt cmdline option Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 71/92] x86/kvm: Update spectre-v1 mitigation Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 72/92] x86/retpoline: Avoid retpolines for built-in __init functions Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 73/92] x86/spectre: Simplify spectre_v2 command line parsing Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 74/92] x86/pti: Mark constant arrays as __initconst Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 75/92] x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 76/92] KVM: nVMX: kmap() cant fail Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 77/92] KVM: nVMX: vmx_complete_nested_posted_interrupt() " Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 78/92] KVM: nVMX: mark vmcs12 pages dirty on L2 exit Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 79/92] KVM: nVMX: Eliminate vmcs02 pool Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 80/92] KVM: VMX: introduce alloc_loaded_vmcs Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 81/92] KVM: VMX: make MSR bitmaps per-VCPU Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 82/92] KVM/x86: Add IBPB support Greg Kroah-Hartman
2018-02-09 13:39   ` Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 83/92] KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES Greg Kroah-Hartman
2018-02-09 13:39   ` Greg Kroah-Hartman
2018-02-09 13:39 ` Greg Kroah-Hartman [this message]
2018-02-09 13:39   ` [PATCH 4.9 84/92] KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 85/92] KVM/SVM: " Greg Kroah-Hartman
2018-02-09 13:39   ` Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 86/92] crypto: tcrypt - fix S/G table for test_aead_speed() Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 87/92] ASoC: simple-card: Fix misleading error message Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 88/92] ASoC: rsnd: dont call free_irq() on Parent SSI Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 89/92] ASoC: rsnd: avoid duplicate free_irq() Greg Kroah-Hartman
2018-02-09 13:39 ` [PATCH 4.9 90/92] drm: rcar-du: Use the VBK interrupt for vblank events Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.9 91/92] drm: rcar-du: Fix race condition when disabling planes at CRTC stop Greg Kroah-Hartman
2018-02-09 13:40 ` [PATCH 4.9 92/92] x86/microcode: Do the family check first Greg Kroah-Hartman
2018-02-09 17:36 ` [PATCH 4.9 00/92] 4.9.81-stable review kernelci.org bot
2018-02-09 20:18 ` Shuah Khan
2018-02-09 21:32 ` Dan Rue
2018-02-10 15:46 ` Guenter Roeck
2018-02-13  9:36   ` Greg Kroah-Hartman
2018-02-13 14:30     ` Guenter Roeck
2018-02-13 15:29       ` Greg Kroah-Hartman
2018-02-17 13:31         ` Yves-Alexis Perez
2018-02-17 13:45           ` Greg Kroah-Hartman
2018-02-17 17:35             ` Guenter Roeck
2018-02-18 17:25               ` Yves-Alexis Perez
2018-02-20 10:40               ` Greg Kroah-Hartman

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=20180209133937.218820152@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=aarcange@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=asit.k.mallick@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=darren.kenny@oracle.com \
    --cc=dave.hansen@intel.com \
    --cc=dwmw@amazon.co.uk \
    --cc=jmattson@google.com \
    --cc=jun.nakajima@intel.com \
    --cc=karahmed@amazon.de \
    --cc=konrad.wilk@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundatio \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.