[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/emul: Don't use the ->cpuid() hook for feature checks
commit 346666c4bdf72ca1d908bbcdb9185981aac7e749 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Thu Jul 19 15:57:41 2018 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Fri May 17 16:37:46 2019 +0100 x86/emul: Don't use the ->cpuid() hook for feature checks For a release build of xen, this removes nearly 5k of code volume, and removes a function pointer call from every instantiation. add/remove: 0/1 grow/shrink: 0/3 up/down: 0/-4822 (-4822) Function old new delta adjust_bnd 260 244 -16 x86_decode 8915 8890 -25 vcpu_has.isra 129 - -129 x86_emulate 130040 125388 -4652 Total: Before=3326565, After=3321743, chg -0.14% Note that one corner case changes. At the moment, it is possible for an entity making direct DOMCTL_set_cpuid hypercalls to construct a policy with max_leaf < 7, but feature bits set in leaf 7. By default, libxc and libxl don't do this, and the result is properly bounded by what the hardware is capable of (so we won't start trying to use instructions which don't exist in the CPU). Previously, the cpuid() hook would end up hiding these features, but they may still be set cpuid_policy, and therefore might start being accepted by x86_emulate(). This corner case will be fixed by the in-progress DOMCTL_set_cpu_policy work, and a guest would only encounter the corner case if it was constructed in a non-standard manner, and if tried using instruction which it couldn't see CPUID feature bits for. As such, it isn't a corner case which we need to worry about. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 143 ++++++++++++--------------------- 1 file changed, 53 insertions(+), 90 deletions(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 23765e602b..154ec1ca26 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1778,92 +1778,58 @@ in_protmode( return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & X86_EFLAGS_VM)); } -#define EAX 0 -#define ECX 1 -#define EDX 2 -#define EBX 3 - -static bool vcpu_has( - unsigned int eax, - unsigned int reg, - unsigned int bit, - struct x86_emulate_ctxt *ctxt, - const struct x86_emulate_ops *ops) -{ - struct cpuid_leaf res; - int rc = X86EMUL_OKAY; - - fail_if(!ops->cpuid); - rc = ops->cpuid(eax, 0, &res, ctxt); - if ( rc == X86EMUL_OKAY ) - { - switch ( reg ) - { - case EAX: reg = res.a; break; - case EBX: reg = res.b; break; - case ECX: reg = res.c; break; - case EDX: reg = res.d; break; - default: BUG(); - } - if ( !(reg & (1U << bit)) ) - rc = ~X86EMUL_OKAY; - } - - done: - return rc == X86EMUL_OKAY; -} - -#define vcpu_has_fpu() vcpu_has( 1, EDX, 0, ctxt, ops) -#define vcpu_has_sep() vcpu_has( 1, EDX, 11, ctxt, ops) -#define vcpu_has_cx8() vcpu_has( 1, EDX, 8, ctxt, ops) -#define vcpu_has_cmov() vcpu_has( 1, EDX, 15, ctxt, ops) -#define vcpu_has_clflush() vcpu_has( 1, EDX, 19, ctxt, ops) -#define vcpu_has_mmx() vcpu_has( 1, EDX, 23, ctxt, ops) -#define vcpu_has_sse() vcpu_has( 1, EDX, 25, ctxt, ops) -#define vcpu_has_sse2() vcpu_has( 1, EDX, 26, ctxt, ops) -#define vcpu_has_sse3() vcpu_has( 1, ECX, 0, ctxt, ops) -#define vcpu_has_pclmulqdq() vcpu_has( 1, ECX, 1, ctxt, ops) -#define vcpu_has_ssse3() vcpu_has( 1, ECX, 9, ctxt, ops) -#define vcpu_has_fma() vcpu_has( 1, ECX, 12, ctxt, ops) -#define vcpu_has_cx16() vcpu_has( 1, ECX, 13, ctxt, ops) -#define vcpu_has_sse4_1() vcpu_has( 1, ECX, 19, ctxt, ops) -#define vcpu_has_sse4_2() vcpu_has( 1, ECX, 20, ctxt, ops) -#define vcpu_has_movbe() vcpu_has( 1, ECX, 22, ctxt, ops) -#define vcpu_has_popcnt() vcpu_has( 1, ECX, 23, ctxt, ops) -#define vcpu_has_aesni() vcpu_has( 1, ECX, 25, ctxt, ops) -#define vcpu_has_avx() vcpu_has( 1, ECX, 28, ctxt, ops) -#define vcpu_has_f16c() vcpu_has( 1, ECX, 29, ctxt, ops) -#define vcpu_has_rdrand() vcpu_has( 1, ECX, 30, ctxt, ops) -#define vcpu_has_mmxext() (vcpu_has(0x80000001, EDX, 22, ctxt, ops) || \ - vcpu_has_sse()) -#define vcpu_has_3dnow_ext() vcpu_has(0x80000001, EDX, 30, ctxt, ops) -#define vcpu_has_3dnow() vcpu_has(0x80000001, EDX, 31, ctxt, ops) -#define vcpu_has_lahf_lm() vcpu_has(0x80000001, ECX, 0, ctxt, ops) -#define vcpu_has_cr8_legacy() vcpu_has(0x80000001, ECX, 4, ctxt, ops) -#define vcpu_has_lzcnt() vcpu_has(0x80000001, ECX, 5, ctxt, ops) -#define vcpu_has_sse4a() vcpu_has(0x80000001, ECX, 6, ctxt, ops) -#define vcpu_has_misalignsse() vcpu_has(0x80000001, ECX, 7, ctxt, ops) -#define vcpu_has_xop() vcpu_has(0x80000001, ECX, 12, ctxt, ops) -#define vcpu_has_fma4() vcpu_has(0x80000001, ECX, 16, ctxt, ops) -#define vcpu_has_tbm() vcpu_has(0x80000001, ECX, 21, ctxt, ops) -#define vcpu_has_bmi1() vcpu_has( 7, EBX, 3, ctxt, ops) -#define vcpu_has_hle() vcpu_has( 7, EBX, 4, ctxt, ops) -#define vcpu_has_avx2() vcpu_has( 7, EBX, 5, ctxt, ops) -#define vcpu_has_bmi2() vcpu_has( 7, EBX, 8, ctxt, ops) -#define vcpu_has_rtm() vcpu_has( 7, EBX, 11, ctxt, ops) -#define vcpu_has_mpx() vcpu_has( 7, EBX, 14, ctxt, ops) -#define vcpu_has_avx512f() vcpu_has( 7, EBX, 16, ctxt, ops) -#define vcpu_has_avx512dq() vcpu_has( 7, EBX, 17, ctxt, ops) -#define vcpu_has_rdseed() vcpu_has( 7, EBX, 18, ctxt, ops) -#define vcpu_has_adx() vcpu_has( 7, EBX, 19, ctxt, ops) -#define vcpu_has_smap() vcpu_has( 7, EBX, 20, ctxt, ops) -#define vcpu_has_clflushopt() vcpu_has( 7, EBX, 23, ctxt, ops) -#define vcpu_has_clwb() vcpu_has( 7, EBX, 24, ctxt, ops) -#define vcpu_has_sha() vcpu_has( 7, EBX, 29, ctxt, ops) -#define vcpu_has_avx512bw() vcpu_has( 7, EBX, 30, ctxt, ops) -#define vcpu_has_avx512vl() vcpu_has( 7, EBX, 31, ctxt, ops) -#define vcpu_has_rdpid() vcpu_has( 7, ECX, 22, ctxt, ops) -#define vcpu_has_clzero() vcpu_has(0x80000008, EBX, 0, ctxt, ops) +#define vcpu_has_fpu() (ctxt->cpuid->basic.fpu) +#define vcpu_has_sep() (ctxt->cpuid->basic.sep) +#define vcpu_has_cx8() (ctxt->cpuid->basic.cx8) +#define vcpu_has_cmov() (ctxt->cpuid->basic.cmov) +#define vcpu_has_clflush() (ctxt->cpuid->basic.clflush) +#define vcpu_has_mmx() (ctxt->cpuid->basic.mmx) +#define vcpu_has_sse() (ctxt->cpuid->basic.sse) +#define vcpu_has_sse2() (ctxt->cpuid->basic.sse2) +#define vcpu_has_sse3() (ctxt->cpuid->basic.sse3) +#define vcpu_has_pclmulqdq() (ctxt->cpuid->basic.pclmulqdq) +#define vcpu_has_ssse3() (ctxt->cpuid->basic.ssse3) +#define vcpu_has_fma() (ctxt->cpuid->basic.fma) +#define vcpu_has_cx16() (ctxt->cpuid->basic.cx16) +#define vcpu_has_sse4_1() (ctxt->cpuid->basic.sse4_1) +#define vcpu_has_sse4_2() (ctxt->cpuid->basic.sse4_2) +#define vcpu_has_movbe() (ctxt->cpuid->basic.movbe) +#define vcpu_has_popcnt() (ctxt->cpuid->basic.popcnt) +#define vcpu_has_aesni() (ctxt->cpuid->basic.aesni) +#define vcpu_has_avx() (ctxt->cpuid->basic.avx) +#define vcpu_has_f16c() (ctxt->cpuid->basic.f16c) +#define vcpu_has_rdrand() (ctxt->cpuid->basic.rdrand) + +#define vcpu_has_mmxext() (ctxt->cpuid->extd.mmxext || vcpu_has_sse()) +#define vcpu_has_3dnow_ext() (ctxt->cpuid->extd._3dnowext) +#define vcpu_has_3dnow() (ctxt->cpuid->extd._3dnow) +#define vcpu_has_lahf_lm() (ctxt->cpuid->extd.lahf_lm) +#define vcpu_has_cr8_legacy() (ctxt->cpuid->extd.cr8_legacy) +#define vcpu_has_lzcnt() (ctxt->cpuid->extd.abm) +#define vcpu_has_sse4a() (ctxt->cpuid->extd.sse4a) +#define vcpu_has_misalignsse() (ctxt->cpuid->extd.misalignsse) +#define vcpu_has_xop() (ctxt->cpuid->extd.xop) +#define vcpu_has_fma4() (ctxt->cpuid->extd.fma4) +#define vcpu_has_tbm() (ctxt->cpuid->extd.tbm) +#define vcpu_has_clzero() (ctxt->cpuid->extd.clzero) + +#define vcpu_has_bmi1() (ctxt->cpuid->feat.bmi1) +#define vcpu_has_hle() (ctxt->cpuid->feat.hle) +#define vcpu_has_avx2() (ctxt->cpuid->feat.avx2) +#define vcpu_has_bmi2() (ctxt->cpuid->feat.bmi2) +#define vcpu_has_rtm() (ctxt->cpuid->feat.rtm) +#define vcpu_has_mpx() (ctxt->cpuid->feat.mpx) +#define vcpu_has_avx512f() (ctxt->cpuid->feat.avx512f) +#define vcpu_has_avx512dq() (ctxt->cpuid->feat.avx512dq) +#define vcpu_has_rdseed() (ctxt->cpuid->feat.rdseed) +#define vcpu_has_adx() (ctxt->cpuid->feat.adx) +#define vcpu_has_smap() (ctxt->cpuid->feat.smap) +#define vcpu_has_clflushopt() (ctxt->cpuid->feat.clflushopt) +#define vcpu_has_clwb() (ctxt->cpuid->feat.clwb) +#define vcpu_has_sha() (ctxt->cpuid->feat.sha) +#define vcpu_has_avx512bw() (ctxt->cpuid->feat.avx512bw) +#define vcpu_has_avx512vl() (ctxt->cpuid->feat.avx512vl) +#define vcpu_has_rdpid() (ctxt->cpuid->feat.rdpid) #define vcpu_must_have(feat) \ generate_exception_if(!vcpu_has_##feat(), EXC_UD) @@ -5519,10 +5485,7 @@ x86_emulate( base = ad_bytes == 8 ? _regs.r(ax) : ad_bytes == 4 ? _regs.eax : _regs.ax; - limit = 0; - if ( vcpu_has_clflush() && - ops->cpuid(1, 0, &cpuid_leaf, ctxt) == X86EMUL_OKAY ) - limit = ((cpuid_leaf.b >> 8) & 0xff) * 8; + limit = ctxt->cpuid->basic.clflush_size * 8; generate_exception_if(limit < sizeof(long) || (limit & (limit - 1)), EXC_UD); base &= ~(limit - 1); -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |