ia64/xen-unstable

changeset 13059:6cbed96fedac

Clean-up hvm/shadow interaction around cr3 updates.

Signed-off-by: Steven Hand <steven@xensource.com>
author Steven Hand <steven@xensource.com>
date Fri Dec 15 11:47:24 2006 +0000 (2006-12-15)
parents ea12d26877a4
children 779e99f810ca
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/include/asm-x86/hvm/hvm.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Dec 15 11:33:50 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Dec 15 11:47:24 2006 +0000
     1.3 @@ -536,6 +536,12 @@ void hvm_do_hypercall(struct cpu_user_re
     1.4  
     1.5  #endif /* defined(__x86_64__) */
     1.6  
     1.7 +void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3)
     1.8 +{
     1.9 +    v->arch.hvm_vcpu.hw_cr3 = guest_cr3;
    1.10 +    hvm_funcs.update_guest_cr3(v);
    1.11 +}
    1.12 +
    1.13  /* Initialise a hypercall transfer page for a VMX domain using
    1.14     paravirtualised drivers. */
    1.15  void hvm_hypercall_page_initialise(struct domain *d,
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Dec 15 11:33:50 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Dec 15 11:47:24 2006 +0000
     2.3 @@ -498,6 +498,11 @@ void svm_update_host_cr3(struct vcpu *v)
     2.4      /* SVM doesn't have a HOST_CR3 equivalent to update. */
     2.5  }
     2.6  
     2.7 +void svm_update_guest_cr3(struct vcpu *v)
     2.8 +{
     2.9 +    v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
    2.10 +}
    2.11 +
    2.12  unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
    2.13  {
    2.14      switch ( num )
    2.15 @@ -883,6 +888,7 @@ int start_svm(void)
    2.16      hvm_funcs.get_segment_register = svm_get_segment_register;
    2.17  
    2.18      hvm_funcs.update_host_cr3 = svm_update_host_cr3;
    2.19 +    hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
    2.20      
    2.21      hvm_funcs.stts = svm_stts;
    2.22      hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
    2.23 @@ -1608,7 +1614,6 @@ static int svm_set_cr0(unsigned long val
    2.24          HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
    2.25                      (unsigned long) (mfn << PAGE_SHIFT));
    2.26  
    2.27 -        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
    2.28          set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
    2.29      }
    2.30  
    2.31 @@ -1630,7 +1635,6 @@ static int svm_set_cr0(unsigned long val
    2.32              return 0;
    2.33          }
    2.34          shadow_update_paging_modes(v);
    2.35 -        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
    2.36          set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
    2.37      }
    2.38      else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
    2.39 @@ -1642,7 +1646,6 @@ static int svm_set_cr0(unsigned long val
    2.40          }
    2.41          /* we should take care of this kind of situation */
    2.42          shadow_update_paging_modes(v);
    2.43 -        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
    2.44          set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
    2.45      }
    2.46  
    2.47 @@ -1768,7 +1771,6 @@ static int mov_to_cr(int gpreg, int cr, 
    2.48  
    2.49              v->arch.hvm_svm.cpu_cr3 = value;
    2.50              update_cr3(v);
    2.51 -            vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
    2.52              HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
    2.53          }
    2.54          break;
    2.55 @@ -1804,8 +1806,6 @@ static int mov_to_cr(int gpreg, int cr, 
    2.56                  HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
    2.57                              (unsigned long) (mfn << PAGE_SHIFT));
    2.58  
    2.59 -                vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
    2.60 -
    2.61                  HVM_DBG_LOG(DBG_LEVEL_VMMU, 
    2.62                              "Update CR3 value = %lx, mfn = %lx",
    2.63                              v->arch.hvm_svm.cpu_cr3, mfn);
     3.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Dec 15 11:33:50 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Dec 15 11:47:24 2006 +0000
     3.3 @@ -430,11 +430,9 @@ static void construct_vmcs(struct vcpu *
     3.4      __vmwrite(GUEST_TR_BASE, 0);
     3.5      __vmwrite(GUEST_TR_LIMIT, 0xff);
     3.6  
     3.7 -    shadow_update_paging_modes(v);
     3.8 -    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
     3.9 -    __vmwrite(HOST_CR3, v->arch.cr3);
    3.10 +    vmx_vmcs_exit(v);
    3.11  
    3.12 -    vmx_vmcs_exit(v);
    3.13 +    shadow_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
    3.14  }
    3.15  
    3.16  int vmx_create_vmcs(struct vcpu *v)
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 15 11:33:50 2006 +0000
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 15 11:47:24 2006 +0000
     4.3 @@ -708,13 +708,23 @@ static int vmx_pae_enabled(struct vcpu *
     4.4      return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
     4.5  }
     4.6  
     4.7 -/* Works only for vcpu == current */
     4.8  static void vmx_update_host_cr3(struct vcpu *v)
     4.9  {
    4.10 -    ASSERT(v == current);
    4.11 +    ASSERT( (v == current) || !vcpu_runnable(v) );
    4.12 +    vmx_vmcs_enter(v);
    4.13      __vmwrite(HOST_CR3, v->arch.cr3);
    4.14 +    vmx_vmcs_exit(v);
    4.15  }
    4.16  
    4.17 +static void vmx_update_guest_cr3(struct vcpu *v)
    4.18 +{
    4.19 +    ASSERT( (v == current) || !vcpu_runnable(v) );
    4.20 +    vmx_vmcs_enter(v);
    4.21 +    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.22 +    vmx_vmcs_exit(v);
    4.23 +}
    4.24 +
    4.25 +
    4.26  static void vmx_inject_exception(
    4.27      unsigned int trapnr, int errcode, unsigned long cr2)
    4.28  {
    4.29 @@ -747,6 +757,7 @@ static void vmx_setup_hvm_funcs(void)
    4.30      hvm_funcs.get_segment_register = vmx_get_segment_register;
    4.31  
    4.32      hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
    4.33 +    hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
    4.34  
    4.35      hvm_funcs.stts = vmx_stts;
    4.36      hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
    4.37 @@ -1531,7 +1542,6 @@ static int vmx_world_restore(struct vcpu
    4.38      __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
    4.39  
    4.40      shadow_update_paging_modes(v);
    4.41 -    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.42      return 0;
    4.43  
    4.44   bad_cr3:
    4.45 @@ -1689,7 +1699,6 @@ static int vmx_set_cr0(unsigned long val
    4.46          HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
    4.47                      (unsigned long) (mfn << PAGE_SHIFT));
    4.48  
    4.49 -        __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.50          /*
    4.51           * arch->shadow_table should hold the next CR3 for shadow
    4.52           */
    4.53 @@ -1761,7 +1770,6 @@ static int vmx_set_cr0(unsigned long val
    4.54              __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
    4.55          }
    4.56          shadow_update_paging_modes(v);
    4.57 -        __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.58      }
    4.59  
    4.60      return 1;
    4.61 @@ -1869,9 +1877,7 @@ static int mov_to_cr(int gp, int cr, str
    4.62               */
    4.63              v->arch.hvm_vmx.cpu_cr3 = value;
    4.64              update_cr3(v);
    4.65 -            HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx",
    4.66 -                        value);
    4.67 -            __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.68 +            HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
    4.69          }
    4.70          break;
    4.71  
    4.72 @@ -1902,13 +1908,11 @@ static int mov_to_cr(int gp, int cr, str
    4.73                  HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
    4.74                              (unsigned long) (mfn << PAGE_SHIFT));
    4.75  
    4.76 -                __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
    4.77 -
    4.78                  /*
    4.79                   * arch->shadow_table should hold the next CR3 for shadow
    4.80                   */
    4.81 -
    4.82 -                HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = %lx",
    4.83 +                HVM_DBG_LOG(DBG_LEVEL_VMMU, 
    4.84 +                            "Update CR3 value = %lx, mfn = %lx",
    4.85                              v->arch.hvm_vmx.cpu_cr3, mfn);
    4.86  #endif
    4.87              }
     5.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Dec 15 11:33:50 2006 +0000
     5.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Dec 15 11:47:24 2006 +0000
     5.3 @@ -2495,7 +2495,9 @@ void sh_update_paging_modes(struct vcpu 
     5.4          {
     5.5              mfn_t mmfn = shadow_make_monitor_table(v);
     5.6              v->arch.monitor_table = pagetable_from_mfn(mmfn);
     5.7 -        } 
     5.8 +            make_cr3(v, mfn_x(mmfn));
     5.9 +            hvm_update_host_cr3(v);
    5.10 +        }
    5.11  
    5.12          if ( v->arch.shadow.mode != old_mode )
    5.13          {
     6.1 --- a/xen/arch/x86/mm/shadow/multi.c	Fri Dec 15 11:33:50 2006 +0000
     6.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Dec 15 11:47:24 2006 +0000
     6.3 @@ -2817,7 +2817,7 @@ static int sh_page_fault(struct vcpu *v,
     6.4  
     6.5      if ( is_hvm_domain(d) )
     6.6          hvm_store_cpu_guest_regs(v, regs, NULL);
     6.7 -    SHADOW_PRINTK("emulate: eip=%#lx\n", regs->eip);
     6.8 +    SHADOW_PRINTK("emulate: eip=%#lx\n", (unsigned long)regs->eip);
     6.9  
    6.10      emul_ops = shadow_init_emulation(&emul_ctxt, regs);
    6.11  
    6.12 @@ -3561,10 +3561,10 @@ sh_update_cr3(struct vcpu *v)
    6.13          ASSERT(is_hvm_domain(d));
    6.14  #if SHADOW_PAGING_LEVELS == 3
    6.15          /* 2-on-3 or 3-on-3: Use the PAE shadow l3 table we just fabricated */
    6.16 -        v->arch.hvm_vcpu.hw_cr3 = virt_to_maddr(&v->arch.shadow.l3table);
    6.17 +        hvm_update_guest_cr3(v, virt_to_maddr(&v->arch.shadow.l3table));
    6.18  #else
    6.19          /* 2-on-2 or 4-on-4: Just use the shadow top-level directly */
    6.20 -        v->arch.hvm_vcpu.hw_cr3 = pagetable_get_paddr(v->arch.shadow_table[0]);
    6.21 +        hvm_update_guest_cr3(v, pagetable_get_paddr(v->arch.shadow_table[0]));
    6.22  #endif
    6.23      }
    6.24  
     7.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Dec 15 11:33:50 2006 +0000
     7.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Dec 15 11:47:24 2006 +0000
     7.3 @@ -103,6 +103,11 @@ struct hvm_function_table {
     7.4      void (*update_host_cr3)(struct vcpu *v);
     7.5  
     7.6      /*
     7.7 +     * Called to inform HVM layer that a guest cr3 has changed
     7.8 +     */
     7.9 +    void (*update_guest_cr3)(struct vcpu *v);
    7.10 +
    7.11 +    /*
    7.12       * Update specifics of the guest state:
    7.13       * 1) TS bit in guest cr0 
    7.14       * 2) TSC offset in guest
    7.15 @@ -188,6 +193,8 @@ hvm_update_host_cr3(struct vcpu *v)
    7.16      hvm_funcs.update_host_cr3(v);
    7.17  }
    7.18  
    7.19 +void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
    7.20 +
    7.21  void hvm_hypercall_page_initialise(struct domain *d,
    7.22                                     void *hypercall_page);
    7.23