|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 25/28] x86emul: enable tile management insns for ACE
These are being re-used from AMX, just that with ACE (alone) palette 1
isn't usable, while palette 2 cannot be used with AMX (alone).
While there also introduce the other two X86EMUL_FPU_*ace*, even if only
X86EMUL_FPU_acecfg is needed right here.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
SDE: ???
---
v4: New.
--- a/tools/tests/x86_emulator/evex-disp8.c
+++ b/tools/tests/x86_emulator/evex-disp8.c
@@ -1202,6 +1202,12 @@ static const struct test amx_tile[] = {
INSN(tilestored, f3, 0f38, 4b, el, d, no),
};
+static const struct test ace[] = {
+ /* Element size is set arbitrarily here. See test_one(). */
+ INSN(ldtilecfg, , 0f38, 49, el, b, no),
+ INSN(sttilecfg, 66, 0f38, 49, el, b, no),
+};
+
static const struct test amx_movrs[] = {
/* Element size assumes a 1x1 matrix here. See test_one(). */
INSN(tileloaddrs, f2, 0f38, 4a, el, d, no),
@@ -1842,6 +1848,7 @@ void evex_disp8_test(void *instr, struct
} \
} while ( false )
+ RUN(ace);
RUN(adx);
RUN(amx_movrs);
RUN(amx_tile);
--- a/tools/tests/x86_emulator/x86-emulate.h
+++ b/tools/tests/x86_emulator/x86-emulate.h
@@ -233,6 +233,10 @@ void wrpkru(unsigned int val);
#define cpu_has_cmpccxadd cpu_policy.feat.cmpccxadd
#define cpu_has_avx_ifma (cpu_policy.feat.avx_ifma && xcr0_mask(6))
#define cpu_has_movrs cpu_policy.feat.movrs
+#define cpu_has_ace (cpu_policy.feat.ace && \
+ xcr0_mask(X86_XCR0_TILE_CFG | \
+ X86_XCR0_TILE_DATA | \
+ X86_XCR0_BSR))
#define cpu_has_avx_vnni_int8 (cpu_policy.feat.avx_vnni_int8 && \
xcr0_mask(6))
#define cpu_has_avx_ne_convert (cpu_policy.feat.avx_ne_convert && \
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -621,6 +621,7 @@ amd_like(const struct x86_emulate_ctxt *
#define vcpu_has_msrlist() (ctxt->cpuid->feat.msrlist)
#define vcpu_has_movrs() (ctxt->cpuid->feat.movrs)
#define vcpu_has_msr_imm() (ctxt->cpuid->feat.msr_imm)
+#define vcpu_has_ace() (ctxt->cpuid->feat.ace)
#define vcpu_has_avx_vnni_int8() (ctxt->cpuid->feat.avx_vnni_int8)
#define vcpu_has_avx_ne_convert() (ctxt->cpuid->feat.avx_ne_convert)
#define vcpu_has_amx_complex() (ctxt->cpuid->feat.amx_complex)
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -176,6 +176,7 @@ static void sttilecfg(struct x86_tilecfg
}
#define PALETTE_AMX 1
+#define PALETTE_ACE 2
#define PALETTE(pal...) TOK_OR(1U << PALETTE_, ## pal)
@@ -192,6 +193,9 @@ static bool tile_valid(unsigned int tile
*/
tilecfg->colsb[tile] && tilecfg->rows[tile];
+ case PALETTE_ACE:
+ return (palettes & PALETTE(ACE)) && tile < 8;
+
default:
break;
}
@@ -511,6 +515,10 @@ int x86emul_get_fpu(
switch ( type )
{
+ case X86EMUL_FPU_zmm_ace:
+ if ( !(state->xcr0 & X86_XCR0_BSR) )
+ return X86EMUL_UNHANDLEABLE;
+ fallthrough;
case X86EMUL_FPU_zmm_tile:
ASSERT(mode_64bit());
if ( !(state->xcr0 & X86_XCR0_TILE_CFG) ||
@@ -533,6 +541,11 @@ int x86emul_get_fpu(
return X86EMUL_UNHANDLEABLE;
break;
+ case X86EMUL_FPU_acecfg:
+ case X86EMUL_FPU_ace:
+ if ( !(state->xcr0 & X86_XCR0_BSR) )
+ return X86EMUL_UNHANDLEABLE;
+ fallthrough;
case X86EMUL_FPU_tilecfg:
case X86EMUL_FPU_tile:
ASSERT(mode_64bit());
@@ -579,6 +592,7 @@ int x86emul_get_fpu(
switch ( type )
{
case X86EMUL_FPU_zmm_tile:
+ case X86EMUL_FPU_zmm_ace:
xcr0_needed = X86_XCR0_TILE_DATA;
fallthrough;
default:
@@ -595,9 +609,11 @@ int x86emul_get_fpu(
break;
case X86EMUL_FPU_tilecfg:
+ case X86EMUL_FPU_acecfg:
break;
case X86EMUL_FPU_tile:
+ case X86EMUL_FPU_ace:
xcr0_needed = X86_XCR0_TILE_DATA;
break;
}
@@ -6672,7 +6688,8 @@ x86_emulate(
switch ( modrm )
{
case 0xc0: /* tilerelease */
- vcpu_must_have(amx_tile);
+ if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_tile);
get_fpu(X86EMUL_FPU_tilecfg);
op_bytes = 1; /* fake */
goto simd_0f_common;
@@ -6686,8 +6703,8 @@ x86_emulate(
{
case 0: /* ldtilecfg mem */
generate_exception_if(vex.reg != 0xf, X86_EXC_UD);
- vcpu_must_have(amx_tile);
- get_fpu(X86EMUL_FPU_tilecfg);
+ if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_tile);
rc = ops->read(ea.mem.seg, ea.mem.off, mmvalp, 64, ctxt);
if ( rc != X86EMUL_OKAY )
goto done;
@@ -6697,12 +6714,15 @@ x86_emulate(
switch ( mmvalp->tilecfg.palette )
{
case 0: /* init */
+ get_fpu(X86EMUL_FPU_tilecfg);
break;
case PALETTE_AMX:
{
const typeof(cp->tile.palette1) *palette = &cp->tile.palette1;
+ generate_exception_if(!vcpu_has_amx_tile(), X86_EXC_UD);
+ get_fpu(X86EMUL_FPU_tilecfg);
generate_exception_if(memchr_inv(mmvalp->tilecfg.res, 0,
sizeof(mmvalp->tilecfg.res)),
X86_EXC_GP, 0);
@@ -6729,6 +6749,20 @@ x86_emulate(
break;
}
+ case PALETTE_ACE:
+ generate_exception_if(!vcpu_has_ace(), X86_EXC_UD);
+ get_fpu(X86EMUL_FPU_acecfg);
+ generate_exception_if(memchr_inv(((void *)mmvalp +
+ endof_field(struct
x86_tilecfg,
+ palette)),
+ 0,
+ (sizeof(mmvalp->tilecfg) -
+ endof_field(struct
x86_tilecfg,
+ palette))),
+ X86_EXC_GP, 0);
+
+ break;
+
default:
generate_exception(X86_EXC_GP, 0);
}
@@ -6751,7 +6785,8 @@ x86_emulate(
switch ( modrm_reg & 7 )
{
case 0: /* sttilecfg mem */
- vcpu_must_have(amx_tile);
+ if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_tile);
get_fpu(X86EMUL_FPU_tilecfg);
op_bytes = 64;
goto simd_0f_common;
@@ -6765,11 +6800,12 @@ x86_emulate(
switch ( modrm_rm & 7 )
{
case 0: /* tilezero */
- vcpu_must_have(amx_tile);
+ if ( !vcpu_has_ace() )
+ vcpu_must_have(amx_tile);
get_fpu(X86EMUL_FPU_tile);
sttilecfg(&mmvalp->tilecfg);
generate_exception_if(!tile_valid(modrm_reg, &mmvalp->tilecfg,
- PALETTE(AMX)),
+ PALETTE(AMX, ACE)),
X86_EXC_UD);
op_bytes = 1; /* fake */
goto simd_0f_common;
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -88,6 +88,9 @@ enum x86_emulate_fpu_type {
X86EMUL_FPU_tilecfg, /* AMX configuration (tilecfg) */
X86EMUL_FPU_tile, /* AMX instruction set (%tmm0-%tmmN) */
X86EMUL_FPU_zmm_tile, /* AMX and AVX512/AVX10 instruction sets */
+ X86EMUL_FPU_acecfg, /* ACE configuration (tilecfg) */
+ X86EMUL_FPU_ace, /* ACE instruction set (%tmm0-%tmmN, %bsr0) */
+ X86EMUL_FPU_zmm_ace, /* ACE plus %zmmN */
/* This sentinel will never be passed to ->get_fpu(). */
X86EMUL_FPU_none
};
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |