[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Re: how to handle paged hypercall args?
On Thu, Nov 18, Keir Fraser wrote: > I've done something along these lines now as xen-unstable:22402. It actually > seems to work okay! So you can go ahead and use waitqueues in __hvm_copy() > now. This is my first attempt to do it. It crashed Xen on the very first try in a spectacular way. But it happend only once for some reason. See my other mail. Olaf --- xen-unstable.hg-4.1.22447.orig/xen/arch/x86/hvm/hvm.c +++ xen-unstable.hg-4.1.22447/xen/arch/x86/hvm/hvm.c @@ -1986,69 +1986,117 @@ static enum hvm_copy_result __hvm_copy( enum hvm_copy_result hvm_copy_to_guest_phys( paddr_t paddr, void *buf, int size) { - return __hvm_copy(buf, paddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, paddr, size, HVMCOPY_to_guest | HVMCOPY_fault | HVMCOPY_phys, - 0); + 0)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_copy_from_guest_phys( void *buf, paddr_t paddr, int size) { - return __hvm_copy(buf, paddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, paddr, size, HVMCOPY_from_guest | HVMCOPY_fault | HVMCOPY_phys, - 0); + 0)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_copy_to_guest_virt( unsigned long vaddr, void *buf, int size, uint32_t pfec) { - return __hvm_copy(buf, vaddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_to_guest | HVMCOPY_fault | HVMCOPY_virt, - PFEC_page_present | PFEC_write_access | pfec); + PFEC_page_present | PFEC_write_access | pfec)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_copy_from_guest_virt( void *buf, unsigned long vaddr, int size, uint32_t pfec) { - return __hvm_copy(buf, vaddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_from_guest | HVMCOPY_fault | HVMCOPY_virt, - PFEC_page_present | pfec); + PFEC_page_present | pfec)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_fetch_from_guest_virt( void *buf, unsigned long vaddr, int size, uint32_t pfec) { + enum hvm_copy_result res; + struct waitqueue_head wq; if ( hvm_nx_enabled(current) ) pfec |= PFEC_insn_fetch; - return __hvm_copy(buf, vaddr, size, + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_from_guest | HVMCOPY_fault | HVMCOPY_virt, - PFEC_page_present | pfec); + PFEC_page_present | pfec)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_copy_to_guest_virt_nofault( unsigned long vaddr, void *buf, int size, uint32_t pfec) { - return __hvm_copy(buf, vaddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_to_guest | HVMCOPY_no_fault | HVMCOPY_virt, - PFEC_page_present | PFEC_write_access | pfec); + PFEC_page_present | PFEC_write_access | pfec)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_copy_from_guest_virt_nofault( void *buf, unsigned long vaddr, int size, uint32_t pfec) { - return __hvm_copy(buf, vaddr, size, + enum hvm_copy_result res; + struct waitqueue_head wq; + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_from_guest | HVMCOPY_no_fault | HVMCOPY_virt, - PFEC_page_present | pfec); + PFEC_page_present | pfec)) != HVMCOPY_gfn_paged_out); + return res; } enum hvm_copy_result hvm_fetch_from_guest_virt_nofault( void *buf, unsigned long vaddr, int size, uint32_t pfec) { + enum hvm_copy_result res; + struct waitqueue_head wq; if ( hvm_nx_enabled(current) ) pfec |= PFEC_insn_fetch; - return __hvm_copy(buf, vaddr, size, + init_waitqueue_head(&wq); + + wait_event(wq, ( + res = __hvm_copy(buf, vaddr, size, HVMCOPY_from_guest | HVMCOPY_no_fault | HVMCOPY_virt, - PFEC_page_present | pfec); + PFEC_page_present | pfec)) != HVMCOPY_gfn_paged_out); + return res; } unsigned long copy_to_user_hvm(void *to, const void *from, unsigned int len) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |