x86/MSR: introduce MSR access split/fold helpers
authorJan Beulich <jbeulich@suse.com>
Tue, 3 Jan 2017 08:42:10 +0000 (09:42 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 3 Jan 2017 08:42:10 +0000 (09:42 +0100)
This is in preparation of eliminating the mis-naming of 64-bit fields
with 32-bit register names (eflags instead of rflags etc). Use the
guaranteed 32-bit underscore prefixed names for now where appropriate.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/hvm/vmx/vvmx.c
xen/arch/x86/time.c
xen/arch/x86/traps.c
xen/include/asm-x86/msr.h

index 708f4746e5cdee81a53c198f56f56951446baf4d..70afcc6cebfd9e08f956bf23dc63f96f54dbe0a4 100644 (file)
@@ -3695,12 +3695,9 @@ static uint64_t _hvm_rdtsc_intercept(void)
 
 void hvm_rdtsc_intercept(struct cpu_user_regs *regs)
 {
-    uint64_t tsc = _hvm_rdtsc_intercept();
+    msr_split(regs, _hvm_rdtsc_intercept());
 
-    regs->eax = (uint32_t)tsc;
-    regs->edx = (uint32_t)(tsc >> 32);
-
-    HVMTRACE_2D(RDTSC, regs->eax, regs->edx);
+    HVMTRACE_2D(RDTSC, regs->_eax, regs->_edx);
 }
 
 int hvm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
index 811ea4e5b4726e9ee6212bf864d49ac281bebc70..97f3d6556f0474751134782ef4e16de74e3de983 100644 (file)
@@ -1936,14 +1936,10 @@ static void svm_do_msr_access(struct cpu_user_regs *regs)
 
         rc = hvm_msr_read_intercept(regs->_ecx, &msr_content);
         if ( rc == X86EMUL_OKAY )
-        {
-            regs->rax = (uint32_t)msr_content;
-            regs->rdx = (uint32_t)(msr_content >> 32);
-        }
+            msr_split(regs, msr_content);
     }
     else
-        rc = hvm_msr_write_intercept(regs->_ecx,
-                                     (regs->rdx << 32) | regs->_eax, 1);
+        rc = hvm_msr_write_intercept(regs->_ecx, msr_fold(regs), 1);
 
     if ( rc == X86EMUL_OKAY )
         __update_guest_eip(regs, inst_len);
@@ -2618,8 +2614,7 @@ void svm_vmexit_handler(struct cpu_user_regs *regs)
         if ( vmcb_get_cpl(vmcb) )
             hvm_inject_hw_exception(TRAP_gp_fault, 0);
         else if ( (inst_len = __get_instruction_length(v, INSTR_XSETBV)) &&
-                  hvm_handle_xsetbv(regs->ecx,
-                                    (regs->rdx << 32) | regs->_eax) == 0 )
+                  hvm_handle_xsetbv(regs->_ecx, msr_fold(regs)) == 0 )
             __update_guest_eip(regs, inst_len);
         break;
 
index d50d49eee55aa59c363c7e80d08252c120659f7a..68db0cb645736c88519a48429f4940a41a619b37 100644 (file)
@@ -3626,22 +3626,18 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
     case EXIT_REASON_MSR_READ:
     {
         uint64_t msr_content;
-        if ( hvm_msr_read_intercept(regs->ecx, &msr_content) == X86EMUL_OKAY )
+        if ( hvm_msr_read_intercept(regs->_ecx, &msr_content) == X86EMUL_OKAY )
         {
-            regs->eax = (uint32_t)msr_content;
-            regs->edx = (uint32_t)(msr_content >> 32);
+            msr_split(regs, msr_content);
             update_guest_eip(); /* Safe: RDMSR */
         }
         break;
     }
+
     case EXIT_REASON_MSR_WRITE:
-    {
-        uint64_t msr_content;
-        msr_content = ((uint64_t)regs->edx << 32) | (uint32_t)regs->eax;
-        if ( hvm_msr_write_intercept(regs->ecx, msr_content, 1) == X86EMUL_OKAY )
+        if ( hvm_msr_write_intercept(regs->_ecx, msr_fold(regs), 1) == X86EMUL_OKAY )
             update_guest_eip(); /* Safe: WRMSR */
         break;
-    }
 
     case EXIT_REASON_VMXOFF:
         if ( nvmx_handle_vmxoff(regs) == X86EMUL_OKAY )
@@ -3802,8 +3798,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case EXIT_REASON_XSETBV:
-        if ( hvm_handle_xsetbv(regs->ecx,
-                               (regs->rdx << 32) | regs->_eax) == 0 )
+        if ( hvm_handle_xsetbv(regs->_ecx, msr_fold(regs)) == 0 )
             update_guest_eip(); /* Safe: XSETBV */
         break;
 
index 6c7e92b791c6bf6cd6b2f401970a882b0e2a9298..d53c5762fccdef2ece6894bf924cc32f2c0c39c4 100644 (file)
@@ -2322,15 +2322,11 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs,
             nvcpu->nv_vmexit_pending = 1;
         else
         {
-            uint64_t tsc;
-
             /*
              * special handler is needed if L1 doesn't intercept rdtsc,
              * avoiding changing guest_tsc and messing up timekeeping in L1
              */
-            tsc = hvm_get_guest_tsc(v) + get_vvmcs(v, TSC_OFFSET);
-            regs->eax = (uint32_t)tsc;
-            regs->edx = (uint32_t)(tsc >> 32);
+            msr_split(regs, hvm_get_guest_tsc(v) + get_vvmcs(v, TSC_OFFSET));
             update_guest_eip();
 
             return 1;
index cb6939eb29bbeea1f87a854baca122df7d53a4ed..b89fa1306870023c3f77ce1600aac3e4ccc926f8 100644 (file)
@@ -1918,13 +1918,10 @@ void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs, int rdtscp)
 
     spin_unlock(&d->arch.vtsc_lock);
 
-    now = gtime_to_gtsc(d, now);
-
-    regs->eax = (uint32_t)now;
-    regs->edx = (uint32_t)(now >> 32);
+    msr_split(regs, gtime_to_gtsc(d, now));
 
     if ( rdtscp )
-         regs->ecx =
+         regs->rcx =
              (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? d->arch.incarnation : 0;
 }
 
index 8005208764ad5f0fb9370c3e90232a735e828839..2d211d1621bfb53680140245cfded96b817f1314 100644 (file)
@@ -3404,12 +3404,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
             else if ( currd->arch.vtsc )
                 pv_soft_rdtsc(curr, regs, 0);
             else
-            {
-                uint64_t val = rdtsc();
-
-                regs->eax = (uint32_t)val;
-                regs->edx = (uint32_t)(val >> 32);
-            }
+                msr_split(regs, rdtsc());
         }
 
         if ( ctxt.ctxt.retire.singlestep )
index f3b85d0352f4cbfa0176a2d94623e8ce057e9efc..f5900ab3af97ceb607e3fecc9dd5cba45a4e3422 100644 (file)
@@ -71,6 +71,17 @@ static inline int wrmsr_safe(unsigned int msr, uint64_t val)
     return _rc;
 }
 
+static inline uint64_t msr_fold(const struct cpu_user_regs *regs)
+{
+    return (regs->rdx << 32) | regs->_eax;
+}
+
+static inline void msr_split(struct cpu_user_regs *regs, uint64_t val)
+{
+    regs->rdx = val >> 32;
+    regs->rax = (uint32_t)val;
+}
+
 static inline uint64_t rdtsc(void)
 {
     uint32_t low, high;