Historical speck list archives
 help / color / mirror / Atom feed
From: Jim Mattson <jmattson@google.com>
To: speck@linutronix.de
Subject: [MODERATED] [PATCH 1/2] Guest L1D flush
Date: Wed, 8 Aug 2018 12:14:20 -0700	[thread overview]
Message-ID: <CALMp9eQDUArTnMYhGo5awSJx5XK=5+5nMFi=CbU0H6Pz8gZOag@mail.gmail.com> (raw)

[patch 1/2] kvm: vmx: Add IA32_FLUSH_CMD guest support

Expose IA32_FLUSH_CMD to the guest if the guest CPUID enumerates
support for this MSR. As with IA32_PRED_CMD, permission for
unintercepted writes to this MSR will be granted to the guest after
the first non-zero write.

Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Ben Serebrin <serebrin@google.com>
Reviewed-by: Peter Shier <pshier@google.com>
---
 arch/x86/kvm/vmx.c | 44 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 58bba7a7572ad..66304555ce9fa 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3996,6 +3996,28 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
 static void vmx_leave_nested(struct kvm_vcpu *vcpu);
 
+static bool valid_msr_setting(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+{
+	bool valid;
+
+	switch (msr_info->index) {
+	case MSR_IA32_PRED_CMD:
+		valid = (msr_info->host_initiated ||
+			 guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) &&
+			!(msr_info->data & ~PRED_CMD_IBPB);
+		break;
+	case MSR_IA32_FLUSH_CMD:
+		valid = (msr_info->host_initiated ||
+			 guest_cpuid_has(vcpu, X86_FEATURE_FLUSH_L1D)) &&
+			!(msr_info->data & ~L1D_FLUSH);
+		break;
+	default:
+		valid = false;
+		break;
+	}
+	return valid;
+}
+
 /*
  * Writes msr value into into the appropriate "register".
  * Returns 0 on success, non-0 otherwise.
@@ -4077,17 +4099,14 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 					      MSR_TYPE_RW);
 		break;
 	case MSR_IA32_PRED_CMD:
-		if (!msr_info->host_initiated &&
-		    !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL))
-			return 1;
-
-		if (data & ~PRED_CMD_IBPB)
+	case MSR_IA32_FLUSH_CMD:
+		if (!valid_msr_setting(vcpu, msr_info))
 			return 1;
 
 		if (!data)
 			break;
 
-		wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB);
+		wrmsrl(msr_index, data);
 
 		/*
 		 * For non-nested:
@@ -4100,7 +4119,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		 * vmcs02.msr_bitmap here since it gets completely overwritten
 		 * in the merging.
 		 */
-		vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD,
+		vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, msr_index,
 					      MSR_TYPE_W);
 		break;
 	case MSR_IA32_ARCH_CAPABILITIES:
@@ -11091,7 +11110,7 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 	unsigned long *msr_bitmap_l1;
 	unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
 	/*
-	 * pred_cmd & spec_ctrl are trying to verify two things:
+	 * pred_cmd, flush_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
@@ -11104,6 +11123,7 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 	 *    the MSR.
 	 */
 	bool pred_cmd = !msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
+	bool flush_cmd = !msr_write_intercepted_l01(vcpu, MSR_IA32_FLUSH_CMD);
 	bool spec_ctrl = !msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
 
 	/* Nothing to do if the MSR bitmap is not in use.  */
@@ -11112,7 +11132,7 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 		return false;
 
 	if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
-	    !pred_cmd && !spec_ctrl)
+	    !pred_cmd && !flush_cmd && !spec_ctrl)
 		return false;
 
 	page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->msr_bitmap);
@@ -11167,6 +11187,12 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 					MSR_IA32_PRED_CMD,
 					MSR_TYPE_W);
 
+	if (flush_cmd)
+		nested_vmx_disable_intercept_for_msr(
+					msr_bitmap_l1, msr_bitmap_l0,
+					MSR_IA32_FLUSH_CMD,
+					MSR_TYPE_W);
+
 	kunmap(page);
 	kvm_release_page_clean(page);
 
-- 
2.18.0.597.ga71716f1ad-goog

             reply	other threads:[~2018-08-08 19:14 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-08 19:14 Jim Mattson [this message]
2018-08-08 20:40 ` [PATCH 1/2] Guest L1D flush Thomas Gleixner

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='CALMp9eQDUArTnMYhGo5awSJx5XK=5+5nMFi=CbU0H6Pz8gZOag@mail.gmail.com' \
    --to=jmattson@google.com \
    --cc=speck@linutronix.de \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).