All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sheng Yang <sheng@linux.intel.com>
To: Avi Kivity <avi@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>,
	kvm@vger.kernel.org, Dexuan Cui <dexuan.cui@intel.com>
Subject: Re: [PATCH v4] KVM: VMX: Enable XSAVE/XRSTORE for guest
Date: Tue, 25 May 2010 14:28:04 +0800	[thread overview]
Message-ID: <201005251428.04300.sheng@linux.intel.com> (raw)
In-Reply-To: <4BFA80CC.9070800@redhat.com>

On Monday 24 May 2010 21:36:12 Avi Kivity wrote:
> On 05/24/2010 01:03 PM, Sheng Yang wrote:
> > From: Dexuan Cui<dexuan.cui@intel.com>
> > 
> > Enable XSAVE/XRSTORE for guest.
> > 
> > Change from V3:
> > 1. Enforced the assumption that host OS would use all available xstate
> > bits. 2. Various fixes, addressed Avi's comments.
> > 
> > I am still not clear about why we need to reload guest xcr0 when
> > cr4.osxsave set...
> 
> When cr4.osxsave=0, then the guest executes with the host xcr0 (since
> xgetbv will trap; this is similar to the guest running with the host fpu
> if cr0.ts=0).  So if cr4.osxsave transtions, we need to transition xcr0
> as well.

Yes...
> 
> > @@ -3354,6 +3356,29 @@ static int handle_wbinvd(struct kvm_vcpu *vcpu)
> > 
> >   	return 1;
> >   
> >   }
> > 
> > +static int handle_xsetbv(struct kvm_vcpu *vcpu)
> > +{
> > +	u64 new_bv = kvm_read_edx_eax(vcpu);
> > +
> > +	if (kvm_register_read(vcpu, VCPU_REGS_RCX) != 0)
> > +		goto err;
> > +	if (vmx_get_cpl(vcpu) != 0)
> > +		goto err;
> > +	if (!(new_bv&  XSTATE_FP))
> > +		goto err;
> > +	if ((new_bv&  XSTATE_YMM)&&  !(new_bv&  XSTATE_SSE))
> > +		goto err;
> > +	if (new_bv&  ~XCNTXT_MASK)
> > +		goto err;
> 
> Ok.  This means we must update kvm immediately when XCNTXT_MASK changes.
> 
> (Otherwise we would use KVM_XCNTXT_MASK which is always smaller than
> than XCNTXT_MASK).

I guess use host_xcr0 here is better?
> 
> > +	vcpu->arch.xcr0 = new_bv;
> > +	xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);
> > +	skip_emulated_instruction(vcpu);
> > +	return 1;
> > +err:
> > +	kvm_inject_gp(vcpu, 0);
> > +	return 1;
> > +}
> > +
> > 
> > 
> > @@ -4124,6 +4176,8 @@ int kvm_arch_init(void *opaque)
> > 
> >   	perf_register_guest_info_callbacks(&kvm_guest_cbs);
> > 
> > +	host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
> > +
> > 
> >   	return 0;
> 
> Will fault on old cpu.

...
> 
> >   EXPORT_SYMBOL_GPL(fx_init);
> > 
> > @@ -5134,6 +5195,12 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
> > 
> >   	vcpu->guest_fpu_loaded = 1;
> >   	unlazy_fpu(current);
> > 
> > +	/*
> > +	 * Restore all possible states in the guest,
> > +	 * and assume host would use all available bits.
> > +	 */
> > +	if (cpu_has_xsave&&  vcpu->arch.xcr0)
> > +		xsetbv(XCR_XFEATURE_ENABLED_MASK, host_xcr0);
> > 
> >   	fpu_restore_checking(&vcpu->arch.guest_fpu);
> 
> I think we need to reload xcr0 now to the guest's value.
> 
> >   	trace_kvm_fpu(1);
> >   
> >   }
> > 
> > @@ -5144,6 +5211,13 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
> > 
> >   		return;
> >   	
> >   	vcpu->guest_fpu_loaded = 0;
> > 
> > +	/*
> > +	 * Save all possible states in the guest,
> > +	 * and assume host would use all available bits.
> > +	 * Also load host_xcr0 for host usage.
> > +	 */
> > +	if (cpu_has_xsave&&  vcpu->arch.xcr0)
> > +		xsetbv(XCR_XFEATURE_ENABLED_MASK, host_xcr0);
> > 
> >   	fpu_save_init(&vcpu->arch.guest_fpu);
> >   	++vcpu->stat.fpu_reload;
> >   	set_bit(KVM_REQ_DEACTIVATE_FPU,&vcpu->requests);
> 
> This might be unnecessary.
> 
> So far xcr0 life cycle is almost that of
> save_host_state()/load_host_state(), but not exactly.  When loading the
> guest fpu we switch temporarily to host xcr0, then we have to switch
> back, but only if gcr4.osxsave.  When saving the guest fpu, we're
> 
> already using the host xcr0:
> > void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> > {
> > 
> >     kvm_x86_ops->vcpu_put(vcpu);
> >     kvm_put_guest_fpu(vcpu);
> > 
> > }
> 
> One way to simplify this is to have a vcpu->guest_xcr0_loaded flag and
> check it when needed.  So the transition matrix is:
> 
>    save_host_state: if gcr4.osxsave, set guest_xcr0_loaded, load it
>    set gcr4.osxsave: ditto
>    clear gcr4.osxsave: do nothing
>    load_host_state: if guest_xcr0_loaded, clear it, reload host xcr0
>    fpu switching: if (switched) switch; reload fpu; if (switched) switch
> 
> may be simplified if we move xcr0 reload back to guest entry (... :)
> but make it lazy:
> 
>    save_host_state: nothing
>    set cr4.osxsave: nothing
>    clear cr4.osxsave: nothing
>    guest entry: if (gcr4.osxsave && !guest_xcr0_loaded) {
> guest_xcr0_loaded = true, load gxcr0 }
>    load_host_state: if (guest_xcr0_loaded) { guest_xcr0_loaded = false;
> load host xcr0 }
>    fpu switching:  if (guest_xcr0_loaded) { guest_xcr0_loaded = false;
> load host xcr0 }, do fpu stuff
> 
> So we delay xcr0 reload as late as possible for both entry and exit.

I think I got it. But why we need do it at "load_host_state()"? I guess just put 
code before fpu testing in kvm_put_guest_fpu() is fine?

--
regards
Yang, Sheng

  parent reply	other threads:[~2010-05-25  6:26 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-24 10:03 [PATCH v4] KVM: VMX: Enable XSAVE/XRSTORE for guest Sheng Yang
2010-05-24 13:36 ` Avi Kivity
2010-05-24 13:40   ` Avi Kivity
2010-05-25  6:28   ` Sheng Yang [this message]
2010-05-25  7:14     ` Avi Kivity
2010-05-24 13:47 ` Avi Kivity

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=201005251428.04300.sheng@linux.intel.com \
    --to=sheng@linux.intel.com \
    --cc=avi@redhat.com \
    --cc=dexuan.cui@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.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 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.