direct-io.hg
changeset 9796:90813b66c3cf
[IA64] get_pfn_list workaround
As we know, the mechanism for hypervisor to pass parameter through pointer
is not complete. Hypervisor use copy_from/to_user functions to copy parameter
to hypervisor and copy result to user, if there is a tlb miss happening and
hypervisor can't handled this. This hypercall fails, there is no mechanism to
handle this failure, that may cause domain crash. Get_pfn_list hypercall copy
large data from hypervisor to user, it is easy to trigger this issue when
creating VTI-domain.
If fails, Get_pfn_list returns the number of pfn entries, and this patch will
Dummy access parameter memory block to cause this tlb mapping tracked by
Hypervisor, then continue to do get_pfn_list.
It's a workaround before we design a new mechanism of passing parameter thr
pointer.
Signed-off-by: Anthony Xu <anthony.xu@intel.com>
As we know, the mechanism for hypervisor to pass parameter through pointer
is not complete. Hypervisor use copy_from/to_user functions to copy parameter
to hypervisor and copy result to user, if there is a tlb miss happening and
hypervisor can't handled this. This hypercall fails, there is no mechanism to
handle this failure, that may cause domain crash. Get_pfn_list hypercall copy
large data from hypervisor to user, it is easy to trigger this issue when
creating VTI-domain.
If fails, Get_pfn_list returns the number of pfn entries, and this patch will
Dummy access parameter memory block to cause this tlb mapping tracked by
Hypervisor, then continue to do get_pfn_list.
It's a workaround before we design a new mechanism of passing parameter thr
pointer.
Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author | awilliam@xenbuild.aw |
---|---|
date | Mon Apr 10 15:13:42 2006 -0600 (2006-04-10) |
parents | 0a7e619a248f |
children | 67b24fc635ae |
files | tools/libxc/xc_ia64_stubs.c |
line diff
1.1 --- a/tools/libxc/xc_ia64_stubs.c Mon Apr 10 14:54:35 2006 -0600 1.2 +++ b/tools/libxc/xc_ia64_stubs.c Mon Apr 10 15:13:42 2006 -0600 1.3 @@ -48,6 +48,12 @@ xc_plan9_build(int xc_handle, 1.4 PERROR("xc_plan9_build not implemented\n"); 1.5 return -1; 1.6 } 1.7 +/* 1.8 + VMM uses put_user to copy pfn_list to guest buffer, this maybe fail, 1.9 + VMM don't handle this now. 1.10 + This method will touch guest buffer to make sure the buffer's mapping 1.11 + is tracked by VMM, 1.12 + */ 1.13 1.14 int xc_ia64_get_pfn_list(int xc_handle, 1.15 uint32_t domid, 1.16 @@ -56,27 +62,48 @@ int xc_ia64_get_pfn_list(int xc_handle, 1.17 unsigned int nr_pages) 1.18 { 1.19 dom0_op_t op; 1.20 - int ret; 1.21 - unsigned long max_pfns = ((unsigned long)start_page << 32) | nr_pages; 1.22 - 1.23 - op.cmd = DOM0_GETMEMLIST; 1.24 - op.u.getmemlist.domain = (domid_t)domid; 1.25 - op.u.getmemlist.max_pfns = max_pfns; 1.26 - op.u.getmemlist.buffer = pfn_buf; 1.27 + int num_pfns,ret; 1.28 + unsigned int __start_page, __nr_pages; 1.29 + unsigned long max_pfns; 1.30 + unsigned long *__pfn_buf; 1.31 + __start_page = start_page; 1.32 + __nr_pages = nr_pages; 1.33 + __pfn_buf = pfn_buf; 1.34 + 1.35 + while(__nr_pages){ 1.36 + max_pfns = ((unsigned long)__start_page << 32) | __nr_pages; 1.37 + op.cmd = DOM0_GETMEMLIST; 1.38 + op.u.getmemlist.domain = (domid_t)domid; 1.39 + op.u.getmemlist.max_pfns = max_pfns; 1.40 + op.u.getmemlist.buffer = __pfn_buf; 1.41 1.42 - if ( (max_pfns != -1UL) 1.43 - && mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) 1.44 - { 1.45 - PERROR("Could not lock pfn list buffer"); 1.46 - return -1; 1.47 - } 1.48 + if ( (max_pfns != -1UL) 1.49 + && mlock(__pfn_buf, __nr_pages * sizeof(unsigned long)) != 0 ) 1.50 + { 1.51 + PERROR("Could not lock pfn list buffer"); 1.52 + return -1; 1.53 + } 1.54 + 1.55 + ret = do_dom0_op(xc_handle, &op); 1.56 + 1.57 + if (max_pfns != -1UL) 1.58 + (void)munlock(__pfn_buf, __nr_pages * sizeof(unsigned long)); 1.59 1.60 - ret = do_dom0_op(xc_handle, &op); 1.61 + if (max_pfns == -1UL) 1.62 + return 0; 1.63 + 1.64 + num_pfns = op.u.getmemlist.num_pfns; 1.65 + __start_page += num_pfns; 1.66 + __nr_pages -= num_pfns; 1.67 + __pfn_buf += num_pfns; 1.68 1.69 - if (max_pfns != -1UL) 1.70 - (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); 1.71 - 1.72 - return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; 1.73 + if (ret < 0) 1.74 + // dummy write to make sure this tlb mapping is tracked by VMM 1.75 + *__pfn_buf = 0; 1.76 + else 1.77 + return nr_pages; 1.78 + } 1.79 + return nr_pages; 1.80 } 1.81 1.82 long xc_get_max_pages(int xc_handle, uint32_t domid)