From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
To: xen-devel@lists.xenproject.org
Cc: iwj@xenproject.org, wl@xen.org, anthony.perard@citrix.com,
jbeulich@suse.com, andrew.cooper3@citrix.com,
roger.pau@citrix.com, jun.nakajima@intel.com,
kevin.tian@intel.com, boris.ostrovsky@oracle.com
Subject: [PATCH v2 3/4] x86: Allow non-faulting accesses to non-emulated MSRs if policy permits this
Date: Wed, 20 Jan 2021 17:49:11 -0500 [thread overview]
Message-ID: <1611182952-9941-4-git-send-email-boris.ostrovsky@oracle.com> (raw)
In-Reply-To: <1611182952-9941-1-git-send-email-boris.ostrovsky@oracle.com>
Starting with commit 84e848fd7a16 ("x86/hvm: disallow access to unknown MSRs")
accesses to unhandled MSRs result in #GP sent to the guest. This caused a
regression for Solaris who tries to acccess MSR_RAPL_POWER_UNIT and (unlike,
for example, Linux) does not catch exceptions when accessing MSRs that
potentially may not be present.
Instead of special-casing RAPL registers we decide what to do when any
non-emulated MSR is accessed based on ignore_msrs field of msr_policy.
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
Changes in v2:
* define x86_emul_guest_msr_access() and use it to determine whether emulated
instruction is rd/wrmsr.
* Don't use ignore_msrs for MSR accesses that are not guest's rd/wrmsr.
* Clear @val for writes too in guest_unhandled_msr()
xen/arch/x86/hvm/svm/svm.c | 10 ++++------
xen/arch/x86/hvm/vmx/vmx.c | 10 ++++------
xen/arch/x86/msr.c | 28 ++++++++++++++++++++++++++++
xen/arch/x86/pv/emul-priv-op.c | 10 ++++++----
xen/arch/x86/x86_emulate/x86_emulate.h | 6 ++++++
xen/include/asm-x86/msr.h | 3 +++
6 files changed, 51 insertions(+), 16 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index b819897a4a9f..7b59885b2619 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1965,8 +1965,8 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
break;
default:
- gdprintk(XENLOG_WARNING, "RDMSR 0x%08x unimplemented\n", msr);
- goto gpf;
+ if ( guest_unhandled_msr(v, msr, msr_content, false, true) )
+ goto gpf;
}
HVM_DBG_LOG(DBG_LEVEL_MSR, "returns: ecx=%x, msr_value=%"PRIx64,
@@ -2151,10 +2151,8 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
break;
default:
- gdprintk(XENLOG_WARNING,
- "WRMSR 0x%08x val 0x%016"PRIx64" unimplemented\n",
- msr, msr_content);
- goto gpf;
+ if ( guest_unhandled_msr(v, msr, &msr_content, true, true) )
+ goto gpf;
}
return X86EMUL_OKAY;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 2d4475ee3de2..87baca57d33f 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -3017,8 +3017,8 @@ static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
break;
}
- gdprintk(XENLOG_WARNING, "RDMSR 0x%08x unimplemented\n", msr);
- goto gp_fault;
+ if ( guest_unhandled_msr(curr, msr, msr_content, false, true) )
+ goto gp_fault;
}
done:
@@ -3319,10 +3319,8 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content)
is_last_branch_msr(msr) )
break;
- gdprintk(XENLOG_WARNING,
- "WRMSR 0x%08x val 0x%016"PRIx64" unimplemented\n",
- msr, msr_content);
- goto gp_fault;
+ if ( guest_unhandled_msr(v, msr, &msr_content, true, true) )
+ goto gp_fault;
}
return X86EMUL_OKAY;
diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c
index 433d16c80728..a57d838f642b 100644
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -164,6 +164,34 @@ int init_vcpu_msr_policy(struct vcpu *v)
return 0;
}
+/* Returns true if policy requires #GP to the guest. */
+bool guest_unhandled_msr(const struct vcpu *v, uint32_t msr, uint64_t *val,
+ bool is_write, bool is_guest_msr_access)
+{
+ u8 ignore_msrs = v->domain->arch.msr->ignore_msrs;
+
+ /*
+ * Accesses to unimplemented MSRs as part of emulation of instructions
+ * other than guest's RDMSR/WRMSR should never succeed.
+ */
+ if ( !is_guest_msr_access )
+ ignore_msrs = MSR_UNHANDLED_NEVER;
+
+ if ( unlikely(ignore_msrs != MSR_UNHANDLED_NEVER) )
+ *val = 0;
+
+ if ( likely(ignore_msrs != MSR_UNHANDLED_SILENT) )
+ {
+ if ( is_write )
+ gdprintk(XENLOG_WARNING, "WRMSR 0x%08x val 0x%016"PRIx64
+ " unimplemented\n", msr, *val);
+ else
+ gdprintk(XENLOG_WARNING, "RDMSR 0x%08x unimplemented\n", msr);
+ }
+
+ return (ignore_msrs == MSR_UNHANDLED_NEVER);
+}
+
int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val)
{
const struct vcpu *curr = current;
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index dbceed8a05fd..6b378dbe2239 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -984,7 +984,9 @@ static int read_msr(unsigned int reg, uint64_t *val,
}
/* fall through */
default:
- gdprintk(XENLOG_WARNING, "RDMSR 0x%08x unimplemented\n", reg);
+ if ( !guest_unhandled_msr(curr, reg, val, false,
+ x86_emul_guest_msr_access(ctxt)) )
+ return X86EMUL_OKAY;
break;
normal:
@@ -1146,9 +1148,9 @@ static int write_msr(unsigned int reg, uint64_t val,
}
/* fall through */
default:
- gdprintk(XENLOG_WARNING,
- "WRMSR 0x%08x val 0x%016"PRIx64" unimplemented\n",
- reg, val);
+ if ( !guest_unhandled_msr(curr, reg, &val, true,
+ x86_emul_guest_msr_access(ctxt)) )
+ return X86EMUL_OKAY;
break;
invalid:
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h
index d8fb3a990933..06e6b7479f37 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -850,4 +850,10 @@ static inline void x86_emul_reset_event(struct x86_emulate_ctxt *ctxt)
ctxt->event = (struct x86_event){};
}
+static inline bool x86_emul_guest_msr_access(struct x86_emulate_ctxt *ctxt)
+{
+ return ctxt->opcode == X86EMUL_OPC(0x0f, 0x32) || /* RDMSR */
+ ctxt->opcode == X86EMUL_OPC(0x0f, 0x30); /* WRMSR */
+}
+
#endif /* __X86_EMULATE_H__ */
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index 16f95e734428..e7d69ad5bf29 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -345,5 +345,8 @@ int init_vcpu_msr_policy(struct vcpu *v);
*/
int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val);
int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val);
+bool guest_unhandled_msr(const struct vcpu *v, uint32_t msr,
+ uint64_t *val, bool is_write,
+ bool is_guest_msr_access);
#endif /* __ASM_MSR_H */
--
1.8.3.1
next prev parent reply other threads:[~2021-01-20 22:49 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-20 22:49 [PATCH v2 0/4] Permit fault-less access to non-emulated MSRs Boris Ostrovsky
2021-01-20 22:49 ` [PATCH v2 1/4] xl: Add support for ignore_msrs option Boris Ostrovsky
2021-01-21 14:56 ` Wei Liu
2021-01-21 22:43 ` Boris Ostrovsky
2021-01-22 9:52 ` Julien Grall
2021-01-22 18:28 ` Boris Ostrovsky
2021-01-22 18:33 ` Julien Grall
2021-01-22 18:39 ` Boris Ostrovsky
2021-01-22 20:42 ` Julien Grall
2021-02-18 10:42 ` Roger Pau Monné
2021-02-18 11:54 ` Jan Beulich
2021-02-18 15:52 ` Roger Pau Monné
2021-02-18 15:57 ` Jan Beulich
2021-02-19 14:50 ` Boris Ostrovsky
2021-02-22 10:24 ` Roger Pau Monné
2021-02-22 10:33 ` Jan Beulich
2021-01-20 22:49 ` [PATCH v2 2/4] x86: Introduce MSR_UNHANDLED Boris Ostrovsky
2021-01-22 11:51 ` Jan Beulich
2021-01-22 18:56 ` Boris Ostrovsky
2021-02-02 17:01 ` Boris Ostrovsky
2021-02-18 10:51 ` Roger Pau Monné
2021-02-19 14:56 ` Boris Ostrovsky
2021-02-22 11:08 ` Roger Pau Monné
2021-02-22 21:19 ` Boris Ostrovsky
2021-02-23 7:57 ` Jan Beulich
2021-02-23 9:34 ` Roger Pau Monné
2021-02-23 10:15 ` Jan Beulich
2021-02-23 12:17 ` Roger Pau Monné
2021-02-23 13:23 ` Jan Beulich
2021-02-23 15:39 ` Boris Ostrovsky
2021-02-23 16:10 ` Jan Beulich
2021-02-23 18:00 ` Roger Pau Monné
2021-02-23 16:11 ` Roger Pau Monné
2021-02-23 16:40 ` Boris Ostrovsky
2021-02-23 18:02 ` Roger Pau Monné
2021-02-23 18:45 ` Boris Ostrovsky
2021-01-20 22:49 ` Boris Ostrovsky [this message]
2021-01-22 12:51 ` [PATCH v2 3/4] x86: Allow non-faulting accesses to non-emulated MSRs if policy permits this Jan Beulich
2021-01-22 19:52 ` Boris Ostrovsky
2021-01-25 10:22 ` Jan Beulich
2021-01-25 18:42 ` Boris Ostrovsky
2021-01-26 9:05 ` Jan Beulich
2021-01-26 16:02 ` Boris Ostrovsky
2021-01-26 16:35 ` Jan Beulich
2021-02-18 11:24 ` Roger Pau Monné
2021-02-18 11:57 ` Jan Beulich
2021-02-18 15:53 ` Roger Pau Monné
2021-01-20 22:49 ` [PATCH v2 4/4] tools/libs: Apply MSR policy to a guest Boris Ostrovsky
2021-01-21 14:58 ` Wei Liu
2021-01-22 9:56 ` Julien Grall
2021-01-22 18:35 ` Boris Ostrovsky
2021-02-18 11:48 ` Roger Pau Monné
2021-02-19 14:57 ` Boris Ostrovsky
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=1611182952-9941-4-git-send-email-boris.ostrovsky@oracle.com \
--to=boris.ostrovsky@oracle.com \
--cc=andrew.cooper3@citrix.com \
--cc=anthony.perard@citrix.com \
--cc=iwj@xenproject.org \
--cc=jbeulich@suse.com \
--cc=jun.nakajima@intel.com \
--cc=kevin.tian@intel.com \
--cc=roger.pau@citrix.com \
--cc=wl@xen.org \
--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.