# 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
|