diff mbox series

[v3,18/22] x86emul: support TILEZERO

Message ID d9d2a273-e366-c007-ddbd-a94ba3c18fb5@suse.com (mailing list archive)
State New
Headers show
Series xvmalloc() / x86 xstate area / x86 CPUID / AMX+XFD | expand

Commit Message

Jan Beulich April 22, 2021, 2:55 p.m. UTC
This is relatively straightforward, and hence best suited to introduce a
few other wider use pieces.

Testing of this will be added once a sensible test can be put together,
i.e. when support for at least TILELOADD (to allow loading non-zero
values in the first place) is also there.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v3: New.
diff mbox series

Patch

--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -1338,6 +1338,7 @@  static const struct vex {
     { { 0x49, 0x00 }, 2, F, R, pfx_no, W0, L0 }, /* ldtilecfg */
     { { 0x49, 0x00 }, 2, F, W, pfx_66, W0, L0 }, /* sttilecfg */
     { { 0x49, 0xc0 }, 2, F, N, pfx_no, W0, L0 }, /* tilerelease */
+    { { 0x49, 0xc0 }, 2, F, N, pfx_f2, W0, L0 }, /* tilezero */
     { { 0x50 }, 2, T, R, pfx_66, W0, Ln }, /* vpdpbusd */
     { { 0x51 }, 2, T, R, pfx_66, W0, Ln }, /* vpdpbusds */
     { { 0x52 }, 2, T, R, pfx_66, W0, Ln }, /* vpdpwssd */
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -3725,6 +3725,31 @@  x86_decode(
 #undef insn_fetch_bytes
 #undef insn_fetch_type
 
+#ifndef X86EMUL_NO_SIMD
+
+static void sttilecfg(struct x86_tilecfg *tilecfg)
+{
+    /* sttilecfg (%rdi) */
+    asm volatile ( ".byte 0xc4, 0xe2, 0x79, 0x49, 0x07"
+                   : "=m" (*tilecfg) : "D" (tilecfg) );
+}
+
+static bool tiles_configured(const struct x86_tilecfg *tilecfg)
+{
+    return tilecfg->palette;
+}
+
+static bool tile_valid(unsigned int tile, const struct x86_tilecfg *tilecfg)
+{
+    /*
+     * Considering the checking LDTILECFG does, checking either would in
+     * principle be sufficient.
+     */
+    return tilecfg->colsb[tile] && tilecfg->rows[tile];
+}
+
+#endif /* X86EMUL_NO_SIMD */
+
 /* Undo DEBUG wrapper. */
 #undef x86_emulate
 
@@ -9584,6 +9609,29 @@  x86_emulate(
         }
         goto unrecognized_insn;
 
+    case X86EMUL_OPC_VEX_F2(0x0f38, 0x49):
+        generate_exception_if(!mode_64bit() || vex.l || vex.w, EXC_UD);
+        if ( ea.type == OP_REG )
+        {
+            switch ( modrm_rm & 7 )
+            {
+            case 0: /* tilezero */
+                host_and_vcpu_must_have(amx_tile);
+                get_fpu(X86EMUL_FPU_tile);
+                sttilecfg(&mmvalp->tilecfg);
+                generate_exception_if(!tiles_configured(&mmvalp->tilecfg),
+                                      EXC_UD);
+                generate_exception_if(!tile_valid(modrm_reg, &mmvalp->tilecfg),
+                                      EXC_UD);
+                op_bytes = 1; /* fake */
+                goto simd_0f_common;
+
+            default:
+                goto unrecognized_insn;
+            }
+        }
+        goto unrecognized_insn;
+
     case X86EMUL_OPC_VEX_66(0x0f38, 0x50): /* vpdpbusd [xy]mm/mem,[xy]mm,[xy]mm */
     case X86EMUL_OPC_VEX_66(0x0f38, 0x51): /* vpdpbusds [xy]mm/mem,[xy]mm,[xy]mm */
     case X86EMUL_OPC_VEX_66(0x0f38, 0x52): /* vpdpwssd [xy]mm/mem,[xy]mm,[xy]mm */