|
[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 |