Mailing List Archive

[xen master] x86emul: support WRMSRNS
commit 07b167d17e84aa7985a1c6d03dd3c23c37a83d23
Author: Jan Beulich <jbeulich@suse.com>
AuthorDate: Mon Apr 17 14:03:22 2023 +0200
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Mon Apr 17 14:03:22 2023 +0200

x86emul: support WRMSRNS

This insn differs from WRMSR solely in the lack of serialization. Hence
the code used there can simply be used here as well, plus a feature
check of course. As there's no other infrastructure needed beyond
permitting the insn for PV privileged-op emulation (in particular no
separate new VMEXIT) we can expose the insn to guests right away.

Don't expose the feature to PV guests, as the involved #UD is
serializing anyway.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
tools/tests/x86_emulator/predicates.c | 1 +
tools/tests/x86_emulator/x86-emulate.c | 1 +
xen/arch/x86/x86_emulate/0f01.c | 14 ++++++++++++++
xen/arch/x86/x86_emulate/private.h | 1 +
xen/include/public/arch-x86/cpufeatureset.h | 2 +-
5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/tests/x86_emulator/predicates.c b/tools/tests/x86_emulator/predicates.c
index cf1cb73054..0cb05442a1 100644
--- a/tools/tests/x86_emulator/predicates.c
+++ b/tools/tests/x86_emulator/predicates.c
@@ -340,6 +340,7 @@ static const struct {
/*{ 0x01, 0xc3 }, { 2, 2 }, F, R }, vmresume */
{ { 0x01, 0xc4 }, { 2, 2 }, F, N }, /* vmxoff */
{ { 0x01, 0xc5 }, { 2, 2 }, F, N }, /* pconfig */
+ { { 0x01, 0xc6 }, { 2, 2 }, F, N }, /* wrmsrns */
{ { 0x01, 0xc8 }, { 2, 2 }, F, N }, /* monitor */
{ { 0x01, 0xc9 }, { 2, 2 }, F, N }, /* mwait */
{ { 0x01, 0xca }, { 2, 2 }, F, N }, /* clac */
diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c
index 7d2d57f759..d3baaef1d0 100644
--- a/tools/tests/x86_emulator/x86-emulate.c
+++ b/tools/tests/x86_emulator/x86-emulate.c
@@ -86,6 +86,7 @@ bool emul_test_init(void)
cp.feat.adx = true;
cp.feat.avx512pf = cp.feat.avx512f;
cp.feat.rdpid = true;
+ cp.feat.wrmsrns = true;
cp.extd.clzero = true;

if ( cpu_has_xsave )
diff --git a/xen/arch/x86/x86_emulate/0f01.c b/xen/arch/x86/x86_emulate/0f01.c
index 5dda10bff1..ba43fc394b 100644
--- a/xen/arch/x86/x86_emulate/0f01.c
+++ b/xen/arch/x86/x86_emulate/0f01.c
@@ -31,6 +31,20 @@ int x86emul_0f01(struct x86_emulate_state *s,
struct segment_register sreg;
uint64_t msr_val;

+ case 0xc6:
+ switch ( s->vex.pfx )
+ {
+ case vex_none: /* wrmsrns */
+ vcpu_must_have(wrmsrns);
+ generate_exception_if(!mode_ring0(), X86_EXC_GP, 0);
+ fail_if(!ops->write_msr);
+ rc = ops->write_msr(regs->ecx,
+ ((uint64_t)regs->r(dx) << 32) | regs->eax,
+ ctxt);
+ goto done;
+ }
+ generate_exception(X86_EXC_UD);
+
case 0xca: /* clac */
case 0xcb: /* stac */
vcpu_must_have(smap);
diff --git a/xen/arch/x86/x86_emulate/private.h b/xen/arch/x86/x86_emulate/private.h
index e09bed55f3..9f8db6ab0d 100644
--- a/xen/arch/x86/x86_emulate/private.h
+++ b/xen/arch/x86/x86_emulate/private.h
@@ -582,6 +582,7 @@ amd_like(const struct x86_emulate_ctxt *ctxt)
#define vcpu_has_tsxldtrk() (ctxt->cpuid->feat.tsxldtrk)
#define vcpu_has_avx_vnni() (ctxt->cpuid->feat.avx_vnni)
#define vcpu_has_avx512_bf16() (ctxt->cpuid->feat.avx512_bf16)
+#define vcpu_has_wrmsrns() (ctxt->cpuid->feat.wrmsrns)

#define vcpu_must_have(feat) \
generate_exception_if(!vcpu_has_##feat(), X86_EXC_UD)
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index 0888519087..46d006be8f 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -281,7 +281,7 @@ XEN_CPUFEATURE(AVX512_BF16, 10*32+ 5) /*A AVX512 BFloat16 Instructions */
XEN_CPUFEATURE(FZRM, 10*32+10) /*A Fast Zero-length REP MOVSB */
XEN_CPUFEATURE(FSRS, 10*32+11) /*A Fast Short REP STOSB */
XEN_CPUFEATURE(FSRCS, 10*32+12) /*A Fast Short REP CMPSB/SCASB */
-XEN_CPUFEATURE(WRMSRNS, 10*32+19) /* WRMSR Non-Serialising */
+XEN_CPUFEATURE(WRMSRNS, 10*32+19) /*S WRMSR Non-Serialising */

/* AMD-defined CPU features, CPUID level 0x80000021.eax, word 11 */
XEN_CPUFEATURE(LFENCE_DISPATCH, 11*32+ 2) /*A LFENCE always serializing */
--
generated by git-patchbot for /home/xen/git/xen.git#master