|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [V7 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
>>> On 20.10.15 at 10:21, <shuai.ruan@xxxxxxxxxxxxxxx> wrote:
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -2088,6 +2088,8 @@ static int hvm_load_cpu_ctxt(struct domain *d,
> hvm_domain_context_t *h)
>
> memcpy(v->arch.xsave_area, ctxt.fpu_regs, sizeof(ctxt.fpu_regs));
> xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
> + if ( cpu_has_xsaves | cpu_has_xsavec )
> + xsave_area->xsave_hdr.xcomp_bv |= XSTATE_FP_SSE;
Is this really |= ? Not just for similarity with the assignment above I
would expect this to be =, as we don't know what value the field
had before.
Also, are you intentionally using | instead of || in the if() (other than
you do elsewhere in the patch)?
> @@ -2257,10 +2259,9 @@ static int hvm_load_cpu_xsave_states(struct domain *d,
> hvm_domain_context_t *h)
> v->arch.xcr0_accum = ctxt->xcr0_accum;
> if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
> v->arch.nonlazy_xstate_used = 1;
> - memcpy(v->arch.xsave_area, &ctxt->save_area,
> - min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
> - save_area));
> -
> + compress_xsave_states(v, &ctxt->save_area,
> + min(desc->length, size) -
> + offsetof(struct hvm_hw_cpu_xsave,save_area));
> return 0;
Bad removal of a blank line.
> --- a/xen/arch/x86/i387.c
> +++ b/xen/arch/x86/i387.c
> @@ -282,7 +282,11 @@ int vcpu_init_fpu(struct vcpu *v)
> return rc;
>
> if ( v->arch.xsave_area )
> + {
> v->arch.fpu_ctxt = &v->arch.xsave_area->fpu_sse;
> + if ( cpu_has_xsaves || cpu_has_xsavec )
> + v->arch.xsave_area->xsave_hdr.xcomp_bv |=
> XSTATE_COMPACTION_ENABLED;
Again - |= or just = ?
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -935,9 +935,9 @@ void pv_cpuid(struct cpu_user_regs *regs)
> goto unsupported;
> if ( regs->_ecx == 1 )
> {
> - a &= boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32];
> - if ( !cpu_has_xsaves )
> - b = c = d = 0;
> + a &= (boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32] &
> + ~cpufeat_mask(X86_FEATURE_XSAVES));
> + b = c = d = 0;
Considering that now we again seem to be black listing features here,
shouldn't we take the opportunity and convert this tho white listing now?
> +static void __init setup_xstate_comp(void)
> +{
> + unsigned int i;
> +
> + /*
> + * The FP xstates and SSE xstates are legacy states. They are always
> + * in the fixed offsets in the xsave area in either compacted form
> + * or standard form.
> + */
> + xstate_comp_offsets[0] = 0;
> + xstate_comp_offsets[1] = XSAVE_SSE_OFFSET;
> +
> + xstate_comp_offsets[2] = FXSAVE_SIZE + XSAVE_HDR_SIZE;
> +
> + for ( i = 3; i < xstate_features; i++ )
> + {
> + xstate_comp_offsets[i] = xstate_comp_offsets[i-1] +
> + (((1ul << i) & xfeature_mask)
> + ? xstate_sizes[i-1] : 0);
One off indentation. Also in both places "[i - 1]" please.
> + ASSERT(xstate_comp_offsets[i] + xstate_sizes[i] <= xsave_cntxt_size);
> + }
> +}
> +
> +static void *get_xsave_addr(const struct xsave_struct *xsave, unsigned int
> xfeature_idx)
> +{
> + if ( !((1ul << xfeature_idx) & xfeature_mask) )
> + return NULL;
> +
> + return (void *)xsave + xstate_comp_offsets[xfeature_idx];
You should never cast away constness like this. I actually don't see
why the parameter's type can't be (const) void*, avoiding any cast.
> +void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size)
> +{
> + const struct xsave_struct *xsave = v->arch.xsave_area;
> + u64 xstate_bv = xsave->xsave_hdr.xstate_bv;
> + u64 valid;
> +
> + if ( !cpu_has_xsaves && !cpu_has_xsavec )
> + {
> + memcpy(dest, xsave, size);
> + return;
> + }
> +
> + ASSERT(xsave_area_compressed(xsave));
> + /*
> + * Copy legacy XSAVE area, to avoid complications with CPUID
> + * leaves 0 and 1 in the loop below.
> + */
> + memcpy(dest, xsave, FXSAVE_SIZE);
> +
> + ((struct xsave_struct *)dest)->xsave_hdr.xstate_bv = xstate_bv;
> + ((struct xsave_struct *)dest)->xsave_hdr.xcomp_bv = 0;
> +
> + /*
> + * Copy each region from the possibly compacted offset to the
> + * non-compacted offset.
> + */
> + valid = xstate_bv & ~XSTATE_FP_SSE;
> + while ( valid )
> + {
> + u64 feature = valid & -valid;
> + unsigned int index = fls(feature) - 1;
> + void *src = get_xsave_addr(xsave, index);
const
> + if ( src )
> + {
> + ASSERT((xstate_offsets[index] + xstate_sizes[index]) <= size);
> + memcpy(dest + xstate_offsets[index], src, xstate_sizes[index]);
> + }
> +
> + valid &= ~feature;
> + }
> +
> +}
Stray blank line.
> @@ -91,7 +253,15 @@ 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_xsaveopt )
> + if ( cpu_has_xsaves )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else if ( cpu_has_xsavec )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x27"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else if ( cpu_has_xsaveopt )
While the REX.W prefixes are needed here, ...
> @@ -144,7 +314,15 @@ void xsave(struct vcpu *v, uint64_t mask)
> }
> else
> {
> - if ( cpu_has_xsaveopt )
> + if ( cpu_has_xsaves )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x2f"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else if ( cpu_has_xsavec )
> + asm volatile ( ".byte 0x48,0x0f,0xc7,0x27"
> + : "=m" (*ptr)
> + : "a" (lmask), "d" (hmask), "D" (ptr) );
> + else if ( cpu_has_xsaveopt )
> asm volatile ( ".byte 0x0f,0xae,0x37"
... they don't belong here (as also visible from the pre-existing
xsaveopt).
> @@ -187,36 +379,20 @@ void xrstor(struct vcpu *v, uint64_t mask)
> switch ( __builtin_expect(ptr->fpu_sse.x[FPU_WORD_SIZE_OFFSET], 8) )
> {
> default:
> - asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n"
> - ".section .fixup,\"ax\" \n"
> - "2: mov %5,%%ecx \n"
> - " xor %1,%1 \n"
> - " rep stosb \n"
> - " lea %2,%0 \n"
> - " mov %3,%1 \n"
> - " jmp 1b \n"
> - ".previous \n"
> - _ASM_EXTABLE(1b, 2b)
> - : "+&D" (ptr), "+&a" (lmask)
> - : "m" (*ptr), "g" (lmask), "d" (hmask),
> - "m" (xsave_cntxt_size)
> - : "ecx" );
> - break;
> + if ( cpu_has_xsaves )
> + asm volatile ( "1: .byte 0x48,0x0f,0xc7,0x1f\n"
> + XSTATE_FIXUP );
> + else
> + asm volatile ( "1: .byte 0x48,0x0f,0xae,0x2f\n"
> + XSTATE_FIXUP );
> + break;
> case 4: case 2:
> - asm volatile ( "1: .byte 0x0f,0xae,0x2f\n"
> - ".section .fixup,\"ax\" \n"
> - "2: mov %5,%%ecx \n"
> - " xor %1,%1 \n"
> - " rep stosb \n"
> - " lea %2,%0 \n"
> - " mov %3,%1 \n"
> - " jmp 1b \n"
> - ".previous \n"
> - _ASM_EXTABLE(1b, 2b)
> - : "+&D" (ptr), "+&a" (lmask)
> - : "m" (*ptr), "g" (lmask), "d" (hmask),
> - "m" (xsave_cntxt_size)
> - : "ecx" );
> + if ( cpu_has_xsaves )
> + asm volatile ( "1: .byte 0x48,0x0f,0xc7,0x1f\n"
> + XSTATE_FIXUP );
Same here.
Also, #undef XSTATE_FIXUP missing at the end of the function.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |