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

[xen staging] x86emul: support non-SIMD MOVRS



commit 59b18eb757dbed47764926ab9adf2ce630b60de2
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Jul 28 10:07:13 2026 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jul 28 10:07:13 2026 +0200

    x86emul: support non-SIMD MOVRS
    
    As we ignore cachability aspects of insns, they're treated like simple
    MOVs.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 tools/tests/x86_emulator/predicates.c        |  3 +++
 tools/tests/x86_emulator/test_x86_emulator.c | 23 +++++++++++++++++++++++
 xen/arch/x86/x86_emulate/decode.c            | 10 +++++++++-
 xen/arch/x86/x86_emulate/private.h           |  1 +
 xen/arch/x86/x86_emulate/x86_emulate.c       | 10 ++++++++++
 xen/include/public/arch-x86/cpufeatureset.h  |  1 +
 xen/tools/gen-cpuid.py                       |  2 +-
 7 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/tools/tests/x86_emulator/predicates.c 
b/tools/tests/x86_emulator/predicates.c
index 84717d3ebe..6c6d0f386c 100644
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -841,6 +841,9 @@ static const struct {
     { { 0x80 }, { 2, 2 }, T, R, pfx_66 }, /* invept */
     { { 0x81 }, { 2, 2 }, T, R, pfx_66 }, /* invvpid */
     { { 0x82 }, { 2, 2 }, T, R, pfx_66 }, /* invpcid */
+    { { 0x8a }, { 2, 2 }, T, R, pfx_no }, /* movrsb */
+    { { 0x8b }, { 2, 2 }, T, R, pfx_no }, /* movrs{d,q} */
+    { { 0x8b }, { 2, 2 }, T, R, pfx_66 }, /* movrsw */
     { { 0xc8 }, { 2, 2 }, T, R, pfx_no }, /* sha1nexte */
     { { 0xc9 }, { 2, 2 }, T, R, pfx_no }, /* sha1msg1 */
     { { 0xca }, { 2, 2 }, T, R, pfx_no }, /* sha1msg2 */
diff --git a/tools/tests/x86_emulator/test_x86_emulator.c 
b/tools/tests/x86_emulator/test_x86_emulator.c
index af29b106f1..31391f1bf7 100644
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -1704,6 +1704,29 @@ int main(int argc, char **argv)
     }
     else
         printf("skipped\n");
+
+    {
+        /* For the non-SIMD forms the emulator doesn't itself use MOVRS. */
+        bool movrs = cpu_policy.feat.movrs;
+
+        cpu_policy.feat.movrs = true;
+
+        printf("%-40s", "Testing movrs 6(%rdi),%si...");
+        instr[0] = 0x66; instr[1] = 0x0f; instr[2] = 0x38;
+        instr[3] = 0x8b; instr[4] = 0x77; instr[5] = 0x06;
+        regs.rip = (unsigned long)&instr[0];
+        regs.rsi = 0x8888777766665555UL;
+        regs.rdi = (unsigned long)res;
+        res[1]   = 0x88777788U;
+        rc = x86_emulate(&ctxt, &emulops);
+        if ( (rc != X86EMUL_OKAY) ||
+             (regs.rip != (unsigned long)&instr[6]) ||
+             (regs.rsi != 0x8888777766668877UL) )
+            goto fail;
+        printf("okay\n");
+
+        cpu_policy.feat.movrs = movrs;
+    }
 #endif /* x86-64 */
 
     printf("%-40s", "Testing shld $1,%ecx,(%edx)...");
