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

[Xen-changelog] [xen-unstable] vms: A cleanup to vmx.c:



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1183802937 -3600
# Node ID 41c8284cfc0cfaa773771a2d9be85cad1fbd4079
# Parent  8528da5be577d0eab1dfc8a8a85d07e041a1f758
vms: A cleanup to vmx.c:
1) move some functions from vmx.h to vmx.c, since they are private.
2) adjust vmx_set_cr0 handling.
3) majorly coding style tidying.
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmx.c        |  426 ++++++++++++++++++++------------------
 xen/include/asm-x86/hvm/vmx/vmx.h |   22 -
 2 files changed, 230 insertions(+), 218 deletions(-)

diff -r 8528da5be577 -r 41c8284cfc0c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sat Jul 07 10:31:15 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Sat Jul 07 11:08:57 2007 +0100
@@ -98,7 +98,62 @@ static void vmx_vcpu_destroy(struct vcpu
     vmx_destroy_vmcs(v);
 }
 
+static int vmx_paging_enabled(struct vcpu *v)
+{
+    unsigned long cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
+    return (cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
+}
+
+static int vmx_pgbit_test(struct vcpu *v)
+{
+    unsigned long cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
+    return cr0 & X86_CR0_PG;
+}
+
+static int vmx_pae_enabled(struct vcpu *v)
+{
+    unsigned long cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
+    return vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE);
+}
+
+static int vmx_nx_enabled(struct vcpu *v)
+{
+    return v->arch.hvm_vmx.efer & EFER_NX;
+}
+
 #ifdef __x86_64__
+
+static int vmx_lme_is_set(struct vcpu *v)
+{
+    return v->arch.hvm_vmx.efer & EFER_LME;
+}
+
+static int vmx_long_mode_enabled(struct vcpu *v)
+{
+    return v->arch.hvm_vmx.efer & EFER_LMA;
+}
+
+static void vmx_enable_long_mode(struct vcpu *v)
+{
+    unsigned long vm_entry_value;
+
+    vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
+    vm_entry_value |= VM_ENTRY_IA32E_MODE;
+    __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
+
+    v->arch.hvm_vmx.efer |= EFER_LMA;
+}
+
+static void vmx_disable_long_mode(struct vcpu *v)
+{
+    unsigned long vm_entry_value;
+
+    vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
+    vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
+    __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
+
+    v->arch.hvm_vmx.efer &= ~EFER_LMA;
+}
 
 static DEFINE_PER_CPU(struct vmx_msr_state, host_msr_state);
 
@@ -123,7 +178,7 @@ static void vmx_save_host_msrs(void)
         set_bit(VMX_INDEX_MSR_ ## address, &host_msr_state->flags);     \
         break
 
-static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
+static int long_mode_do_msr_read(struct cpu_user_regs *regs)
 {
     u64 msr_content = 0;
     u32 ecx = regs->ecx;
@@ -181,7 +236,7 @@ static inline int long_mode_do_msr_read(
     return 1;
 }
 
-static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
+static int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
     u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
     u32 ecx = regs->ecx;
@@ -300,6 +355,7 @@ static void vmx_restore_host_msrs(void)
         wrmsrl(msr_index[i], host_msr_state->msrs[i]);
         clear_bit(i, &host_msr_state->flags);
     }
+
     if ( cpu_has_nx && !(read_efer() & EFER_NX) )
         write_efer(read_efer() | EFER_NX);
 }
