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

[Xen-changelog] [xen-unstable] [HVM] Make copy_{to, from}_guest work for HVM domains.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID bfe12b4d45d3cf4c86bf81bc900e73554915ee76
# Parent  cec400df74622d761244706dd8eb46c572054686
[HVM] Make copy_{to,from}_guest work for HVM domains.
Signed-off-by: Steven Smith <ssmith@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c                 |    9 ++++-----
 xen/arch/x86/hvm/platform.c            |   14 ++++++++++++++
 xen/include/asm-x86/guest_access.h     |   20 +++++++++++++++++++-
 xen/include/asm-x86/hvm/guest_access.h |    7 +++++++
 xen/include/asm-x86/shadow.h           |    7 +++++++
 5 files changed, 51 insertions(+), 6 deletions(-)

diff -r cec400df7462 -r bfe12b4d45d3 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Aug 03 15:05:54 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Thu Aug 03 15:22:25 2006 +0100
@@ -254,7 +254,7 @@ int
 int
 hvm_copy(void *buf, unsigned long vaddr, int size, int dir)
 {
-    unsigned long gpa, mfn;
+    unsigned long mfn;
     char *addr;
     int count;
 
@@ -263,10 +263,9 @@ hvm_copy(void *buf, unsigned long vaddr,
         if (count > size)
             count = size;
 
-        if (hvm_paging_enabled(current)) {
-            gpa = gva_to_gpa(vaddr);
-            mfn = get_mfn_from_gpfn(gpa >> PAGE_SHIFT);
-        } else
+        if (hvm_paging_enabled(current))
+            mfn = gva_to_mfn(vaddr);
+        else
             mfn = get_mfn_from_gpfn(vaddr >> PAGE_SHIFT);
         if (mfn == INVALID_MFN)
             return 0;
diff -r cec400df7462 -r bfe12b4d45d3 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Thu Aug 03 15:05:54 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c       Thu Aug 03 15:22:25 2006 +0100
@@ -1034,6 +1034,20 @@ void handle_mmio(unsigned long va, unsig
     }
 }
 
+/* Note that copy_{to,from}_user_hvm don't set the A and D bits on
+   PTEs, and require the PTE to be writable even when they're only
+   trying to read from it.  The guest is expected to deal with
+   this. */
+unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len)
+{
+    return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT);
+}
+
+unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
+{
+    return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN);
+}
+
 /*
  * Local variables:
  * mode: C
diff -r cec400df7462 -r bfe12b4d45d3 xen/include/asm-x86/guest_access.h
--- a/xen/include/asm-x86/guest_access.h        Thu Aug 03 15:05:54 2006 +0100
+++ b/xen/include/asm-x86/guest_access.h        Thu Aug 03 15:22:25 2006 +0100
@@ -8,6 +8,8 @@
 #define __ASM_X86_GUEST_ACCESS_H__
 
 #include <asm/uaccess.h>
+#include <asm/hvm/support.h>
+#include <asm/hvm/guest_access.h>
 
 /* Is the guest handle a NULL reference? */
 #define guest_handle_is_null(hnd)        ((hnd).p == NULL)
@@ -28,6 +30,8 @@
 #define copy_to_guest_offset(hnd, off, ptr, nr) ({      \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
+    hvm_guest(current) ?                                \
+    copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
     copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));       \
 })
 
@@ -38,6 +42,8 @@
 #define copy_from_guest_offset(ptr, hnd, off, nr) ({    \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
+    hvm_guest(current) ?                                \
+    copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\
     copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));     \
 })
 
@@ -45,6 +51,8 @@
 #define copy_field_to_guest(hnd, ptr, field) ({         \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
+    hvm_guest(current) ?                                \
+    copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
     copy_to_user(_x, _y, sizeof(*_x));                  \
 })
 
@@ -52,6 +60,8 @@
 #define copy_field_from_guest(ptr, hnd, field) ({       \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
+    hvm_guest(current) ?                                \
+    copy_from_user_hvm(_y, _x, sizeof(*_x)) :           \
     copy_from_user(_y, _x, sizeof(*_x));                \
 })
 
@@ -60,29 +70,37 @@
  * Allows use of faster __copy_* functions.
  */
 #define guest_handle_okay(hnd, nr)                      \
-    array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))
+    (hvm_guest(current) || array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
 
 #define __copy_to_guest_offset(hnd, off, ptr, nr) ({    \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
+    hvm_guest(current) ?                                \
+    copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) :  \
     __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr));     \
 })
 
 #define __copy_from_guest_offset(ptr, hnd, off, nr) ({  \
     const typeof(ptr) _x = (hnd).p;                     \
     const typeof(ptr) _y = (ptr);                       \
+    hvm_guest(current) ?                                \
+    copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \
     __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr));   \
 })
 
 #define __copy_field_to_guest(hnd, ptr, field) ({       \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
+    hvm_guest(current) ?                                \
+    copy_to_user_hvm(_x, _y, sizeof(*_x)) :             \
     __copy_to_user(_x, _y, sizeof(*_x));                \
 })
 
 #define __copy_field_from_guest(ptr, hnd, field) ({     \
     const typeof(&(ptr)->field) _x = &(hnd).p->field;   \
     const typeof(&(ptr)->field) _y = &(ptr)->field;     \
+    hvm_guest(current) ?                                \
+    copy_from_user_hvm(_x, _y, sizeof(*_x)) :           \
     __copy_from_user(_y, _x, sizeof(*_x));              \
 })
 
diff -r cec400df7462 -r bfe12b4d45d3 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Thu Aug 03 15:05:54 2006 +0100
+++ b/xen/include/asm-x86/shadow.h      Thu Aug 03 15:22:25 2006 +0100
@@ -1734,6 +1734,13 @@ static inline unsigned long gva_to_gpa(u
     return l1e_get_paddr(gpte) + (gva & ~PAGE_MASK); 
 }
 #endif
+
+static inline unsigned long gva_to_mfn(unsigned long gva)
+{
+    unsigned long gpa = gva_to_gpa(gva);
+    return get_mfn_from_gpfn(gpa >> PAGE_SHIFT);
+}
+
 /************************************************************************/
 
 extern void __update_pagetables(struct vcpu *v);
diff -r cec400df7462 -r bfe12b4d45d3 xen/include/asm-x86/hvm/guest_access.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/hvm/guest_access.h    Thu Aug 03 15:22:25 2006 +0100
@@ -0,0 +1,7 @@
+#ifndef __ASM_X86_HVM_GUEST_ACCESS_H__
+#define __ASM_X86_HVM_GUEST_ACCESS_H__
+
+unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len);
+unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len);
+
+#endif /* __ASM_X86_HVM_GUEST_ACCESS_H__ */

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