diff --git a/xen/arch/x86/x86_emulate/decode.c 
b/xen/arch/x86/x86_emulate/decode.c
index d1665e6eb3..48e8c79964 100644
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -902,7 +902,8 @@ decode_0f38(struct x86_emulate_state *s,
 {
     switch ( ctxt->opcode & X86EMUL_OPC_MASK )
     {
-    case 0x00 ... 0xef:
+    case 0x00 ... 0x89:
+    case 0x8c ... 0xef:
     case 0xf2 ... 0xf5:
     case 0xf7 ... 0xf8:
     case 0xfa ... 0xff:
@@ -913,6 +914,13 @@ decode_0f38(struct x86_emulate_state *s,
         ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
         break;
 
+    case 0x8a ... 0x8b: /* movrs */
+        s->desc = DstReg | SrcMem | Mov;
+        if ( !(ctxt->opcode & 1) )
+            s->desc |= ByteOp;
+        s->simd_size = simd_none;
+        break;
+
     case X86EMUL_OPC_VEX_66(0, 0x2d): /* vmaskmovpd */
         s->simd_size = simd_packed_fp;
         break;
diff --git a/xen/arch/x86/x86_emulate/private.h 
b/xen/arch/x86/x86_emulate/private.h
index 6c96f72327..1b06c60248 100644
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -612,6 +612,7 @@ amd_like(const struct x86_emulate_ctxt *ctxt)
 #define vcpu_has_lkgs()        (ctxt->cpuid->feat.lkgs)
 #define vcpu_has_wrmsrns()     (ctxt->cpuid->feat.wrmsrns)
 #define vcpu_has_avx_ifma()    (ctxt->cpuid->feat.avx_ifma)
+#define vcpu_has_movrs()       (ctxt->cpuid->feat.movrs)
 #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_avx_vnni_int16() (ctxt->cpuid->feat.avx_vnni_int16)
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index a4ba22ffb5..80742e50d4 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -6375,6 +6375,16 @@ x86_emulate(
         fault_suppression = false;
         goto avx512f_no_sae;
 
+#endif /* !X86EMUL_NO_SIMD */
+
+    case X86EMUL_OPC(0x0f38, 0x8a)
+     ... X86EMUL_OPC(0x0f38, 0x8b): /* movrs */
+        vcpu_must_have(movrs);
+        dst.val = src.val;
+        break;
+
+#ifndef X86EMUL_NO_SIMD
+
     case X86EMUL_OPC_VEX_66(0x0f38, 0x8c): /* vpmaskmov{d,q} 
mem,{x,y}mm,{x,y}mm */
     case X86EMUL_OPC_VEX_66(0x0f38, 0x8e): /* vpmaskmov{d,q} 
{x,y}mm,{x,y}mm,mem */
         generate_exception_if(ea.type != OP_MEM, X86_EXC_UD);
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index ce4a7982a5..72c1bde7e6 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -319,6 +319,7 @@ XEN_CPUFEATURE(AVX_IFMA,     10*32+23) /*A  AVX-IFMA 
Instructions */
 XEN_CPUFEATURE(LAM,          10*32+26) /*   Linear Address Masking */
 XEN_CPUFEATURE(MSRLIST,      10*32+27) /*   {RD,WR}MSRLIST instructions */
 XEN_CPUFEATURE(NO_INVD,      10*32+30) /*   INVD instruction unusable */
+XEN_CPUFEATURE(MOVRS,        10*32+31) /*a  MOV-read-shared instructions */
 
 /* AMD-defined CPU features, CPUID level 0x80000021.eax, word 11 */
 XEN_CPUFEATURE(NO_NEST_BP,         11*32+ 0) /*A  No Nested Data Breakpoints */
diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py
index a30c68b40a..749d3f4e09 100755
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -283,7 +283,7 @@ def crunch_numbers(state):
         # NO_LMSL indicates the absense of Long Mode Segment Limits, which
         # have been dropped in hardware.
         LM: [CX16, PCID, LAHF_LM, PAGE1GB, PKU, NO_LMSL, AMX_TILE, CMPCCXADD,
-             LKGS],
+             LKGS, MOVRS],
 
         # AMD K6-2+ and K6-III processors shipped with 3DNow+, beyond the
         # standard 3DNow in the earlier K6 processors.
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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