[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 14/22] x86emul: introduce X86EMUL_FPU_{tilecfg,tile}
These will be used by AMX insns. They're not sensitive to CR0.TS, but instead some are sensitive to XFD. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- v3: Separate X86EMUL_FPU_tilecfg. Use XFD alternative logic instead of checking CR0.TS. v2: New. --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1420,6 +1420,13 @@ static int _get_fpu( return X86EMUL_UNHANDLEABLE; break; + case X86EMUL_FPU_tilecfg: + case X86EMUL_FPU_tile: + ASSERT(mode_64bit()); + if ( !(xcr0 & X86_XCR0_TILECFG) || !(xcr0 & X86_XCR0_TILEDATA) ) + return X86EMUL_UNHANDLEABLE; + break; + default: break; } @@ -1429,6 +1436,7 @@ static int _get_fpu( if ( rc == X86EMUL_OKAY ) { unsigned long cr0; + uint64_t xcr0_needed = 0; fail_if(type == X86EMUL_FPU_fpu && !ops->put_fpu); @@ -1453,15 +1461,45 @@ static int _get_fpu( /* Should be unreachable if VEX decoding is working correctly. */ ASSERT((cr0 & X86_CR0_PE) && !(ctxt->regs->eflags & X86_EFLAGS_VM)); } - if ( cr0 & X86_CR0_EM ) + + switch ( type ) + { + default: + if ( cr0 & X86_CR0_EM ) + { + generate_exception_if(type == X86EMUL_FPU_fpu, EXC_NM); + generate_exception_if(type == X86EMUL_FPU_mmx, EXC_UD); + generate_exception_if(type == X86EMUL_FPU_xmm, EXC_UD); + } + generate_exception_if((cr0 & X86_CR0_TS) && + (type != X86EMUL_FPU_wait || + (cr0 & X86_CR0_MP)), + EXC_NM); + break; + + case X86EMUL_FPU_tilecfg: + break; + + case X86EMUL_FPU_tile: + xcr0_needed = X86_XCR0_TILEDATA; + break; + } + + if ( xcr0_needed && ctxt->cpuid->xstate.xfd ) { - generate_exception_if(type == X86EMUL_FPU_fpu, EXC_NM); - generate_exception_if(type == X86EMUL_FPU_mmx, EXC_UD); - generate_exception_if(type == X86EMUL_FPU_xmm, EXC_UD); + uint64_t xfd; + + fail_if(!ops->read_msr); + rc = ops->read_msr(MSR_XFD, &xfd, ctxt); + if ( rc == X86EMUL_OKAY && (xfd & xcr0_needed) ) + { + fail_if(!ops->write_msr); + rc = ops->read_msr(MSR_XFD_ERR, &xfd, ctxt); + if ( rc == X86EMUL_OKAY ) + rc = ops->write_msr(MSR_XFD_ERR, xfd | xcr0_needed, ctxt); + generate_exception_if(rc == X86EMUL_OKAY, EXC_NM); + } } - generate_exception_if((cr0 & X86_CR0_TS) && - (type != X86EMUL_FPU_wait || (cr0 & X86_CR0_MP)), - EXC_NM); } done: --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -172,6 +172,8 @@ enum x86_emulate_fpu_type { X86EMUL_FPU_ymm, /* AVX/XOP instruction set (%ymm0-%ymm7/15) */ X86EMUL_FPU_opmask, /* AVX512 opmask instruction set (%k0-%k7) */ X86EMUL_FPU_zmm, /* AVX512 instruction set (%zmm0-%zmm7/31) */ + X86EMUL_FPU_tilecfg, /* AMX configuration (tilecfg) */ + X86EMUL_FPU_tile, /* AMX instruction set (%tmm0-%tmmN) */ /* This sentinel will never be passed to ->get_fpu(). */ X86EMUL_FPU_none };
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |