direct-io.hg
changeset 10920:bfe12b4d45d3
[HVM] Make copy_{to,from}_guest work for HVM domains.
Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Steven Smith <ssmith@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Thu Aug 03 15:22:25 2006 +0100 (2006-08-03) |
parents | cec400df7462 |
children | 4c2fab8f8c34 |
files | xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/platform.c xen/include/asm-x86/guest_access.h xen/include/asm-x86/hvm/guest_access.h xen/include/asm-x86/shadow.h |
line diff
1.1 --- a/xen/arch/x86/hvm/hvm.c Thu Aug 03 15:05:54 2006 +0100 1.2 +++ b/xen/arch/x86/hvm/hvm.c Thu Aug 03 15:22:25 2006 +0100 1.3 @@ -254,7 +254,7 @@ int cpu_get_interrupt(struct vcpu *v, in 1.4 int 1.5 hvm_copy(void *buf, unsigned long vaddr, int size, int dir) 1.6 { 1.7 - unsigned long gpa, mfn; 1.8 + unsigned long mfn; 1.9 char *addr; 1.10 int count; 1.11 1.12 @@ -263,10 +263,9 @@ hvm_copy(void *buf, unsigned long vaddr, 1.13 if (count > size) 1.14 count = size; 1.15 1.16 - if (hvm_paging_enabled(current)) { 1.17 - gpa = gva_to_gpa(vaddr); 1.18 - mfn = get_mfn_from_gpfn(gpa >> PAGE_SHIFT); 1.19 - } else 1.20 + if (hvm_paging_enabled(current)) 1.21 + mfn = gva_to_mfn(vaddr); 1.22 + else 1.23 mfn = get_mfn_from_gpfn(vaddr >> PAGE_SHIFT); 1.24 if (mfn == INVALID_MFN) 1.25 return 0;
2.1 --- a/xen/arch/x86/hvm/platform.c Thu Aug 03 15:05:54 2006 +0100 2.2 +++ b/xen/arch/x86/hvm/platform.c Thu Aug 03 15:22:25 2006 +0100 2.3 @@ -1034,6 +1034,20 @@ void handle_mmio(unsigned long va, unsig 2.4 } 2.5 } 2.6 2.7 +/* Note that copy_{to,from}_user_hvm don't set the A and D bits on 2.8 + PTEs, and require the PTE to be writable even when they're only 2.9 + trying to read from it. The guest is expected to deal with 2.10 + this. */ 2.11 +unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len) 2.12 +{ 2.13 + return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT); 2.14 +} 2.15 + 2.16 +unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len) 2.17 +{ 2.18 + return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN); 2.19 +} 2.20 + 2.21 /* 2.22 * Local variables: 2.23 * mode: C
3.1 --- a/xen/include/asm-x86/guest_access.h Thu Aug 03 15:05:54 2006 +0100 3.2 +++ b/xen/include/asm-x86/guest_access.h Thu Aug 03 15:22:25 2006 +0100 3.3 @@ -8,6 +8,8 @@ 3.4 #define __ASM_X86_GUEST_ACCESS_H__ 3.5 3.6 #include <asm/uaccess.h> 3.7 +#include <asm/hvm/support.h> 3.8 +#include <asm/hvm/guest_access.h> 3.9 3.10 /* Is the guest handle a NULL reference? */ 3.11 #define guest_handle_is_null(hnd) ((hnd).p == NULL) 3.12 @@ -28,6 +30,8 @@ 3.13 #define copy_to_guest_offset(hnd, off, ptr, nr) ({ \ 3.14 const typeof(ptr) _x = (hnd).p; \ 3.15 const typeof(ptr) _y = (ptr); \ 3.16 + hvm_guest(current) ? \ 3.17 + copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \ 3.18 copy_to_user(_x+(off), _y, sizeof(*_x)*(nr)); \ 3.19 }) 3.20 3.21 @@ -38,6 +42,8 @@ 3.22 #define copy_from_guest_offset(ptr, hnd, off, nr) ({ \ 3.23 const typeof(ptr) _x = (hnd).p; \ 3.24 const typeof(ptr) _y = (ptr); \ 3.25 + hvm_guest(current) ? \ 3.26 + copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\ 3.27 copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \ 3.28 }) 3.29 3.30 @@ -45,6 +51,8 @@ 3.31 #define copy_field_to_guest(hnd, ptr, field) ({ \ 3.32 const typeof(&(ptr)->field) _x = &(hnd).p->field; \ 3.33 const typeof(&(ptr)->field) _y = &(ptr)->field; \ 3.34 + hvm_guest(current) ? \ 3.35 + copy_to_user_hvm(_x, _y, sizeof(*_x)) : \ 3.36 copy_to_user(_x, _y, sizeof(*_x)); \ 3.37 }) 3.38 3.39 @@ -52,6 +60,8 @@ 3.40 #define copy_field_from_guest(ptr, hnd, field) ({ \ 3.41 const typeof(&(ptr)->field) _x = &(hnd).p->field; \ 3.42 const typeof(&(ptr)->field) _y = &(ptr)->field; \ 3.43 + hvm_guest(current) ? \ 3.44 + copy_from_user_hvm(_y, _x, sizeof(*_x)) : \ 3.45 copy_from_user(_y, _x, sizeof(*_x)); \ 3.46 }) 3.47 3.48 @@ -60,29 +70,37 @@ 3.49 * Allows use of faster __copy_* functions. 3.50 */ 3.51 #define guest_handle_okay(hnd, nr) \ 3.52 - array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)) 3.53 + (hvm_guest(current) || array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))) 3.54 3.55 #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \ 3.56 const typeof(ptr) _x = (hnd).p; \ 3.57 const typeof(ptr) _y = (ptr); \ 3.58 + hvm_guest(current) ? \ 3.59 + copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \ 3.60 __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr)); \ 3.61 }) 3.62 3.63 #define __copy_from_guest_offset(ptr, hnd, off, nr) ({ \ 3.64 const typeof(ptr) _x = (hnd).p; \ 3.65 const typeof(ptr) _y = (ptr); \ 3.66 + hvm_guest(current) ? \ 3.67 + copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \ 3.68 __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \ 3.69 }) 3.70 3.71 #define __copy_field_to_guest(hnd, ptr, field) ({ \ 3.72 const typeof(&(ptr)->field) _x = &(hnd).p->field; \ 3.73 const typeof(&(ptr)->field) _y = &(ptr)->field; \ 3.74 + hvm_guest(current) ? \ 3.75 + copy_to_user_hvm(_x, _y, sizeof(*_x)) : \ 3.76 __copy_to_user(_x, _y, sizeof(*_x)); \ 3.77 }) 3.78 3.79 #define __copy_field_from_guest(ptr, hnd, field) ({ \ 3.80 const typeof(&(ptr)->field) _x = &(hnd).p->field; \ 3.81 const typeof(&(ptr)->field) _y = &(ptr)->field; \ 3.82 + hvm_guest(current) ? \ 3.83 + copy_from_user_hvm(_x, _y, sizeof(*_x)) : \ 3.84 __copy_from_user(_y, _x, sizeof(*_x)); \ 3.85 }) 3.86
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/xen/include/asm-x86/hvm/guest_access.h Thu Aug 03 15:22:25 2006 +0100 4.3 @@ -0,0 +1,7 @@ 4.4 +#ifndef __ASM_X86_HVM_GUEST_ACCESS_H__ 4.5 +#define __ASM_X86_HVM_GUEST_ACCESS_H__ 4.6 + 4.7 +unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len); 4.8 +unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len); 4.9 + 4.10 +#endif /* __ASM_X86_HVM_GUEST_ACCESS_H__ */
5.1 --- a/xen/include/asm-x86/shadow.h Thu Aug 03 15:05:54 2006 +0100 5.2 +++ b/xen/include/asm-x86/shadow.h Thu Aug 03 15:22:25 2006 +0100 5.3 @@ -1734,6 +1734,13 @@ static inline unsigned long gva_to_gpa(u 5.4 return l1e_get_paddr(gpte) + (gva & ~PAGE_MASK); 5.5 } 5.6 #endif 5.7 + 5.8 +static inline unsigned long gva_to_mfn(unsigned long gva) 5.9 +{ 5.10 + unsigned long gpa = gva_to_gpa(gva); 5.11 + return get_mfn_from_gpfn(gpa >> PAGE_SHIFT); 5.12 +} 5.13 + 5.14 /************************************************************************/ 5.15 5.16 extern void __update_pagetables(struct vcpu *v);