linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Yang Weijiang <weijiang.yang@intel.com>
Cc: pbonzini@redhat.com, rkrcmar@redhat.com, jmattson@google.com,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	mst@redhat.com, yu-cheng.yu@intel.com
Subject: Re: [PATCH v3 8/8] KVM:X86: Add user-space read/write interface for CET MSRs.
Date: Fri, 8 Mar 2019 09:30:45 -0800	[thread overview]
Message-ID: <20190308173044.GD2528@linux.intel.com> (raw)
In-Reply-To: <20190228094152.GE12006@local-michael-cet-test.sh.intel.com>

[-- Attachment #1: Type: text/plain, Size: 2050 bytes --]

On Thu, Feb 28, 2019 at 05:41:52PM +0800, Yang Weijiang wrote:
> On Thu, Feb 28, 2019 at 08:32:49AM -0800, Sean Christopherson wrote:
> > On Mon, Feb 25, 2019 at 09:27:16PM +0800, Yang Weijiang wrote:

...

> > >  static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
> > > -		    struct kvm_msr_entry *entries,
> > > +		    struct kvm_msr_entry *entries, bool read,
> > >  		    int (*do_msr)(struct kvm_vcpu *vcpu,
> > >  				  unsigned index, u64 *data))
> > >  {
> > >  	int i;
> > >  
> > > -	for (i = 0; i < msrs->nmsrs; ++i)
> > > +	for (i = 0; i < msrs->nmsrs; ++i) {
> > > +		/* If it comes to CET related MSRs, read them together. */
> > > +		if (entries[i].index == MSR_IA32_U_CET) {
> > > +			i += do_cet_msrs(vcpu, i, entries, read) - 1;
> > 
> > This wrong, not to mention horribly buggy.  The correct way to handle
> > MSRs that are switched via the VMCS is to read/write the VMCS in
> > vmx_{get,set}_msr() as needed, e.g. vmcs_writel(GUEST_GS_BASE, data).
> >
> The code is barely for migration purpose since they're passed through
> to guest, I have no intent to expose them just like normal MSRs.
> I double checked the spec.:
> MSR_IA32_U_CET                  0x6a0
> MSR_IA32_PL0_SSP                0x6a4
> MSR_IA32_PL3_SSP                0x6a7
> should come from xsave area.
> 
> MSR_IA32_S_CET                  0x6a2
> MSR_IA32_INTR_SSP_TABL          0x6a8
> should come from VMCS guest fields.
> 
> for the former, they're stored in guest fpu area, need
> to restore them with xrstors temporarily before read, while the later is stored in
> VMCS guest fields, I can read them out via vmcs_read() directly.
> 
> I'd like to read them out as a whole(all or nothing) due to cost induced 
> by xsaves/xrstors, in Qemu I put these MSRs as sequential fields.
> 
> what do you think of it?

It doesn't need to be all or nothing, it should be simple enough to set
a flag when we load guest state and use it to skip reloading guest state
and to load host state before returning.  I think the attached patch
does the trick.

[-- Attachment #2: 0001-KVM-x86-load-guest-fpu-state-when-accessing-MSRs-man.patch --]
[-- Type: text/x-diff, Size: 3738 bytes --]

From dc3064e6a73951feae52b47dc1b44a50ae589339 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <sean.j.christopherson@intel.com>
Date: Fri, 8 Mar 2019 09:12:07 -0800
Subject: [PATCH] KVM: x86: load guest fpu state when accessing MSRs managed by
 XSAVES

A handful of CET MSRs are not context switched through "traditional"
methods, e.g. VMCS or manual switching, but rather are passed through
to the guest and are saved and restored by XSAVES/XRSTORS, i.e. the
guest's FPU state.

Load the guest's FPU state if userspace is accessing MSRs whose values
are managed by XSAVES so that the MSR helper, e.g. vmx_{get,set}_msr(),
can simply do {RD,WR}MSR to access the guest's value.

Note that guest_cpuid_has() is not queried as host userspace is allowed
to access MSRs that have not been exposed to the guest, e.g. it might do
KVM_SET_MSRS prior to KVM_SET_CPUID2.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 arch/x86/kvm/x86.c | 65 +++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d90f011f3e32..e0d48f22edd9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2901,6 +2901,38 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 }
 EXPORT_SYMBOL_GPL(kvm_get_msr_common);
 
+static bool is_xsaves_msr(u32 index)
+{
+	if (!kvm_x86_ops->xsaves_supported())
+		return false;
+
+	return index == MSR_IA32_U_CET ||
+	       (index >= MSR_IA32_PL0_SSP && index <= MSR_IA32_PL3_SSP);
+}
+
+/* Swap (qemu) user FPU context for the guest FPU context. */
+static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
+{
+	preempt_disable();
+	copy_fpregs_to_fpstate(&current->thread.fpu);
+	/* PKRU is separately restored in kvm_x86_ops->run.  */
+	__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu->state,
+				~XFEATURE_MASK_PKRU);
+	preempt_enable();
+	trace_kvm_fpu(1);
+}
+
+/* When vcpu_run ends, restore user space FPU context. */
+static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
+{
+	preempt_disable();
+	copy_fpregs_to_fpstate(vcpu->arch.guest_fpu);
+	copy_kernel_to_fpregs(&current->thread.fpu.state);
+	preempt_enable();
+	++vcpu->stat.fpu_reload;
+	trace_kvm_fpu(0);
+}
+
 /*
  * Read or write a bunch of msrs. All parameters are kernel addresses.
  *
@@ -2911,11 +2943,19 @@ static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs,
 		    int (*do_msr)(struct kvm_vcpu *vcpu,
 				  unsigned index, u64 *data))
 {
+	bool fpu_loaded = false;
 	int i;
 
-	for (i = 0; i < msrs->nmsrs; ++i)
+	for (i = 0; i < msrs->nmsrs; ++i) {
+		if (!fpu_loaded && is_xsaves_msr(entries[i].index)) {
+			kvm_load_guest_fpu(vcpu);
+			fpu_loaded = true;
+		}
 		if (do_msr(vcpu, entries[i].index, &entries[i].data))
 			break;
+	}
+	if (fpu_loaded)
+		kvm_put_guest_fpu(vcpu);
 
 	return i;
 }
@@ -8116,29 +8156,6 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-/* Swap (qemu) user FPU context for the guest FPU context. */
-static void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
-{
-	preempt_disable();
-	copy_fpregs_to_fpstate(&current->thread.fpu);
-	/* PKRU is separately restored in kvm_x86_ops->run.  */
-	__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu->state,
-				~XFEATURE_MASK_PKRU);
-	preempt_enable();
-	trace_kvm_fpu(1);
-}
-
-/* When vcpu_run ends, restore user space FPU context. */
-static void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
-{
-	preempt_disable();
-	copy_fpregs_to_fpstate(vcpu->arch.guest_fpu);
-	copy_kernel_to_fpregs(&current->thread.fpu.state);
-	preempt_enable();
-	++vcpu->stat.fpu_reload;
-	trace_kvm_fpu(0);
-}
-
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	int r;
-- 
2.21.0


      reply	other threads:[~2019-03-08 17:30 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-25 13:27 [PATCH v3 0/8] This patch-set is to enable Guest CET support Yang Weijiang
2019-02-25 13:27 ` [PATCH v3 1/8] KVM:VMX: Define CET VMCS fields and bits Yang Weijiang
2019-02-26 19:31   ` Jim Mattson
2019-02-26  7:52     ` Yang Weijiang
2019-02-28 15:53     ` Sean Christopherson
2019-02-28  9:51       ` Yang Weijiang
2019-02-25 13:27 ` [PATCH v3 2/8] KVM:CPUID: Define CET CPUID bits and CR4.CET master enable bit Yang Weijiang
2019-02-26 19:48   ` Jim Mattson
2019-02-26  7:57     ` Yang Weijiang
2019-03-01  2:15       ` Xiaoyao Li
2019-02-28 16:04   ` Sean Christopherson
2019-02-28  8:10     ` Yang Weijiang
2019-02-25 13:27 ` [PATCH v3 3/8] KVM:CPUID: Add CPUID support for Guest CET Yang Weijiang
2019-02-28 15:59   ` Sean Christopherson
2019-02-28  8:28     ` Yang Weijiang
2019-03-01 14:53       ` Sean Christopherson
2019-03-03  9:36         ` Yang Weijiang
2019-03-04 18:28           ` Sean Christopherson
2019-03-04 12:17             ` Yang Weijiang
2019-03-04 18:47   ` Sean Christopherson
2019-03-04 10:01     ` Yang Weijiang
2019-03-04 18:54     ` Sean Christopherson
2019-03-04 10:11       ` Yang Weijiang
2019-03-08 11:32   ` Paolo Bonzini
2019-03-10 12:18     ` Yang Weijiang
2019-02-25 13:27 ` [PATCH v3 4/8] KVM:CPUID: Fix xsaves area size calculation for CPUID.(EAX=0xD,ECX=1) Yang Weijiang
2019-02-25 13:27 ` [PATCH v3 5/8] KVM:VMX: Pass through host CET related MSRs to Guest Yang Weijiang
2019-03-04 18:53   ` Sean Christopherson
2019-03-04 10:07     ` Yang Weijiang
2019-03-05  3:21       ` Sean Christopherson
2019-02-25 13:27 ` [PATCH v3 6/8] KVM:VMX: Load Guest CET via VMCS when CET is enabled in Guest Yang Weijiang
2019-02-28 16:17   ` Sean Christopherson
2019-02-28  8:38     ` Yang Weijiang
2019-03-01 14:58       ` Sean Christopherson
2019-03-03 12:26         ` Yang Weijiang
2019-03-04 18:43           ` Sean Christopherson
2019-03-04  9:56             ` Yang Weijiang
2019-03-05  3:12               ` Sean Christopherson
2019-03-04 12:36                 ` Yang Weijiang
2019-03-08 16:28                   ` Sean Christopherson
2019-03-08 16:36                     ` Paolo Bonzini
2019-02-25 13:27 ` [PATCH v3 7/8] KVM:X86: Add XSS bit 11 and 12 support for CET xsaves/xrstors Yang Weijiang
2019-02-28 16:25   ` Sean Christopherson
2019-02-28  8:44     ` Yang Weijiang
2019-03-08 11:32       ` Paolo Bonzini
2019-03-10 12:20         ` Yang Weijiang
2019-03-10 13:35           ` Yang Weijiang
2019-03-11 15:32             ` Paolo Bonzini
2019-03-12 14:30               ` Yang Weijiang
2019-03-08 10:49   ` Paolo Bonzini
2019-03-11  1:29     ` Kang, Luwei
2019-02-25 13:27 ` [PATCH v3 8/8] KVM:X86: Add user-space read/write interface for CET MSRs Yang Weijiang
2019-02-28 16:32   ` Sean Christopherson
2019-02-28  9:41     ` Yang Weijiang
2019-03-08 17:30       ` Sean Christopherson [this message]

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=20190308173044.GD2528@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=weijiang.yang@intel.com \
    --cc=yu-cheng.yu@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).