ia64/xen-unstable

changeset 11676:412fc1c1bd7a

[HVM][VMX] Fix data copying in transition to/from vmxassist.

In vmx_assist, the copy for new/old context and vmx assist magic are
all using physical address, while hvm_copy will use the virtual address.

This may cause problem when guest jump directly from real mode to
paging mode.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Sep 29 10:30:18 2006 +0100 (2006-09-29)
parents 6d5d5b883dfc
children 058f4a2a8642
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/support.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Fri Sep 29 09:29:20 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Fri Sep 29 10:30:18 2006 +0100
     1.3 @@ -389,44 +389,59 @@ void hvm_hlt(unsigned long rflags)
     1.4  }
     1.5  
     1.6  /*
     1.7 - * Copy from/to guest virtual.
     1.8 + * __hvm_copy():
     1.9 + *  @buf  = hypervisor buffer
    1.10 + *  @addr = guest virtual or physical address to copy to/from
    1.11 + *  @size = number of bytes to copy
    1.12 + *  @dir  = HVM_COPY_IN / HVM_COPY_OUT
    1.13 + *  @phy  = interpret addr as physical or virtual address?
    1.14 + * Returns TRUE on success.
    1.15   */
    1.16 -int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
    1.17 +static int __hvm_copy(
    1.18 +    void *buf, unsigned long addr, int size, int dir, int phy)
    1.19  {
    1.20      struct vcpu *v = current;
    1.21 -    unsigned long gfn;
    1.22      unsigned long mfn;
    1.23 -    char *addr;
    1.24 +    char *p;
    1.25      int count;
    1.26  
    1.27 -    while (size > 0) {
    1.28 -        count = PAGE_SIZE - (vaddr & ~PAGE_MASK);
    1.29 -        if (count > size)
    1.30 -            count = size;
    1.31 +    while ( size > 0 )
    1.32 +    {
    1.33 +        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), size);
    1.34  
    1.35 -        gfn = shadow_gva_to_gfn(v, vaddr);
    1.36 -        mfn = mfn_x(sh_vcpu_gfn_to_mfn(v, gfn));
    1.37 -
    1.38 -        if (mfn == INVALID_MFN)
    1.39 +        mfn = phy ? 
    1.40 +            get_mfn_from_gpfn(addr >> PAGE_SHIFT) :
    1.41 +            mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr)));
    1.42 +        if ( mfn == INVALID_MFN )
    1.43              return 0;
    1.44  
    1.45 -        addr = (char *)map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
    1.46 +        p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK);
    1.47  
    1.48 -        if (dir == HVM_COPY_IN)
    1.49 -            memcpy(buf, addr, count);
    1.50 +        if ( dir == HVM_COPY_IN )
    1.51 +            memcpy(buf, p, count);
    1.52          else
    1.53 -            memcpy(addr, buf, count);
    1.54 +            memcpy(p, buf, count);
    1.55  
    1.56 -        unmap_domain_page(addr);
    1.57 +        unmap_domain_page(p);
    1.58  
    1.59 -        vaddr += count;
    1.60 -        buf += count;
    1.61 +        addr += count;
    1.62 +        buf  += count;
    1.63          size -= count;
    1.64      }
    1.65  
    1.66      return 1;
    1.67  }
    1.68  
    1.69 +int hvm_copy_phy(void *buf, unsigned long paddr, int size, int dir)
    1.70 +{
    1.71 +    return __hvm_copy(buf, paddr, size, dir, 1);
    1.72 +}
    1.73 +
    1.74 +int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
    1.75 +{
    1.76 +    return __hvm_copy(buf, vaddr, size, dir, 0);
    1.77 +}
    1.78 +
    1.79  /*
    1.80   * HVM specific printbuf. Mostly used for hvmloader chit-chat.
    1.81   */
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 29 09:29:20 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Sep 29 10:30:18 2006 +0100
     2.3 @@ -1371,7 +1371,7 @@ static int vmx_assist(struct vcpu *v, in
     2.4      u32 cp;
     2.5  
     2.6      /* make sure vmxassist exists (this is not an error) */
     2.7 -    if (!hvm_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN))
     2.8 +    if (!hvm_copy_phy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN))
     2.9          return 0;
    2.10      if (magic != VMXASSIST_MAGIC)
    2.11          return 0;
    2.12 @@ -1385,20 +1385,20 @@ static int vmx_assist(struct vcpu *v, in
    2.13           */
    2.14      case VMX_ASSIST_INVOKE:
    2.15          /* save the old context */
    2.16 -        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.17 +        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.18              goto error;
    2.19          if (cp != 0) {
    2.20              if (!vmx_world_save(v, &c))
    2.21                  goto error;
    2.22 -            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_OUT))
    2.23 +            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_OUT))
    2.24                  goto error;
    2.25          }
    2.26  
    2.27          /* restore the new context, this should activate vmxassist */
    2.28 -        if (!hvm_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.29 +        if (!hvm_copy_phy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.30              goto error;
    2.31          if (cp != 0) {
    2.32 -            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
    2.33 +            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
    2.34                  goto error;
    2.35              if (!vmx_world_restore(v, &c))
    2.36                  goto error;
    2.37 @@ -1412,10 +1412,10 @@ static int vmx_assist(struct vcpu *v, in
    2.38           */
    2.39      case VMX_ASSIST_RESTORE:
    2.40          /* save the old context */
    2.41 -        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.42 +        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
    2.43              goto error;
    2.44          if (cp != 0) {
    2.45 -            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
    2.46 +            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
    2.47                  goto error;
    2.48              if (!vmx_world_restore(v, &c))
    2.49                  goto error;
     3.1 --- a/xen/include/asm-x86/hvm/support.h	Fri Sep 29 09:29:20 2006 +0100
     3.2 +++ b/xen/include/asm-x86/hvm/support.h	Fri Sep 29 10:30:18 2006 +0100
     3.3 @@ -138,6 +138,7 @@ extern int hvm_enabled;
     3.4  
     3.5  enum { HVM_COPY_IN = 0, HVM_COPY_OUT };
     3.6  extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir);
     3.7 +extern int hvm_copy_phy(void *buf, unsigned long vaddr, int size, int dir);
     3.8  
     3.9  extern void hvm_setup_platform(struct domain* d);
    3.10  extern int hvm_mmio_intercept(ioreq_t *p);