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

[PATCH v2 02/16] 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.

Resolves: https://gitlab.com/xen-project/xen/-/work_items/217
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>

Doing this safely does depend on getting GCC-14 into CI somewhere.  Debian
13/Trixie satisfies this, as does archlinux I expect.
---
 xen/arch/x86/include/asm/msr.h | 19 +++++++++++++++++++
 xen/arch/x86/pv/emul-priv-op.c |  3 +--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/include/asm/msr.h b/xen/arch/x86/include/asm/msr.h
index d2c86ddb09e9..6a97b41bae07 100644
--- a/xen/arch/x86/include/asm/msr.h
+++ b/xen/arch/x86/include/asm/msr.h
@@ -55,6 +55,24 @@ static inline void wrmsrns(uint32_t msr, uint64_t val)
 /* rdmsr with exception handling */
 static inline int rdmsr_safe(unsigned int msr, uint64_t *val)
 {
+#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
+    uint64_t lo, hi;
+
+    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;
     uint64_t lo, hi;
 
@@ -73,6 +91,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 4afbee59e53e..c3a484c50bf8 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -1027,6 +1027,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;
 
@@ -1040,8 +1041,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:
-- 
2.39.5




 


Rackspace

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