[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [V5 2/4] x86/xsaves: enable xsaves/xrstors/xsavec in xen
>>> On 21.09.15 at 13:33, <shuai.ruan@xxxxxxxxxxxxxxx> 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. Assuming the hardware has XSAVEC but no XSAVES support - why wouldn't we want use XSAVEC in that case? > --- a/xen/arch/x86/domain.c > +++ b/xen/arch/x86/domain.c > @@ -1529,6 +1529,9 @@ static void __context_switch(void) > if ( xcr0 != get_xcr0() && !set_xcr0(xcr0) ) > BUG(); > } > + if ( cpu_has_xsaves ) > + if ( is_hvm_vcpu(n) ) > + set_msr_xss(n->arch.hvm_vcpu.msr_xss); The two if()s should be combined. > --- a/xen/arch/x86/domctl.c > +++ b/xen/arch/x86/domctl.c > @@ -867,7 +867,7 @@ long arch_do_domctl( > if ( domctl->cmd == XEN_DOMCTL_getvcpuextstate ) > { > unsigned int size; > - > + void * xsave_area; > ret = 0; Stray removal of a blank line. Stray blank after *. > @@ -896,9 +896,30 @@ 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 ( !ret && (cpu_has_xsaves || cpu_has_xsavec) && Ah, you actually use it, but don't say so in the description. > + xsave_area_compressed(v->arch.xsave_area) ) > + { > + xsave_area = xmalloc_bytes(size); Perhaps this variable would better be declared here anyway. > + if ( !xsave_area ) > + { > + ret = -ENOMEM; > + vcpu_unpause(v); > + goto vcpuextstate_out; This is unfortunate - it would be better if you could avoid failing the request here. > + } > + > + save_xsave_states(v, xsave_area, > + evc->size - 2*sizeof(uint64_t)); Blanks around * please. > + > + if ( !ret && copy_to_guest_offset(evc->buffer, offset, There's no way for ret to be non-zero at this point. > + xsave_area, size - Hard tabs (more elsewhere). > @@ -954,8 +975,13 @@ 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 || cpu_has_xsavec) && > + !xsave_area_compressed(_xsave_area) ) Is it intended to support compact input here? Where would such come from? And if so, don't you need to validate the input (e.g. being a certain size)? > @@ -2248,9 +2253,15 @@ 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)); > + if ( (cpu_has_xsaves || cpu_has_xsavec) && > + !xsave_area_compressed((struct xsave_struct *)&ctxt->save_area) ) Same questions here. > --- a/xen/arch/x86/traps.c > +++ b/xen/arch/x86/traps.c > @@ -935,10 +935,9 @@ void pv_cpuid(struct cpu_user_regs *regs) > goto unsupported; > 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); > + a &= cpufeat_mask(X86_FEATURE_XSAVEOPT) | > + cpufeat_mask(X86_FEATURE_XSAVEC) | > + (cpu_has_xgetbv1 ? cpufeat_mask(X86_FEATURE_XGETBV1) : 0); I think you indeed mean to drop xsaves here, but then you should say so (i.e. PV unsupported) in the commit message > if ( !cpu_has_xsaves ) > b = c = d = 0; And it would seem that this then needs to become unconditional? > @@ -341,36 +357,68 @@ 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" > + ".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" ); > + else > + 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; > 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" > + ".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" ); > + else > + 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" ); The amount of redundancy calls for some helper macros. > @@ -495,18 +543,24 @@ void xstate_init(bool_t bsp) > cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx); > if ( 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_xsaveopt = !!(eax & cpufeat_mask(X86_FEATURE_XSAVEOPT)); > + cpu_has_xsavec = !!(eax & cpufeat_mask(X86_FEATURE_XSAVEC)); > + cpu_has_xgetbv1 = !!(eax & cpufeat_mask(X86_FEATURE_XGETBV1)); > + cpu_has_xsaves = !!(eax & cpufeat_mask(X86_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_xsaveopt != !(eax & > cpufeat_mask(X86_FEATURE_XSAVEOPT))); > + BUG_ON(!cpu_has_xsavec != !(eax & cpufeat_mask(X86_FEATURE_XSAVEC))); > + BUG_ON(!cpu_has_xgetbv1 != !(eax & > cpufeat_mask(X86_FEATURE_XGETBV1))); > + BUG_ON(!cpu_has_xsaves != !(eax & cpufeat_mask(X86_FEATURE_XSAVES))); > } > + > + if( setup_xstate_features(bsp) ) > + BUG(); > + > + if ( bsp && (cpu_has_xsaves || cpu_has_xsavec) ) > + setup_xstate_comp(); Implying that the function should be annotated __init in patch 1. With it being static there without having a caller, it also means things wouldn't build with just patch 1 applied. This needs to be addressed. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |