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

[Xen-changelog] [xen-unstable] [HVM][VMX] Fix data copying in transition to/from vmxassist.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 412fc1c1bd7a8ac70dace63b84bcc075c1fb8e0b
# Parent  6d5d5b883dfcf60f0b17fcfc31269e43aecd5b0c
[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@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            |   81 ++++++++++++++++++++++----------------
 xen/arch/x86/hvm/vmx/vmx.c        |   14 +++---
 xen/include/asm-x86/hvm/support.h |    1 
 3 files changed, 56 insertions(+), 40 deletions(-)

diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Sep 29 09:29:20 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Fri Sep 29 10:30:18 2006 +0100
@@ -389,42 +389,57 @@ void hvm_hlt(unsigned long rflags)
 }
 
 /*
- * Copy from/to guest virtual.
+ * __hvm_copy():
+ *  @buf  = hypervisor buffer
+ *  @addr = guest virtual or physical address to copy to/from
+ *  @size = number of bytes to copy
+ *  @dir  = HVM_COPY_IN / HVM_COPY_OUT
+ *  @phy  = interpret addr as physical or virtual address?
+ * Returns TRUE on success.
  */
+static int __hvm_copy(
+    void *buf, unsigned long addr, int size, int dir, int phy)
+{
+    struct vcpu *v = current;
+    unsigned long mfn;
+    char *p;
+    int count;
+
+    while ( size > 0 )
+    {
+        count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), size);
+
+        mfn = phy ? 
+            get_mfn_from_gpfn(addr >> PAGE_SHIFT) :
+            mfn_x(sh_vcpu_gfn_to_mfn(v, shadow_gva_to_gfn(v, addr)));
+        if ( mfn == INVALID_MFN )
+            return 0;
+
+        p = (char *)map_domain_page(mfn) + (addr & ~PAGE_MASK);
+
+        if ( dir == HVM_COPY_IN )
+            memcpy(buf, p, count);
+        else
+            memcpy(p, buf, count);
+
+        unmap_domain_page(p);
+
+        addr += count;
+        buf  += count;
+        size -= count;
+    }
+
+    return 1;
+}
+
+int hvm_copy_phy(void *buf, unsigned long paddr, int size, int dir)
+{
+    return __hvm_copy(buf, paddr, size, dir, 1);
+}
+
 int hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
 {
-    struct vcpu *v = current;
-    unsigned long gfn;
-    unsigned long mfn;
-    char *addr;
-    int count;
-
-    while (size > 0) {
-        count = PAGE_SIZE - (vaddr & ~PAGE_MASK);
-        if (count > size)
-            count = size;
-
-        gfn = shadow_gva_to_gfn(v, vaddr);
-        mfn = mfn_x(sh_vcpu_gfn_to_mfn(v, gfn));
-
-        if (mfn == INVALID_MFN)
-            return 0;
-
-        addr = (char *)map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
-
-        if (dir == HVM_COPY_IN)
-            memcpy(buf, addr, count);
-        else
-            memcpy(addr, buf, count);
-
-        unmap_domain_page(addr);
-
-        vaddr += count;
-        buf += count;
-        size -= count;
-    }
-
-    return 1;
+    return __hvm_copy(buf, vaddr, size, dir, 0);
 }
 
 /*
diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Sep 29 09:29:20 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Sep 29 10:30:18 2006 +0100
@@ -1371,7 +1371,7 @@ static int vmx_assist(struct vcpu *v, in
     u32 cp;
 
     /* make sure vmxassist exists (this is not an error) */
-    if (!hvm_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), HVM_COPY_IN))
+    if (!hvm_copy_phy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), 
HVM_COPY_IN))
         return 0;
     if (magic != VMXASSIST_MAGIC)
         return 0;
@@ -1385,20 +1385,20 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_INVOKE:
         /* save the old context */
-        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
             goto error;
         if (cp != 0) {
             if (!vmx_world_save(v, &c))
                 goto error;
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_OUT))
+            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_OUT))
                 goto error;
         }
 
         /* restore the new context, this should activate vmxassist */
-        if (!hvm_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (!hvm_copy_phy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), HVM_COPY_IN))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
@@ -1412,10 +1412,10 @@ static int vmx_assist(struct vcpu *v, in
          */
     case VMX_ASSIST_RESTORE:
         /* save the old context */
-        if (!hvm_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
+        if (!hvm_copy_phy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), HVM_COPY_IN))
             goto error;
         if (cp != 0) {
-            if (!hvm_copy(&c, cp, sizeof(c), HVM_COPY_IN))
+            if (!hvm_copy_phy(&c, cp, sizeof(c), HVM_COPY_IN))
                 goto error;
             if (!vmx_world_restore(v, &c))
                 goto error;
diff -r 6d5d5b883dfc -r 412fc1c1bd7a xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Fri Sep 29 09:29:20 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Fri Sep 29 10:30:18 2006 +0100
@@ -138,6 +138,7 @@ extern int hvm_enabled;
 
 enum { HVM_COPY_IN = 0, HVM_COPY_OUT };
 extern int hvm_copy(void *buf, unsigned long vaddr, int size, int dir);
+extern int hvm_copy_phy(void *buf, unsigned long vaddr, int size, int dir);
 
 extern void hvm_setup_platform(struct domain* d);
 extern int hvm_mmio_intercept(ioreq_t *p);

_______________________________________________
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®.