|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/msr: Rework rdmsr_safe() using asm goto()
commit 16de294bed6e4817a7275fa11cf8d203c009a1f5
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Apr 18 17:09:40 2025 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Fri Aug 22 23:34:07 2025 +0100
x86/msr: Rework rdmsr_safe() using asm goto()
... on capable toolchains.
This avoids needing to hold rc in a register across the RDMSR, and in most
cases removes direct testing and branching based on rc, as the fault label
can
be rearranged to directly land on the out-of-line block.
There is a subtle difference in behaviour. The old behaviour would, on
fault,
still produce 0's and write to val.
The new behaviour only writes val on success, and write_msr() is the only
place where this matters. Move temp out of switch() scope and initialise it
to 0.
While it is possible to retain the old behaviour, it's not great to do so
because the compiler cannot optimise out the dead store when it's not to a
local function variable, and Xen has a lot of msr infrastructure which
passes
a val pointer through the call-tree. We have compilers with ASM_GOTO_OUTPUT
in CI, and they do notice.
Resolves: https://gitlab.com/xen-project/xen/-/work_items/217
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
xen/arch/x86/include/asm/msr.h | 18 ++++++++++++++++++
xen/arch/x86/pv/emul-priv-op.c | 3 +--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/xen/arch/x86/include/asm/msr.h b/xen/arch/x86/include/asm/msr.h
index 70e6796a45..901770555b 100644
--- a/xen/arch/x86/include/asm/msr.h
+++ b/xen/arch/x86/include/asm/msr.h
@@ -51,6 +51,23 @@ static inline void wrmsrns(uint32_t msr, uint64_t val)
static inline int rdmsr_safe(unsigned int msr, uint64_t *val)
{
uint64_t lo, hi;
+
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+ asm_inline goto (
+ "1: rdmsr\n\t"
+ _ASM_EXTABLE(1b, %l[fault])
+ : "=a" (lo), "=d" (hi)
+ : "c" (msr)
+ :
+ : fault );
+
+ *val = lo | (hi << 32);
+
+ return 0;
+
+ fault:
+ return -EFAULT;
+#else
int rc;
asm_inline volatile (
@@ -68,6 +85,7 @@ static inline int rdmsr_safe(unsigned int msr, uint64_t *val)
*val = lo | (hi << 32);
return rc;
+#endif
}
/* wrmsr with exception handling */
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index f46aaf2a3b..225d4cff03 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -1028,6 +1028,7 @@ static int cf_check write_msr(
struct vcpu *curr = current;
const struct domain *currd = curr->domain;
const struct cpu_policy *cp = currd->arch.cpu_policy;
+ uint64_t temp = 0;
bool vpmu_msr = false;
int ret;
@@ -1041,8 +1042,6 @@ static int cf_check write_msr(
switch ( reg )
{
- uint64_t temp;
-
case MSR_FS_BASE:
case MSR_GS_BASE:
case MSR_SHADOW_GS_BASE:
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |