]> xenbits.xensource.com Git - xen.git/commitdiff
x86/MSR: improve code gen for rdmsr_safe() and rdtsc()
authorJan Beulich <jbeulich@suse.com>
Tue, 1 Oct 2024 07:47:32 +0000 (09:47 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 1 Oct 2024 07:47:32 +0000 (09:47 +0200)
To fold two 32-bit outputs from the asm()-s into a single 64-bit value
the compiler needs to emit a zero-extension insn for the low half. Both
RDMSR and RDTSC clear the upper halves of their output registers anyway,
though. So despite that zero-extending insn (a simple MOV) being cheap,
we can do better: Without one, by declaring the local variables as 64-
bit ones.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/include/asm/msr.h

index c95330a5a16da18a7e6fe58a55ec7bb1a2305d08..e1e7439d6c64604d73db1eb45f7de56fdd089c1c 100644 (file)
@@ -54,17 +54,17 @@ static inline void wrmsr_ns(uint32_t msr, uint32_t lo, uint32_t hi)
 /* rdmsr with exception handling */
 #define rdmsr_safe(msr,val) ({\
     int rc_; \
-    uint32_t lo_, hi_; \
+    uint64_t lo_, hi_; \
     __asm__ __volatile__( \
         "1: rdmsr\n2:\n" \
         ".section .fixup,\"ax\"\n" \
-        "3: xorl %0,%0\n; xorl %1,%1\n" \
+        "3: xorl %k0,%k0\n; xorl %k1,%k1\n" \
         "   movl %5,%2\n; jmp 2b\n" \
         ".previous\n" \
         _ASM_EXTABLE(1b, 3b) \
         : "=a" (lo_), "=d" (hi_), "=&r" (rc_) \
         : "c" (msr), "2" (0), "i" (-EFAULT)); \
-    val = lo_ | ((uint64_t)hi_ << 32); \
+    val = lo_ | (hi_ << 32); \
     rc_; })
 
 /* wrmsr with exception handling */
@@ -99,11 +99,11 @@ static inline void msr_split(struct cpu_user_regs *regs, uint64_t val)
 
 static inline uint64_t rdtsc(void)
 {
-    uint32_t low, high;
+    uint64_t low, high;
 
     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
 
-    return ((uint64_t)high << 32) | low;
+    return (high << 32) | low;
 }
 
 static inline uint64_t rdtsc_ordered(void)