From: Jan Beulich <jbeulich@suse.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: "Andrew Cooper" <andrew.cooper3@citrix.com>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH v9 06/10] x86emul: support MSR_IMM instructions
Date: Mon, 24 Nov 2025 16:00:33 +0100 [thread overview]
Message-ID: <55c90cf6-13fa-4afa-be6d-97d16cfb369f@suse.com> (raw)
In-Reply-To: <926a2315-a2b7-4aad-87e6-d686c9da9e3a@suse.com>
Encoding-wise these are very similar to URDMSR/UWRMSR, so existing logic
is easy to extend.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
RFC only for now, as the VMX part is missing: The existing intercepts
can't be re-used unmodified, as those require the MSR index to be
fetched from guest ECX.
---
v8: Don't mark the feature 's' just yet. Re-base.
v7: New.
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -1519,6 +1519,8 @@ static const struct vex {
{ { 0xdf }, 3, T, R, pfx_66, WIG, Ln }, /* vaeskeygenassist */
{ { 0xf0 }, 3, T, R, pfx_f2, Wn, L0 }, /* rorx */
}, vex_map7[] = {
+ { { 0xf6, 0xc0 }, 6, F, N, pfx_f3, W0, L0 }, /* wrmsrns */
+ { { 0xf6, 0xc0 }, 6, F, N, pfx_f2, W0, L0 }, /* rdmsr */
{ { 0xf8, 0xc0 }, 6, F, N, pfx_f3, W0, L0 }, /* uwrmsr */
{ { 0xf8, 0xc0 }, 6, F, N, pfx_f2, W0, L0 }, /* urdmsr */
};
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -1574,6 +1574,30 @@ int main(int argc, char **argv)
if ( (rc != X86EMUL_EXCEPTION) ||
(regs.rip != (unsigned long)&instr[0]) )
goto fail;
+ printf("okay\n");
+
+ printf("%-40s", "Testing rdmsr $MSR_GS_BASE,%rdx...");
+ instr[0] = 0xc4; instr[1] = 0xe7; instr[2] = 0x7b; instr[3] = 0xf6; instr[4] = 0xc2;
+ *(uint32_t *)&instr[5] = MSR_GS_BASE;
+ regs.rip = (unsigned long)&instr[0];
+ regs.rdx = ~gs_base;
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.rip != (unsigned long)&instr[9]) ||
+ (regs.rdx != gs_base) )
+ goto fail;
+ printf("okay\n");
+
+ printf("%-40s", "Testing wrmsrns %rsi,$MSR_SHADOW_GS_BASE...");
+ instr[0] = 0xc4; instr[1] = 0xe7; instr[2] = 0x7a; instr[3] = 0xf6; instr[4] = 0xc6;
+ *(uint32_t *)&instr[5] = MSR_SHADOW_GS_BASE;
+ regs.rip = (unsigned long)&instr[0];
+ regs.rsi = 0x665544332211UL;
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.rip != (unsigned long)&instr[9]) ||
+ (gs_base_shadow != 0x665544332211UL) )
+ goto fail;
emulops.write_msr = NULL;
#endif
--- a/tools/tests/x86_emulator/x86-emulate.c
+++ b/tools/tests/x86_emulator/x86-emulate.c
@@ -88,6 +88,7 @@ bool emul_test_init(void)
cpu_policy.feat.lkgs = true;
cpu_policy.feat.wrmsrns = true;
cpu_policy.feat.msrlist = true;
+ cpu_policy.feat.msr_imm = true;
cpu_policy.feat.user_msr = true;
cpu_policy.extd.clzero = true;
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -1262,8 +1262,9 @@ int x86emul_decode(struct x86_emulate_st
case vex_map7:
opcode |= MASK_INSR(7, X86EMUL_OPC_EXT_MASK);
/*
- * No table lookup here for now, as there's only a single
- * opcode point (0xf8) populated in map 7.
+ * No table lookup here for now, as there are only two
+ * (very similar) opcode points (0xf6, 0xf8) populated
+ * in map 7.
*/
d = DstMem | SrcImm | ModRM | Mov;
s->op_bytes = 8;
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -614,6 +614,7 @@ amd_like(const struct x86_emulate_ctxt *
#define vcpu_has_wrmsrns() (ctxt->cpuid->feat.wrmsrns)
#define vcpu_has_avx_ifma() (ctxt->cpuid->feat.avx_ifma)
#define vcpu_has_msrlist() (ctxt->cpuid->feat.msrlist)
+#define vcpu_has_msr_imm() (ctxt->cpuid->feat.msr_imm)
#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)
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -7024,6 +7024,34 @@ x86_emulate(
state->simd_size = simd_none;
break;
+ case X86EMUL_OPC_VEX_F3(7, 0xf6): /* wrmsrns r64,imm32 */
+ case X86EMUL_OPC_VEX_F2(7, 0xf6): /* rdmsr imm32,r64 */
+ generate_exception_if(!mode_64bit() || ea.type != OP_REG, X86_EXC_UD);
+ generate_exception_if(vex.l || vex.w, X86_EXC_UD);
+ generate_exception_if(vex.opcx && ((modrm_reg & 7) || vex.reg != 0xf),
+ X86_EXC_UD);
+ vcpu_must_have(msr_imm);
+ generate_exception_if(!mode_ring0(), X86_EXC_GP, 0);
+ if ( vex.pfx == vex_f2 )
+ {
+ /* urdmsr */
+ fail_if(!ops->read_msr);
+ if ( (rc = ops->read_msr(imm1, &msr_val, ctxt)) != X86EMUL_OKAY )
+ goto done;
+ dst.val = msr_val;
+ ASSERT(dst.type == OP_REG);
+ dst.bytes = 8;
+ }
+ else
+ {
+ /* wrmsrns */
+ fail_if(!ops->write_msr);
+ if ( (rc = ops->write_msr(imm1, dst.val, ctxt)) != X86EMUL_OKAY )
+ goto done;
+ dst.type = OP_NONE;
+ }
+ break;
+
case X86EMUL_OPC_F3(0x0f38, 0xf8): /* enqcmds r,m512 / uwrmsr r64,r32 */
case X86EMUL_OPC_F2(0x0f38, 0xf8): /* enqcmd r,m512 / urdmsr r32,r64 */
if ( ea.type == OP_MEM )
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -352,6 +352,7 @@ XEN_CPUFEATURE(MCDT_NO, 13*32
XEN_CPUFEATURE(UC_LOCK_DIS, 13*32+ 6) /* UC-lock disable */
/* Intel-defined CPU features, CPUID level 0x00000007:1.ecx, word 14 */
+XEN_CPUFEATURE(MSR_IMM, 14*32+ 5) /* RDMSR/WRMSRNS with immediate operand */
/* Intel-defined CPU features, CPUID level 0x00000007:1.edx, word 15 */
XEN_CPUFEATURE(AVX_VNNI_INT8, 15*32+ 4) /*A AVX-VNNI-INT8 Instructions */
--- 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, MSRLIST, USER_MSR],
+ LKGS, MSRLIST, USER_MSR, MSR_IMM],
# AMD K6-2+ and K6-III processors shipped with 3DNow+, beyond the
# standard 3DNow in the earlier K6 processors.
next prev parent reply other threads:[~2025-11-24 15:00 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-24 14:56 [PATCH v9 10/10] x86emul: misc additions Jan Beulich
2025-11-24 14:57 ` [PATCH v9 01/10] x86emul: support LKGS Jan Beulich
2025-11-24 14:58 ` [PATCH v9 02/10] x86emul+VMX: support {RD,WR}MSRLIST Jan Beulich
2025-11-24 14:58 ` [PATCH v9 03/10] x86emul: support USER_MSR instructions Jan Beulich
2025-11-24 14:59 ` [PATCH v9 04/10] x86/cpu-policy: re-arrange no-VMX logic Jan Beulich
2026-04-07 21:58 ` Andrew Cooper
2026-04-08 6:09 ` Jan Beulich
2025-11-24 15:00 ` [PATCH v9 05/10] VMX: support USER-MSR Jan Beulich
2025-11-24 15:00 ` Jan Beulich [this message]
2025-11-24 15:00 ` [PATCH v9 07/10] VMX: support MSR-IMM Jan Beulich
2025-11-26 18:50 ` Andrew Cooper
2025-11-27 8:18 ` Jan Beulich
2025-11-24 15:01 ` [PATCH v9 08/10] x86emul: support non-SIMD MOVRS Jan Beulich
2025-11-24 15:01 ` [PATCH v9 09/10] x86: use / "support" UDB Jan Beulich
2025-12-05 12:01 ` Andrew Cooper
2025-12-05 12:40 ` Andrew Cooper
2025-12-05 13:13 ` Jan Beulich
2025-12-05 13:15 ` Andrew Cooper
2025-12-05 13:15 ` Jan Beulich
2025-12-05 13:35 ` Andrew Cooper
2025-12-05 13:09 ` Jan Beulich
2025-11-24 15:02 ` [PATCH v9 10/10] x86emul: support AVX512-BMM Jan Beulich
2025-12-05 12:33 ` Andrew Cooper
2025-12-05 12:47 ` Jan Beulich
2026-04-07 15:11 ` Andrew Cooper
2025-11-24 15:03 ` [PATCH v9 00/10] x86emul: misc additions Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55c90cf6-13fa-4afa-be6d-97d16cfb369f@suse.com \
--to=jbeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=roger.pau@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.