@@ -323,7 +379,8 @@ static void vmx_restore_guest_msrs(struc
 
     guest_flags = guest_msr_state->flags;
 
-    while ( guest_flags ) {
+    while ( guest_flags )
+    {
         i = find_first_set_bit(guest_flags);
 
         HVM_DBG_LOG(DBG_LEVEL_2,
@@ -334,17 +391,26 @@ static void vmx_restore_guest_msrs(struc
         clear_bit(i, &guest_flags);
     }
 
-    if ( (v->arch.hvm_vmx.efer ^ read_efer()) & (EFER_NX|EFER_SCE) )
+    if ( (v->arch.hvm_vmx.efer ^ read_efer()) & (EFER_NX | EFER_SCE) )
     {
         HVM_DBG_LOG(DBG_LEVEL_2,
                     "restore guest's EFER with value %lx",
                     v->arch.hvm_vmx.efer);
-        write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
-                   (v->arch.hvm_vmx.efer & (EFER_NX|EFER_SCE)));
+        write_efer((read_efer() & ~(EFER_NX | EFER_SCE)) |
+                   (v->arch.hvm_vmx.efer & (EFER_NX | EFER_SCE)));
     }
 }
 
 #else  /* __i386__ */
+
+static int vmx_lme_is_set(struct vcpu *v)
+{ return 0; }
+static int vmx_long_mode_enabled(struct vcpu *v)
+{ return 0; }
+static void vmx_enable_long_mode(struct vcpu *v)
+{ BUG(); }
+static void vmx_disable_long_mode(struct vcpu *v)
+{ BUG(); }
 
 #define vmx_save_host_msrs()        ((void)0)
 
@@ -368,7 +434,7 @@ static void vmx_restore_guest_msrs(struc
     }
 }
 
-static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
+static int long_mode_do_msr_read(struct cpu_user_regs *regs)
 {
     u64 msr_content = 0;
     struct vcpu *v = current;
@@ -388,7 +454,7 @@ static inline int long_mode_do_msr_read(
     return 1;
 }
 
-static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
+static int long_mode_do_msr_write(struct cpu_user_regs *regs)
 {
     u64 msr_content = regs->eax | ((u64)regs->edx << 32);
     struct vcpu *v = current;
@@ -426,7 +492,24 @@ static inline int long_mode_do_msr_write
 #define savedebug(_v,_reg)  \
     __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" 
((_v)->debugreg[_reg]))
 
-static inline void vmx_save_dr(struct vcpu *v)
+static int vmx_guest_x86_mode(struct vcpu *v)
+{
+    unsigned int cs_ar_bytes;
+
+    ASSERT(v == current);
+
+    if ( unlikely(!(v->arch.hvm_vmx.cpu_shadow_cr0 & X86_CR0_PE)) )
+        return 0;
+    if ( unlikely(__vmread(GUEST_RFLAGS) & X86_EFLAGS_VM) )
+        return 1;
+    cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
+    if ( vmx_long_mode_enabled(v) &&
+         likely(cs_ar_bytes & X86_SEG_AR_CS_LM_ACTIVE) )
+        return 8;
+    return (likely(cs_ar_bytes & X86_SEG_AR_DEF_OP_SIZE) ? 4 : 2);
+}
+
+static void vmx_save_dr(struct vcpu *v)
 {
     if ( !v->arch.hvm_vcpu.flag_dr_dirty )
         return;
@@ -444,7 +527,7 @@ static inline void vmx_save_dr(struct vc
     v->arch.guest_context.debugreg[7] = __vmread(GUEST_DR7);
 }
 
-static inline void __restore_debug_registers(struct vcpu *v)
+static void __restore_debug_registers(struct vcpu *v)
 {
     loaddebug(&v->arch.guest_context, 0);
     loaddebug(&v->arch.guest_context, 1);
@@ -455,9 +538,11 @@ static inline void __restore_debug_regis
     /* DR7 is loaded from the VMCS. */
 }
 
-int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
-{    
+void vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
+{
     uint32_t ev;
+
+    vmx_vmcs_enter(v);
 
     c->rip = __vmread(GUEST_RIP);
     c->rsp = __vmread(GUEST_RSP);
@@ -468,11 +553,11 @@ int vmx_vmcs_save(struct vcpu *v, struct
     c->cr3 = v->arch.hvm_vmx.cpu_cr3;
     c->cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
 
+    c->msr_efer = v->arch.hvm_vmx.efer;
+
 #ifdef HVM_DEBUG_SUSPEND
-    printk("vmx_vmcs_save: cr3=0x%"PRIx64", cr0=0x%"PRIx64", 
cr4=0x%"PRIx64".\n",
-            c->cr3,
-            c->cr0,
-            c->cr4);
+    printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
+           __func__, c->cr3, c->cr0, c->cr4);
 #endif
 
     c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
@@ -525,29 +610,31 @@ int vmx_vmcs_save(struct vcpu *v, struct
     c->sysenter_esp = __vmread(GUEST_SYSENTER_ESP);
     c->sysenter_eip = __vmread(GUEST_SYSENTER_EIP);
 
-    /* Save any event/interrupt that was being injected when we last
-     * exited.  IDT_VECTORING_INFO_FIELD has priority, as anything in
+    /*
+     * Save any event/interrupt that was being injected when we last
+     * exited. IDT_VECTORING_INFO_FIELD has priority, as anything in
      * VM_ENTRY_INTR_INFO_FIELD is either a fault caused by the first
      * event, which will happen the next time, or an interrupt, which we
-     * never inject when IDT_VECTORING_INFO_FIELD is valid.*/
-    if ( (ev = __vmread(IDT_VECTORING_INFO_FIELD)) & INTR_INFO_VALID_MASK ) 
+     * never inject when IDT_VECTORING_INFO_FIELD is valid.
+     */
+    if ( (ev = __vmread(IDT_VECTORING_INFO_FIELD)) & INTR_INFO_VALID_MASK )
     {
         c->pending_event = ev;
         c->error_code = __vmread(IDT_VECTORING_ERROR_CODE);
     }
-    else if ( (ev = __vmread(VM_ENTRY_INTR_INFO_FIELD)) 
-              & INTR_INFO_VALID_MASK ) 
+    else if ( (ev = __vmread(VM_ENTRY_INTR_INFO_FIELD)) &
+              INTR_INFO_VALID_MASK )
     {
         c->pending_event = ev;
         c->error_code = __vmread(VM_ENTRY_EXCEPTION_ERROR_CODE);
     }
-    else 
+    else
     {
         c->pending_event = 0;
         c->error_code = 0;
     }
 
-    return 1;
+    vmx_vmcs_exit(v);
 }
 
 int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
@@ -560,47 +647,47 @@ int vmx_vmcs_restore(struct vcpu *v, str
     __vmwrite(GUEST_RSP, c->rsp);
     __vmwrite(GUEST_RFLAGS, c->rflags);
 
-    v->arch.hvm_vmx.cpu_cr0 = (c->cr0 | X86_CR0_PE | X86_CR0_PG 
-                               | X86_CR0_NE | X86_CR0_WP | X86_CR0_ET);
+    v->arch.hvm_vmx.cpu_cr0 = (c->cr0 | X86_CR0_PE | X86_CR0_PG |
+                               X86_CR0_NE | X86_CR0_WP | X86_CR0_ET);
     __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
     v->arch.hvm_vmx.cpu_shadow_cr0 = c->cr0;
     __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
 
     v->arch.hvm_vmx.cpu_cr2 = c->cr2;
 
+    v->arch.hvm_vmx.efer = c->msr_efer;
+
 #ifdef HVM_DEBUG_SUSPEND
-    printk("vmx_vmcs_restore: cr3=0x%"PRIx64", cr0=0x%"PRIx64", 
cr4=0x%"PRIx64".\n",
-            c->cr3,
-            c->cr0,
-            c->cr4);
+    printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
+           __func__, c->cr3, c->cr0, c->cr4);
 #endif
 
-    if (!vmx_paging_enabled(v)) {
-        printk("vmx_vmcs_restore: paging not enabled.");
+    if ( !vmx_paging_enabled(v) )
+    {
+        HVM_DBG_LOG(DBG_LEVEL_VMMU, "%s: paging not enabled.", __func__);
         goto skip_cr3;
     }
 
-    HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64, c->cr3);
+    HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 = %"PRIx64, c->cr3);
     /* current!=vcpu as not called by arch_vmx_do_launch */
     mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT);
-    if( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain)) {
-        goto bad_cr3;
-    }
+    if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
+    {
+        gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64".\n", c->cr3);
+        vmx_vmcs_exit(v);
+        return -EINVAL;
+    }
+
     old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
     v->arch.guest_table = pagetable_from_pfn(mfn);
-    if (old_base_mfn)
+    if ( old_base_mfn )
         put_page(mfn_to_page(old_base_mfn));
+
     v->arch.hvm_vmx.cpu_cr3 = c->cr3;
 
  skip_cr3:
-#if defined(__x86_64__)
-    if (vmx_long_mode_enabled(v)) {
-        unsigned long vm_entry_value;
-        vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
-        vm_entry_value |= VM_ENTRY_IA32E_MODE;
-        __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
-    }
-#endif
+    if ( vmx_long_mode_enabled(v) )
+        vmx_enable_long_mode(v);
 
     __vmwrite(GUEST_CR4, (c->cr4 | HVM_CR4_HOST_MASK));
     v->arch.hvm_vmx.cpu_shadow_cr4 = c->cr4;
@@ -662,53 +749,53 @@ int vmx_vmcs_restore(struct vcpu *v, str
 
     paging_update_paging_modes(v);
 
-    if ( c->pending_valid ) 
+    if ( c->pending_valid )
     {
         vmx_vmcs_enter(v);
+
         gdprintk(XENLOG_INFO, "Re-injecting 0x%"PRIx32", 0x%"PRIx32"\n",
                  c->pending_event, c->error_code);
 
         /* SVM uses type 3 ("Exception") for #OF and #BP; VMX uses type 6 */
-        if ( c->pending_type == 3 
-             && (c->pending_vector == 3 || c->pending_vector == 4) ) 
+        if ( (c->pending_type == 3) &&
+             ((c->pending_vector == 3) || (c->pending_vector == 4)) )
             c->pending_type = 6;
 
-        /* For software exceptions, we need to tell the hardware the 
+        /* For software exceptions, we need to tell the hardware the
          * instruction length as well (hmmm). */
-        if ( c->pending_type > 4 ) 
+        if ( c->pending_type > 4 )
         {
-            int addrbytes, ilen; 
-            if ( (c->cs_arbytes & (1u<<13)) && (c->msr_efer & EFER_LMA) ) 
+            int addrbytes, ilen;
+            if ( (c->cs_arbytes & X86_SEG_AR_CS_LM_ACTIVE) &&
+                 (c->msr_efer & EFER_LMA) )
                 addrbytes = 8;
-            else if ( (c->cs_arbytes & (1u<<14)) ) 
+            else if ( c->cs_arbytes & X86_SEG_AR_DEF_OP_SIZE )
                 addrbytes = 4;
-            else 
+            else
                 addrbytes = 2;
+
             ilen = hvm_instruction_length(c->rip, addrbytes);
             __vmwrite(VM_ENTRY_INSTRUCTION_LEN, ilen);
         }
 
         /* Sanity check */
-        if ( c->pending_type == 1 || c->pending_type > 6
-             || c->pending_reserved != 0 )
+        if ( (c->pending_type == 1) || (c->pending_type > 6) ||
+             (c->pending_reserved != 0) )
         {
-            gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32"\n", 
+            gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32".\n",
                      c->pending_event);
             return -EINVAL;
         }
+
         /* Re-inject the exception */
         __vmwrite(VM_ENTRY_INTR_INFO_FIELD, c->pending_event);
         __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, c->error_code);
         v->arch.hvm_vmx.vector_injected = 1;
+
         vmx_vmcs_exit(v);
     }
 
     return 0;
-
- bad_cr3:
-    gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"", c->cr3);
-    vmx_vmcs_exit(v);
-    return -EINVAL;
 }
 
 #if defined(__x86_64__) && defined(HVM_DEBUG_SUSPEND)
