From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Shuai Ruan <shuai.ruan@linux.intel.com>, xen-devel@lists.xen.org
Cc: kevin.tian@intel.com, wei.liu2@citrix.com,
Ian.Campbell@citrix.com, stefano.stabellini@eu.citrix.com,
eddie.dong@intel.com, ian.jackson@eu.citrix.com,
jbeulich@suse.com, jun.nakajima@intel.com, keir@xen.org
Subject: Re: [PATCH V4 2/4] x86/xsaves: enable xsaves/xrstors in xen
Date: Wed, 26 Aug 2015 11:12:02 +0100 [thread overview]
Message-ID: <55DD90F2.9090200@citrix.com> (raw)
In-Reply-To: <1440500087-9852-3-git-send-email-shuai.ruan@linux.intel.com>
On 25/08/15 11:54, Shuai Ruan wrote:
> This patch uses xsaves/xrstors instead of xsaveopt/xrstor
> to perform the xsave_area switching so that xen itself
> can benefit from them when available.
>
> For xsaves/xrstors only use compact format. Add format conversion
> support when perform guest os migration.
>
> Signed-off-by: Shuai Ruan <shuai.ruan@linux.intel.com>
> ---
> xen/arch/x86/domain.c | 2 +
> xen/arch/x86/domctl.c | 34 ++++++++++++---
> xen/arch/x86/hvm/hvm.c | 19 ++++++---
> xen/arch/x86/i387.c | 4 ++
> xen/arch/x86/traps.c | 7 ++--
> xen/arch/x86/xstate.c | 112 ++++++++++++++++++++++++++++++++++---------------
> 6 files changed, 132 insertions(+), 46 deletions(-)
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index 045f6ff..7b8f649 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1529,6 +1529,8 @@ static void __context_switch(void)
> if ( xcr0 != get_xcr0() && !set_xcr0(xcr0) )
> BUG();
> }
> + if ( cpu_has_xsaves )
> + wrmsrl(MSR_IA32_XSS, n->arch.msr_ia32_xss);
This is still not appropriate. You need a per cpu variable and only
perform lazy writes of the MSR.
> vcpu_restore_fpu_eager(n);
> n->arch.ctxt_switch_to(n);
> }
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index bf62a88..da136876 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -867,6 +867,7 @@ long arch_do_domctl(
> if ( domctl->cmd == XEN_DOMCTL_getvcpuextstate )
> {
> unsigned int size;
> + void * xsave_area;
Unnecessary space.
>
> ret = 0;
> vcpu_pause(v);
> @@ -896,9 +897,28 @@ long arch_do_domctl(
> ret = -EFAULT;
>
> offset += sizeof(v->arch.xcr0_accum);
> - if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> - (void *)v->arch.xsave_area,
> - size - 2 * sizeof(uint64_t)) )
> +
> + if ( cpu_has_xsaves )
I think this would be more correct to gate on v->arch.xsave_area
actually being compressed.
> + {
> + xsave_area = xmalloc_bytes(size);
> + if ( !xsave_area )
> + {
> + ret = -ENOMEM;
> + goto vcpuextstate_out;
> + }
> +
> + save_xsave_states(v, xsave_area,
> + evc->size - 2*sizeof(uint64_t));
And on a similar note, save_xsave_states() is really
uncompress_xsave_area(). On further consideration, it should ASSERT()
that the source is currently compressed.
> +
> + if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> + xsave_area, size -
> + 2 * sizeof(uint64_t)) )
> + ret = -EFAULT;
> + xfree(xsave_area);
> + }
> + else if ( !ret && copy_to_guest_offset(evc->buffer, offset,
> + (void *)v->arch.xsave_area,
> + size - 2 * sizeof(uint64_t)) )
> ret = -EFAULT;
>
> vcpu_unpause(v);
> @@ -954,8 +974,12 @@ long arch_do_domctl(
> v->arch.xcr0_accum = _xcr0_accum;
> if ( _xcr0_accum & XSTATE_NONLAZY )
> v->arch.nonlazy_xstate_used = 1;
> - memcpy(v->arch.xsave_area, _xsave_area,
> - evc->size - 2 * sizeof(uint64_t));
> + if ( cpu_has_xsaves )
> + load_xsave_states(v, (void *)_xsave_area,
> + evc->size - 2*sizeof(uint64_t));
Similarly, load_xsave_states() is really compress_xsave_area().
You should check to see whether the area is already compressed, and just
memcpy() in that case.
> + else
> + memcpy(v->arch.xsave_area, (void *)_xsave_area,
> + evc->size - 2 * sizeof(uint64_t));
> vcpu_unpause(v);
> }
> else
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index c957610..dc444ac 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -2148,8 +2148,12 @@ static int hvm_save_cpu_xsave_states(struct domain *d, hvm_domain_context_t *h)
> ctxt->xfeature_mask = xfeature_mask;
> ctxt->xcr0 = v->arch.xcr0;
> ctxt->xcr0_accum = v->arch.xcr0_accum;
> - memcpy(&ctxt->save_area, v->arch.xsave_area,
> - size - offsetof(struct hvm_hw_cpu_xsave, save_area));
> + if ( cpu_has_xsaves )
Stray hard tab.
> + save_xsave_states(v, (void *)&ctxt->save_area,
> + size - offsetof(struct hvm_hw_cpu_xsave,save_area));
These offsetof()s can become far shorter by using offsetof(*ctxt,
save_area).
> diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
> index 9f5a6c6..e9beec1 100644
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -936,9 +936,10 @@ void pv_cpuid(struct cpu_user_regs *regs)
> if ( regs->_ecx == 1 )
> {
> a &= XSTATE_FEATURE_XSAVEOPT |
> - XSTATE_FEATURE_XSAVEC |
> - (cpu_has_xgetbv1 ? XSTATE_FEATURE_XGETBV1 : 0) |
> - (cpu_has_xsaves ? XSTATE_FEATURE_XSAVES : 0);
> + XSTATE_FEATURE_XSAVEC;
> + /* PV guest will not support xsaves. */
> + /* (cpu_has_xgetbv1 ? XSTATE_FEATURE_XGETBV1 : 0) |
> + (cpu_has_xsaves ? XSTATE_FEATURE_XSAVES : 0); */
Don't leave this code commented out like this. Just delete it.
> if ( !cpu_has_xsaves )
> b = c = d = 0;
> }
> diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
> index 3986515..9050607 100644
> --- a/xen/arch/x86/xstate.c
> +++ b/xen/arch/x86/xstate.c
> @@ -214,6 +214,11 @@ void xsave(struct vcpu *v, uint64_t mask)
> typeof(ptr->fpu_sse.fip.sel) fcs = ptr->fpu_sse.fip.sel;
> typeof(ptr->fpu_sse.fdp.sel) fds = ptr->fpu_sse.fdp.sel;
>
> + if ( cpu_has_xsaves )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else
> if ( cpu_has_xsaveopt )
Please join the if() onto the previous line.
> {
> /*
> @@ -267,6 +272,11 @@ void xsave(struct vcpu *v, uint64_t mask)
> }
> else
> {
> + if ( cpu_has_xsaves )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else
> if ( cpu_has_xsaveopt )
And here.
> @@ -466,16 +508,20 @@ void xstate_init(bool_t bsp)
> {
> cpu_has_xsaveopt = !!(eax & XSTATE_FEATURE_XSAVEOPT);
> cpu_has_xsavec = !!(eax & XSTATE_FEATURE_XSAVEC);
> - /* XXX cpu_has_xgetbv1 = !!(eax & XSTATE_FEATURE_XGETBV1); */
> - /* XXX cpu_has_xsaves = !!(eax & XSTATE_FEATURE_XSAVES); */
> + cpu_has_xgetbv1 = !!(eax & XSTATE_FEATURE_XGETBV1);
> + cpu_has_xsaves = !!(eax & XSTATE_FEATURE_XSAVES);
> }
> else
> {
> BUG_ON(!cpu_has_xsaveopt != !(eax & XSTATE_FEATURE_XSAVEOPT));
> BUG_ON(!cpu_has_xsavec != !(eax & XSTATE_FEATURE_XSAVEC));
> - /* XXX BUG_ON(!cpu_has_xgetbv1 != !(eax & XSTATE_FEATURE_XGETBV1)); */
> - /* XXX BUG_ON(!cpu_has_xsaves != !(eax & XSTATE_FEATURE_XSAVES)); */
> + BUG_ON(!cpu_has_xgetbv1 != !(eax & XSTATE_FEATURE_XGETBV1));
> + BUG_ON(!cpu_has_xsaves != !(eax & XSTATE_FEATURE_XSAVES));
> }
> +
> + setup_xstate_features();
> + if ( cpu_has_xsaves )
> + setup_xstate_comp();
setup_state_comp() should only be called on the bsp, and
setup_xstate_features() should have a similar bsp/ap split with
generating or validating state.
~Andrew
next prev parent reply other threads:[~2015-08-26 10:12 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 10:54 [PATCH V4 0/4] add xsaves/xrstors support Shuai Ruan
2015-08-25 10:54 ` [PATCH V4 1/4] x86/xsaves: add basic definitions/helpers to support xsaves Shuai Ruan
2015-08-26 9:47 ` Andrew Cooper
2015-08-26 11:41 ` Jan Beulich
2015-08-26 12:53 ` Jan Beulich
2015-08-28 5:34 ` Shuai Ruan
2015-08-28 2:49 ` Shuai Ruan
2015-08-26 12:55 ` Jan Beulich
2015-08-25 10:54 ` [PATCH V4 2/4] x86/xsaves: enable xsaves/xrstors in xen Shuai Ruan
2015-08-26 10:12 ` Andrew Cooper [this message]
2015-08-26 11:50 ` Jan Beulich
2015-08-26 12:05 ` Andrew Cooper
2015-08-26 12:35 ` Jan Beulich
2015-08-28 5:25 ` Shuai Ruan
2015-08-28 5:22 ` Shuai Ruan
2015-08-26 13:06 ` Jan Beulich
2015-08-28 10:54 ` Shuai Ruan
[not found] ` <20150828105408.GA18437@shuai.ruan@linux.intel.com>
2015-08-28 11:27 ` Jan Beulich
2015-08-25 10:54 ` [PATCH V4 3/4] x86/xsaves: enable xsaves/xrstors for hvm guest Shuai Ruan
2015-08-26 10:36 ` Andrew Cooper
2015-08-28 2:52 ` Shuai Ruan
2015-08-26 13:14 ` Jan Beulich
2015-08-25 10:54 ` [PATCH V4 4/4] libxc: expose xsaves/xgetbv1/xsavec to " Shuai Ruan
2015-08-26 10:43 ` Andrew Cooper
2015-08-26 12:03 ` Jan Beulich
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=55DD90F2.9090200@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=eddie.dong@intel.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=jun.nakajima@intel.com \
--cc=keir@xen.org \
--cc=kevin.tian@intel.com \
--cc=shuai.ruan@linux.intel.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.org \
/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.