[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 27/28] x86emul: enable block scale register insns for ACE


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 11 Nov 2026 16:19:22 +0100
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=suse.com header.i="@suse.com" header.h="Content-Transfer-Encoding:Content-Type:In-Reply-To:Autocrypt:Content-Language:References:Cc:To:From:Subject:User-Agent:MIME-Version:Date:Message-ID"
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>
  • Delivery-date: Wed, 11 Nov 2026 15:19:27 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

BSRINIT is an encoding sibling of TILEZERO and hence the code there merely
needs EVEX.W handling to be adjusted. BSRMOV* are at an entirely new code
point, with EVEX.W controlling the direction of the move.

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
@@ -1203,6 +1203,12 @@ static const struct test amx_tile[] = {
 };
 
 static const struct test ace[] = {
+    /* Element sizes are arbitrary here, for test_one() to set W correctly. */
+    INSN(bsrmovf,       , map6, 95, vl, q_nb, vl),
+    INSN(bsrmovh,     f2, map6, 95, vl, d_nb, vl),
+    INSN(bsrmovh,     f2, map6, 95, vl, q_nb, vl),
+    INSN(bsrmovl,     f3, map6, 95, vl, d_nb, vl),
+    INSN(bsrmovl,     f3, map6, 95, vl, q_nb, vl),
     /* Element size is set arbitrarily here. See test_one(). */
     INSN(ldtilecfg,     , 0f38, 49, el,    b, no),
     INSN(sttilecfg,   66, 0f38, 49, el,    b, no),
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -1347,6 +1347,7 @@ static const struct vex {
     { { 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 */
+    { { 0x49, 0xc0 }, 2, F, N, pfx_f2, W1, L0 }, /* bsrinit */
     { { 0x4a, VSIB(0) }, 3, F, R, pfx_66, W0, L0 }, /* tileloaddrst1 */
     { { 0x4a, VSIB(0) }, 3, F, R, pfx_f2, W0, L0 }, /* tileloaddrs */
     { { 0x4b, VSIB(0) }, 3, F, R, pfx_66, W0, L0 }, /* tileloaddt1 */
@@ -2567,6 +2568,11 @@ static const struct evex {
     { { 0x80 }, 2, T, R, pfx_no, W0, L1 | L2 }, /* vbmacor16x16x16 */
     { { 0x80 }, 2, T, R, pfx_no, W1, L1 | L2 }, /* vbmacxor16x16x16 */
     { { 0x81 }, 2, T, R, pfx_no, W0, Ln }, /* vbitrev */
+    { { 0x95 }, 2, F, R, pfx_no, W1, L2 }, /* bsrmovf */
+    { { 0x95 }, 2, F, W, pfx_f3, W0, L2 }, /* bsrmovl */
+    { { 0x95 }, 2, F, R, pfx_f3, W1, L2 }, /* bsrmovl */
+    { { 0x95 }, 2, F, W, pfx_f2, W0, L2 }, /* bsrmovh */
+    { { 0x95 }, 2, F, R, pfx_f2, W1, L2 }, /* bsrmovh */
     { { 0x96 }, 2, T, R, pfx_66, W0, Ln }, /* vfmaddsub132ph */
     { { 0x97 }, 2, T, R, pfx_66, W0, Ln }, /* vfmsubadd132ph */
     { { 0x98 }, 2, T, R, pfx_66, W0, Ln }, /* vfmadd132ph */
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -406,6 +406,7 @@ static const struct ext0f38_table {
     [0x8e] = { .simd_size = simd_packed_int, .to_mem = 1 },
     [0x8f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
     [0x90 ... 0x93] = { .simd_size = simd_other, .vsib = 1, .d8s = d8s_dq },
+    [0x95] = { .simd_size = simd_other, .d8s = d8s_vl },
     [0x96 ... 0x98] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
     [0x99] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
     [0x9a] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
@@ -1559,6 +1560,26 @@ decode_map5(struct x86_emulate_state *s,
     return rc;
 }
 
+static int
+decode_map6(struct x86_emulate_state *s,
+            struct x86_emulate_ctxt *ctxt,
+            const struct x86_emulate_ops *ops)
+{
+    int rc = X86EMUL_OKAY;
+
+    switch ( ctxt->opcode & 0xff )
+    {
+    case 0x95: /* bsrmov{f,h,l} */
+        if ( !s->evex.w )
+            s->desc = DstMem | SrcReg;
+        if ( s->evex.pfx )
+            s->desc |= TwoOp;
+        break;
+    }
+
+    return rc;
+}
+
 #define ad_bytes (s->ad_bytes) /* for truncate_ea() */
 
 int x86emul_decode(struct x86_emulate_state *s,
@@ -2706,6 +2727,9 @@ int x86emul_decode(struct x86_emulate_st
         break;
 
     case ext_map6:
+        rc = decode_map6(s, ctxt, ops);
+        break;
+
     case ext_map7:
     case ext_8f09:
     case ext_8f0a:
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6794,18 +6794,29 @@ x86_emulate(
         goto unrecognized_insn;
 
     case X86EMUL_OPC_VEX_F2(0x0f38, 0x49):
-        generate_exception_if(!mode_64bit() || vex.l || vex.w, X86_EXC_UD);
+        generate_exception_if(!mode_64bit() || vex.l, X86_EXC_UD);
         if ( ea.type == OP_REG )
         {
             switch ( modrm_rm & 7 )
             {
-            case 0: /* tilezero */
-                if ( !vcpu_has_ace() )
-                    vcpu_must_have(amx_tile);
-                get_fpu(X86EMUL_FPU_tile);
+            case 0:
+                if ( !vex.w ) /* tilezero */
+                {
+                    if ( !vcpu_has_ace() )
+                        vcpu_must_have(amx_tile);
+                    get_fpu(X86EMUL_FPU_tile);
+                }
+                else /* bsrinit */
+                {
+                    vcpu_must_have(ace);
+                    get_fpu(X86EMUL_FPU_ace);
+                }
                 sttilecfg(&mmvalp->tilecfg);
-                generate_exception_if(!tile_valid(modrm_reg, &mmvalp->tilecfg,
-                                                  PALETTE(AMX, ACE)),
+                generate_exception_if(vex.w
+                                      ? mmvalp->tilecfg.palette != PALETTE_ACE 
||
+                                        modrm_reg
+                                      : !tile_valid(modrm_reg, 
&mmvalp->tilecfg,
+                                                    PALETTE(AMX, ACE)),
                                       X86_EXC_UD);
                 op_bytes = 1; /* fake */
                 goto simd_0f_common;
@@ -9415,6 +9426,41 @@ x86_emulate(
         avx512_vlen_check(false);
         goto simd_zmm;
 
+    case X86EMUL_OPC_EVEX   (6, 0x95): /* bsrmovf zmm/m512,zmm,%bsr0 */
+        generate_exception_if(!evex.w, X86_EXC_UD);
+        fallthrough;
+    case X86EMUL_OPC_EVEX_F3(6, 0x95): /* bsrmovl zmm/m512,%bsr0 */
+                                       /* bsrmovl %bsr0,zmm/m512 */
+    case X86EMUL_OPC_EVEX_F2(6, 0x95): /* bsrmovh zmm/m512,%bsr0 */
+                                       /* bsrmovh %bsr0,zmm/m512 */
+        vcpu_must_have(ace);
+        generate_exception_if((evex.brs || evex.opmsk || evex.lr != 2),
+                              X86_EXC_UD);
+
+        get_fpu(X86EMUL_FPU_zmm_ace);
+        sttilecfg(&mmvalp->tilecfg);
+        generate_exception_if(mmvalp->tilecfg.palette != PALETTE_ACE,
+                              X86_EXC_UD);
+
+        generate_exception_if(modrm_reg, X86_EXC_UD);
+
+        opc = init_evex(stub);
+        opc[0] = b;
+        opc[1] = modrm;
+        if ( ea.type == OP_MEM )
+        {
+            generate_exception_if(!evex.RX && !(state->xcr0 & X86_XCR0_APX),
+                                  X86_EXC_UD);
+
+            /* convert memory operand to (%rAX) */
+            evex.b3 = 1;
+            evex.b4 = 0;
+            opc[1] &= 0x38;
+        }
+        insn_bytes = EVEX_PFX_BYTES + 2;
+        op_bytes = 64;
+        break;
+
     case X86EMUL_OPC_XOP(08, 0x85): /* vpmacssww xmm,xmm/m128,xmm,xmm */
     case X86EMUL_OPC_XOP(08, 0x86): /* vpmacsswd xmm,xmm/m128,xmm,xmm */
     case X86EMUL_OPC_XOP(08, 0x87): /* vpmacssdql xmm,xmm/m128,xmm,xmm */




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.