@@ -717,14 +804,14 @@ static void dump_msr_state(struct vmx_ms
     int i = 0;
     printk("**** msr state ****\n");
     printk("shadow_gs=0x%lx, flags=0x%lx, msr_items:", m->shadow_gs, m->flags);
-    for (i = 0; i < VMX_MSR_COUNT; i++)
+    for ( i = 0; i < VMX_MSR_COUNT; i++ )
         printk("0x%lx,", m->msrs[i]);
     printk("\n");
 }
 #else
 #define dump_msr_state(m) ((void)0)
 #endif
-        
+
 static void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
 {
 #ifdef __x86_64__
@@ -741,10 +828,8 @@ static void vmx_save_cpu_state(struct vc
     data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
 #endif
 
-    data->msr_efer = v->arch.hvm_vmx.efer;
-
     data->tsc = hvm_get_guest_time(v);
-    
+
     dump_msr_state(guest_state);
 }
 
@@ -763,8 +848,6 @@ static void vmx_load_cpu_state(struct vc
     v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
 #endif
 
-    v->arch.hvm_vmx.efer = data->msr_efer;
-
     v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
 
     hvm_set_guest_time(v, data->tsc);
@@ -776,16 +859,16 @@ static void vmx_save_vmcs_ctxt(struct vc
 static void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
 {
     vmx_save_cpu_state(v, ctxt);
-    vmx_vmcs_enter(v);
     vmx_vmcs_save(v, ctxt);
-    vmx_vmcs_exit(v);
 }
 
 static int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
 {
     vmx_load_cpu_state(v, ctxt);
-    if (vmx_vmcs_restore(v, ctxt)) {
-        printk("vmx_vmcs restore failed!\n");
+
+    if ( vmx_vmcs_restore(v, ctxt) )
+    {
+        gdprintk(XENLOG_ERR, "vmx_vmcs restore failed!\n");
         domain_crash(v->domain);
         return -EINVAL;
     }
@@ -801,7 +884,7 @@ static int vmx_load_vmcs_ctxt(struct vcp
  */
 #define DR7_ACTIVE_MASK 0xff
 
-static inline void vmx_restore_dr(struct vcpu *v)
+static void vmx_restore_dr(struct vcpu *v)
 {
     /* NB. __vmread() is not usable here, so we cannot read from the VMCS. */
     if ( unlikely(v->arch.guest_context.debugreg[7] & DR7_ACTIVE_MASK) )
@@ -915,11 +998,9 @@ static unsigned long vmx_get_segment_bas
 
     ASSERT(v == current);
 
-#ifdef __x86_64__
     if ( vmx_long_mode_enabled(v) &&
          (__vmread(GUEST_CS_AR_BYTES) & X86_SEG_AR_CS_LM_ACTIVE) )
         long_mode = 1;
-#endif
 
     switch ( seg )
     {
@@ -1072,34 +1153,6 @@ static void vmx_init_hypercall_page(stru
     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 }
 
-static int vmx_guest_x86_mode(struct vcpu *v)
-{
-    unsigned int cs_ar_bytes;
-
-    ASSERT(v == current);
-
-    if ( unlikely(!(v->arch.hvm_vmx.cpu_shadow_cr0 & X86_CR0_PE)) )
-        return 0;
-    if ( unlikely(__vmread(GUEST_RFLAGS) & X86_EFLAGS_VM) )
-        return 1;
-    cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
-    if ( vmx_long_mode_enabled(v) && likely(cs_ar_bytes &
-                                            X86_SEG_AR_CS_LM_ACTIVE) )
-        return 8;
-    return (likely(cs_ar_bytes & X86_SEG_AR_DEF_OP_SIZE) ? 4 : 2);
-}
-
-static int vmx_pae_enabled(struct vcpu *v)
-{
-    unsigned long cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
-    return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
-}
-
-static int vmx_nx_enabled(struct vcpu *v)
-{
-    return v->arch.hvm_vmx.efer & EFER_NX;
-}
-
 static int vmx_interrupts_enabled(struct vcpu *v, enum hvm_intack type)
 {
     unsigned long intr_shadow, eflags;
@@ -1137,7 +1190,7 @@ static void vmx_update_guest_cr3(struct 
 
 static void vmx_flush_guest_tlbs(void)
 {
-    /* No tagged TLB support on VMX yet.  The fact that we're in Xen 
+    /* No tagged TLB support on VMX yet.  The fact that we're in Xen
      * at all means any guest will have a clean TLB when it's next run,
      * because VMRESUME will flush it for us. */
 }
@@ -1302,7 +1355,7 @@ static int __get_instruction_length(void
     return len;
 }
 
-static void inline __update_guest_eip(unsigned long inst_len)
+static void __update_guest_eip(unsigned long inst_len)
 {
     unsigned long x;
 
@@ -1605,10 +1658,10 @@ static int vmx_str_pio_check_descriptor(
 }
 
 
-static inline void vmx_str_pio_check_limit(u32 limit, unsigned int size,
-                                           u32 ar_bytes, unsigned long addr,
-                                           unsigned long base, int df,
-                                           unsigned long *count)
+static void vmx_str_pio_check_limit(u32 limit, unsigned int size,
+                                    u32 ar_bytes, unsigned long addr,
+                                    unsigned long base, int df,
+                                    unsigned long *count)
 {
     unsigned long ea = addr - base;
 
@@ -1664,10 +1717,10 @@ static inline void vmx_str_pio_check_lim
 }
 
 #ifdef __x86_64__
-static inline void vmx_str_pio_lm_check_limit(struct cpu_user_regs *regs,
-                                              unsigned int size,
-                                              unsigned long addr,
-                                              unsigned long *count)
+static void vmx_str_pio_lm_check_limit(struct cpu_user_regs *regs,
+                                       unsigned int size,
+                                       unsigned long addr,
+                                       unsigned long *count)
 {
     if ( !is_canonical_address(addr) ||
          !is_canonical_address(addr + size - 1) )
@@ -1693,12 +1746,12 @@ static inline void vmx_str_pio_lm_check_
 }
 #endif
 
-static inline void vmx_send_str_pio(struct cpu_user_regs *regs,
-                                    struct hvm_io_op *pio_opp,
-                                    unsigned long inst_len, unsigned int port,
-                                    int sign, unsigned int size, int dir,
-                                    int df, unsigned long addr,
-                                    unsigned long paddr, unsigned long count)
+static void vmx_send_str_pio(struct cpu_user_regs *regs,
+                             struct hvm_io_op *pio_opp,
+                             unsigned long inst_len, unsigned int port,
+                             int sign, unsigned int size, int dir,
+                             int df, unsigned long addr,
+                             unsigned long paddr, unsigned long count)
 {
     /*
      * Handle string pio instructions that cross pages or that
@@ -1754,10 +1807,10 @@ static inline void vmx_send_str_pio(stru
     }
 }
 
-static void vmx_str_pio_handler(unsigned long exit_qualification,
-                                unsigned long inst_len,
-                                struct cpu_user_regs *regs,
-                                struct hvm_io_op *pio_opp)
+static void vmx_do_str_pio(unsigned long exit_qualification,
+                           unsigned long inst_len,
+                           struct cpu_user_regs *regs,
+                           struct hvm_io_op *pio_opp)
 {
     unsigned int port, size;
     int dir, df, vm86;
@@ -1786,11 +1839,9 @@ static void vmx_str_pio_handler(unsigned
 
     sign = regs->eflags & X86_EFLAGS_DF ? -1 : 1;
     ar_bytes = __vmread(GUEST_CS_AR_BYTES);
-#ifdef __x86_64__
     if ( vmx_long_mode_enabled(current) &&
          (ar_bytes & X86_SEG_AR_CS_LM_ACTIVE) )
         long_mode = 1;
-#endif
     addr = __vmread(GUEST_LINEAR_ADDRESS);
 
     if ( test_bit(5, &exit_qualification) ) { /* "rep" prefix */
@@ -1874,7 +1925,7 @@ static void vmx_io_instruction(unsigned 
                 regs->cs, (unsigned long)regs->eip, exit_qualification);
 
     if ( test_bit(4, &exit_qualification) ) /* string instrucation */
-        vmx_str_pio_handler(exit_qualification, inst_len, regs, pio_opp);
+        vmx_do_str_pio(exit_qualification, inst_len, regs, pio_opp);
     else
     {
         unsigned int port, size;
@@ -2000,7 +2051,7 @@ static int vmx_world_restore(struct vcpu
             goto bad_cr3;
         old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
         v->arch.guest_table = pagetable_from_pfn(mfn);
-        if (old_base_mfn)
+        if ( old_base_mfn )
              put_page(mfn_to_page(old_base_mfn));
         v->arch.hvm_vmx.cpu_cr3 = c->cr3;
     }
@@ -2078,13 +2129,13 @@ static int vmx_assist(struct vcpu *v, in
     u32 magic, cp;
 
     /* make sure vmxassist exists (this is not an error) */
-    if (hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
-                                 sizeof(magic)))
+    if ( hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
+                                  sizeof(magic)) )
         return 0;
-    if (magic != VMXASSIST_MAGIC)
+    if ( magic != VMXASSIST_MAGIC )
         return 0;
 
-    switch (mode) {
+    switch ( mode ) {
         /*
          * Transfer control to vmxassist.
          * Store the current context in VMXASSIST_OLD_CONTEXT and load
@@ -2093,19 +2144,19 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_INVOKE:
         /* save the old context */
-        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
+        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
             goto error;
-        if (cp != 0) {
+        if ( cp != 0 ) {
             vmx_world_save(v, &c);
-            if (hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
+            if ( hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
                 goto error;
         }
 
         /* restore the new context, this should activate vmxassist */
-        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)))
+        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)) )
             goto error;
-        if (cp != 0) {
-            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
+        if ( cp != 0 ) {
+            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
                 goto error;
             if ( vmx_world_restore(v, &c) != 0 )
                 goto error;
@@ -2124,10 +2175,10 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_RESTORE:
         /* save the old context */
-        if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
+        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
             goto error;
-        if (cp != 0) {
-            if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
+        if ( cp != 0 ) {
+            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
                 goto error;
             if ( vmx_world_restore(v, &c) != 0 )
                 goto error;
@@ -2156,7 +2207,6 @@ static int vmx_set_cr0(unsigned long val
     unsigned long mfn;
     unsigned long eip;
     int paging_enabled;
-    unsigned long vm_entry_value;
     unsigned long old_cr0;
     unsigned long old_base_mfn;
 
@@ -2181,30 +2231,17 @@ static int vmx_set_cr0(unsigned long val
     old_cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
     paging_enabled = old_cr0 & X86_CR0_PG;
 
-    v->arch.hvm_vmx.cpu_cr0 = (value | X86_CR0_PE | X86_CR0_PG 
+    v->arch.hvm_vmx.cpu_cr0 = (value | X86_CR0_PE | X86_CR0_PG
                                | X86_CR0_NE | X86_CR0_WP);
     __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
 
     v->arch.hvm_vmx.cpu_shadow_cr0 = value;
     __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
 
+    /* Trying to enable paging. */
     if ( (value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled )
     {
-        /*
-         * Trying to enable guest paging.
-         * The guest CR3 must be pointing to the guest physical.
-         */
-        mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
-        if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
-        {
-            gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
-                     v->arch.hvm_vmx.cpu_cr3, mfn);
-            domain_crash(v->domain);
-            return 0;
-        }
-
-#if defined(__x86_64__)
-        if ( vmx_lme_is_set(v) )
+        if ( vmx_lme_is_set(v) && !vmx_long_mode_enabled(v) )
         {
             if ( !(v->arch.hvm_vmx.cpu_shadow_cr4 & X86_CR4_PAE) )
             {
@@ -2215,21 +2252,30 @@ static int vmx_set_cr0(unsigned long val
             else
             {
                 HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode");
-                v->arch.hvm_vmx.efer |= EFER_LMA;
-                vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
-                vm_entry_value |= VM_ENTRY_IA32E_MODE;
-                __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
+                vmx_enable_long_mode(v);
             }
         }
-#endif
+
+        /*
+         * The guest CR3 must be pointing to the guest physical.
+         */
+        mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
+        if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
+        {
+            gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
+                     v->arch.hvm_vmx.cpu_cr3, mfn);
+            domain_crash(v->domain);
+            return 0;
+        }
 
         /*
          * Now arch.guest_table points to machine physical.
          */
         old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
         v->arch.guest_table = pagetable_from_pfn(mfn);
-        if (old_base_mfn)
+        if ( old_base_mfn )
             put_page(mfn_to_page(old_base_mfn));
+
         paging_update_paging_modes(v);
 
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
@@ -2239,12 +2285,20 @@ static int vmx_set_cr0(unsigned long val
                     v->arch.hvm_vmx.cpu_cr3, mfn);
     }
 
-    if ( !((value & X86_CR0_PE) && (value & X86_CR0_PG)) && paging_enabled )
-        if ( v->arch.hvm_vmx.cpu_cr3 ) {
+    /* Trying to disable paging. */
+    if ( ((value & (X86_CR0_PE | X86_CR0_PG)) != (X86_CR0_PE | X86_CR0_PG)) &&
+         paging_enabled )
+    {
+        if ( v->arch.hvm_vmx.cpu_cr3 )
+        {
             put_page(mfn_to_page(get_mfn_from_gpfn(
                       v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT)));
             v->arch.guest_table = pagetable_null();
         }
+
+        if ( vmx_long_mode_enabled(v) )
+            vmx_disable_long_mode(v);
+    }
 
     /*
      * VMX does not implement real-mode virtualization. We emulate
@@ -2257,18 +2311,6 @@ static int vmx_set_cr0(unsigned long val
             /* inject GP here */
             vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
             return 0;
-        } else {
-            /*
-             * Disable paging here.
-             * Same to PE == 1 && PG == 0
-             */
-            if ( vmx_long_mode_enabled(v) )
-            {
-                v->arch.hvm_vmx.efer &= ~EFER_LMA;
-                vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
-                vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
-                __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
-            }
         }
 
         if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
@@ -2292,16 +2334,7 @@ static int vmx_set_cr0(unsigned long val
         }
     }
     else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
-    {
-        if ( vmx_long_mode_enabled(v) )
-        {
-            v->arch.hvm_vmx.efer &= ~EFER_LMA;
-            vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
-            vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
-            __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
-        }
         paging_update_paging_modes(v);
-    }
 
     return 1;
 }
@@ -2370,7 +2403,7 @@ static int mov_to_cr(int gp, int cr, str
         /*
          * If paging is not enabled yet, simply copy the value to CR3.
          */
-        if (!vmx_paging_enabled(v)) {
+        if ( !vmx_paging_enabled(v) ) {
             v->arch.hvm_vmx.cpu_cr3 = value;
             break;
         }
@@ -2378,14 +2411,14 @@ static int mov_to_cr(int gp, int cr, str
         /*
          * We make a new one if the shadow does not exist.
          */
-        if (value == v->arch.hvm_vmx.cpu_cr3) {
+        if ( value == v->arch.hvm_vmx.cpu_cr3 ) {
             /*
              * This is simple TLB flush, implying the guest has
              * removed some translation or changed page attributes.
              * We simply invalidate the shadow.
              */
             mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
-            if (mfn != pagetable_get_pfn(v->arch.guest_table))
+            if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
                 goto bad_cr3;
             paging_update_cr3(v);
         } else {
@@ -2399,7 +2432,7 @@ static int mov_to_cr(int gp, int cr, str
                 goto bad_cr3;
             old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
             v->arch.guest_table = pagetable_from_pfn(mfn);
-            if (old_base_mfn)
+            if ( old_base_mfn )
                 put_page(mfn_to_page(old_base_mfn));
             v->arch.hvm_vmx.cpu_cr3 = value;
             update_cr3(v);
@@ -2443,7 +2476,7 @@ static int mov_to_cr(int gp, int cr, str
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                             (unsigned long) (mfn << PAGE_SHIFT));
 
-                HVM_DBG_LOG(DBG_LEVEL_VMMU, 
+                HVM_DBG_LOG(DBG_LEVEL_VMMU,
                             "Update CR3 value = %lx, mfn = %lx",
                             v->arch.hvm_vmx.cpu_cr3, mfn);
 #endif
@@ -2469,6 +2502,7 @@ static int mov_to_cr(int gp, int cr, str
          */
         if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
             paging_update_paging_modes(v);
+
         break;
 
     case 8:
@@ -2545,7 +2579,7 @@ static int vmx_cr_access(unsigned long e
     unsigned long value;
     struct vcpu *v = current;
 
-    switch (exit_qualification & CONTROL_REG_ACCESS_TYPE) {
+    switch ( exit_qualification & CONTROL_REG_ACCESS_TYPE ) {
     case TYPE_MOV_TO_CR:
         gp = exit_qualification & CONTROL_REG_ACCESS_REG;
         cr = exit_qualification & CONTROL_REG_ACCESS_NUM;
@@ -2578,7 +2612,7 @@ static int vmx_cr_access(unsigned long e
     return 1;
 }
 
-static inline int vmx_do_msr_read(struct cpu_user_regs *regs)
+static int vmx_do_msr_read(struct cpu_user_regs *regs)
 {
     u64 msr_content = 0;
     u32 ecx = regs->ecx, eax, edx;
@@ -2699,7 +2733,7 @@ void vmx_vlapic_msr_changed(struct vcpu 
     vmx_vmcs_exit(v);
 }
 
-static inline int vmx_do_msr_write(struct cpu_user_regs *regs)
+static int vmx_do_msr_write(struct cpu_user_regs *regs)
 {
     u32 ecx = regs->ecx;
     u64 msr_content;
@@ -2752,7 +2786,7 @@ static void vmx_do_hlt(void)
     hvm_hlt(rflags);
 }
 
-static inline void vmx_do_extint(struct cpu_user_regs *regs)
+static void vmx_do_extint(struct cpu_user_regs *regs)
 {
     unsigned int vector;
 
diff -r 8528da5be577 -r 41c8284cfc0c xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Sat Jul 07 10:31:15 2007 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Sat Jul 07 11:08:57 2007 +0100
@@ -263,28 +263,6 @@ static inline int __vmxon (u64 addr)
     return rc;
 }
 
-static inline int vmx_paging_enabled(struct vcpu *v)
-{
-    unsigned long cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
-    return ((cr0 & (X86_CR0_PE|X86_CR0_PG)) == (X86_CR0_PE|X86_CR0_PG));
-}
-
-static inline int vmx_long_mode_enabled(struct vcpu *v)
-{
-    return v->arch.hvm_vmx.efer & EFER_LMA;
-}
-
-static inline int vmx_lme_is_set(struct vcpu *v)
-{
-    return v->arch.hvm_vmx.efer & EFER_LME;
-}
-
-static inline int vmx_pgbit_test(struct vcpu *v)
-{
-    unsigned long cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
-    return (cr0 & X86_CR0_PG);
-}
-
 static inline void __vmx_inject_exception(struct vcpu *v, int trap, int type,
                                          int error_code, int ilen)
 {

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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