rev |
line source |
mjw@1623
|
1 /******************************************************************************
|
mjw@1623
|
2 * xc_private.c
|
mjw@1623
|
3 *
|
mjw@1623
|
4 * Helper functions for the rest of the library.
|
mjw@1623
|
5 */
|
mjw@1623
|
6
|
mafetter@3434
|
7 #include <zlib.h>
|
mjw@1623
|
8 #include "xc_private.h"
|
kaf24@6468
|
9 #include <xen/memory.h>
|
mjw@1623
|
10
|
iap10@2325
|
11 void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
|
kaf24@1645
|
12 unsigned long *arr, int num )
|
mjw@1623
|
13 {
|
mjw@1623
|
14 privcmd_mmapbatch_t ioctlx;
|
mjw@1623
|
15 void *addr;
|
kaf24@1645
|
16 addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
|
rusty@4866
|
17 if ( addr == MAP_FAILED )
|
rusty@4866
|
18 return NULL;
|
rusty@4866
|
19
|
rusty@4866
|
20 ioctlx.num=num;
|
rusty@4866
|
21 ioctlx.dom=dom;
|
rusty@4866
|
22 ioctlx.addr=(unsigned long)addr;
|
rusty@4866
|
23 ioctlx.arr=arr;
|
rusty@4866
|
24 if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx ) < 0 )
|
mjw@1623
|
25 {
|
kaf24@5543
|
26 int saved_errno = errno;
|
rusty@4866
|
27 perror("XXXXXXXX");
|
kaf24@5543
|
28 (void)munmap(addr, num*PAGE_SIZE);
|
kaf24@5543
|
29 errno = saved_errno;
|
rusty@4866
|
30 return NULL;
|
mjw@1623
|
31 }
|
mjw@1623
|
32 return addr;
|
mjw@1623
|
33
|
mjw@1623
|
34 }
|
mjw@1623
|
35
|
mjw@1623
|
36 /*******************/
|
mjw@1623
|
37
|
iap10@2325
|
38 void *xc_map_foreign_range(int xc_handle, u32 dom,
|
kaf24@1645
|
39 int size, int prot,
|
kaf24@1645
|
40 unsigned long mfn )
|
mjw@1623
|
41 {
|
mjw@1623
|
42 privcmd_mmap_t ioctlx;
|
mjw@1623
|
43 privcmd_mmap_entry_t entry;
|
mjw@1623
|
44 void *addr;
|
kaf24@1645
|
45 addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
|
rusty@4866
|
46 if ( addr == MAP_FAILED )
|
rusty@4866
|
47 return NULL;
|
rusty@4866
|
48
|
rusty@4866
|
49 ioctlx.num=1;
|
rusty@4866
|
50 ioctlx.dom=dom;
|
rusty@4866
|
51 ioctlx.entry=&entry;
|
rusty@4866
|
52 entry.va=(unsigned long) addr;
|
rusty@4866
|
53 entry.mfn=mfn;
|
rusty@4866
|
54 entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
|
rusty@4866
|
55 if ( ioctl( xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx ) < 0 )
|
mjw@1623
|
56 {
|
kaf24@5543
|
57 int saved_errno = errno;
|
kaf24@5543
|
58 (void)munmap(addr, size);
|
kaf24@5543
|
59 errno = saved_errno;
|
rusty@4866
|
60 return NULL;
|
mjw@1623
|
61 }
|
mjw@1623
|
62 return addr;
|
mjw@1623
|
63 }
|
mjw@1623
|
64
|
mjw@1623
|
65 /*******************/
|
mjw@1623
|
66
|
mjw@1623
|
67 /* NB: arr must be mlock'ed */
|
cl349@6389
|
68 int xc_get_pfn_type_batch(int xc_handle,
|
cl349@6389
|
69 u32 dom, int num, unsigned long *arr)
|
mjw@1623
|
70 {
|
mjw@1623
|
71 dom0_op_t op;
|
mjw@1623
|
72 op.cmd = DOM0_GETPAGEFRAMEINFO2;
|
mjw@1623
|
73 op.u.getpageframeinfo2.domain = (domid_t)dom;
|
mjw@1623
|
74 op.u.getpageframeinfo2.num = num;
|
mjw@1623
|
75 op.u.getpageframeinfo2.array = arr;
|
mjw@1623
|
76 return do_dom0_op(xc_handle, &op);
|
mjw@1623
|
77 }
|
mjw@1623
|
78
|
mjw@1623
|
79 #define GETPFN_ERR (~0U)
|
mjw@1623
|
80 unsigned int get_pfn_type(int xc_handle,
|
mjw@1623
|
81 unsigned long mfn,
|
mjw@1623
|
82 u32 dom)
|
mjw@1623
|
83 {
|
mjw@1623
|
84 dom0_op_t op;
|
mjw@1623
|
85 op.cmd = DOM0_GETPAGEFRAMEINFO;
|
mjw@1623
|
86 op.u.getpageframeinfo.pfn = mfn;
|
mjw@1623
|
87 op.u.getpageframeinfo.domain = (domid_t)dom;
|
mjw@1623
|
88 if ( do_dom0_op(xc_handle, &op) < 0 )
|
mjw@1623
|
89 {
|
mjw@1623
|
90 PERROR("Unexpected failure when getting page frame info!");
|
mjw@1623
|
91 return GETPFN_ERR;
|
mjw@1623
|
92 }
|
mjw@1623
|
93 return op.u.getpageframeinfo.type;
|
mjw@1623
|
94 }
|
mjw@1623
|
95
|
cl349@6389
|
96 int xc_mmuext_op(
|
cl349@6389
|
97 int xc_handle,
|
cl349@6389
|
98 struct mmuext_op *op,
|
cl349@6389
|
99 unsigned int nr_ops,
|
cl349@6389
|
100 domid_t dom)
|
cl349@6389
|
101 {
|
cl349@6389
|
102 privcmd_hypercall_t hypercall;
|
cl349@6389
|
103 long ret = -EINVAL;
|
mjw@1623
|
104
|
cl349@6389
|
105 hypercall.op = __HYPERVISOR_mmuext_op;
|
cl349@6389
|
106 hypercall.arg[0] = (unsigned long)op;
|
cl349@6389
|
107 hypercall.arg[1] = (unsigned long)nr_ops;
|
cl349@6389
|
108 hypercall.arg[2] = (unsigned long)0;
|
cl349@6389
|
109 hypercall.arg[3] = (unsigned long)dom;
|
kaf24@4388
|
110
|
cl349@6389
|
111 if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
|
cl349@6389
|
112 {
|
cl349@6389
|
113 PERROR("Could not lock memory for Xen hypercall");
|
cl349@6389
|
114 goto out1;
|
cl349@6389
|
115 }
|
kaf24@4388
|
116
|
cl349@6389
|
117 if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
|
cl349@6389
|
118 {
|
iap10@6680
|
119 fprintf(stderr, "Dom_mmuext operation failed (rc=%ld errno=%d)-- need to"
|
cl349@6389
|
120 " rebuild the user-space tool set?\n",ret,errno);
|
cl349@6389
|
121 }
|
kaf24@4388
|
122
|
cl349@6389
|
123 safe_munlock(op, nr_ops*sizeof(*op));
|
mjw@1623
|
124
|
cl349@6389
|
125 out1:
|
cl349@6389
|
126 return ret;
|
cl349@6389
|
127 }
|
cl349@6389
|
128
|
cl349@6389
|
129 static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu)
|
mjw@1623
|
130 {
|
mjw@1623
|
131 int err = 0;
|
mjw@1623
|
132 privcmd_hypercall_t hypercall;
|
mjw@1623
|
133
|
kaf24@4388
|
134 if ( mmu->idx == 0 )
|
mjw@1623
|
135 return 0;
|
mjw@1623
|
136
|
mjw@1623
|
137 hypercall.op = __HYPERVISOR_mmu_update;
|
mjw@1623
|
138 hypercall.arg[0] = (unsigned long)mmu->updates;
|
mjw@1623
|
139 hypercall.arg[1] = (unsigned long)mmu->idx;
|
mjw@1623
|
140 hypercall.arg[2] = 0;
|
kaf24@4388
|
141 hypercall.arg[3] = mmu->subject;
|
mjw@1623
|
142
|
mjw@1623
|
143 if ( mlock(mmu->updates, sizeof(mmu->updates)) != 0 )
|
mjw@1623
|
144 {
|
cl349@5333
|
145 PERROR("flush_mmu_updates: mmu updates mlock failed");
|
mjw@1623
|
146 err = 1;
|
mjw@1623
|
147 goto out;
|
mjw@1623
|
148 }
|
mjw@1623
|
149
|
mjw@1623
|
150 if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
|
mjw@1623
|
151 {
|
mjw@1623
|
152 ERROR("Failure when submitting mmu updates");
|
mjw@1623
|
153 err = 1;
|
mjw@1623
|
154 }
|
mjw@1623
|
155
|
kaf24@4388
|
156 mmu->idx = 0;
|
kaf24@5543
|
157
|
kaf24@5543
|
158 safe_munlock(mmu->updates, sizeof(mmu->updates));
|
mjw@1623
|
159
|
mjw@1623
|
160 out:
|
mjw@1623
|
161 return err;
|
mjw@1623
|
162 }
|
mjw@1623
|
163
|
cl349@6389
|
164 xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom)
|
mjw@1623
|
165 {
|
cl349@6389
|
166 xc_mmu_t *mmu = malloc(sizeof(xc_mmu_t));
|
mjw@1623
|
167 if ( mmu == NULL )
|
mjw@1623
|
168 return mmu;
|
kaf24@4388
|
169 mmu->idx = 0;
|
mjw@1623
|
170 mmu->subject = dom;
|
mjw@1623
|
171 return mmu;
|
mjw@1623
|
172 }
|
mjw@1623
|
173
|
cl349@6389
|
174 int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu,
|
iap10@6680
|
175 unsigned long long ptr, unsigned long long val)
|
mjw@1623
|
176 {
|
mjw@1623
|
177 mmu->updates[mmu->idx].ptr = ptr;
|
mjw@1623
|
178 mmu->updates[mmu->idx].val = val;
|
mjw@1623
|
179
|
mjw@1623
|
180 if ( ++mmu->idx == MAX_MMU_UPDATES )
|
mjw@1623
|
181 return flush_mmu_updates(xc_handle, mmu);
|
mjw@1623
|
182
|
mjw@1623
|
183 return 0;
|
mjw@1623
|
184 }
|
mjw@1623
|
185
|
cl349@6389
|
186 int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu)
|
mjw@1623
|
187 {
|
mjw@1623
|
188 return flush_mmu_updates(xc_handle, mmu);
|
mjw@1623
|
189 }
|
mjw@1623
|
190
|
kaf24@6468
|
191 int xc_memory_op(int xc_handle,
|
kaf24@6468
|
192 int cmd,
|
kaf24@6468
|
193 void *arg)
|
cl349@6389
|
194 {
|
cl349@6389
|
195 privcmd_hypercall_t hypercall;
|
kaf24@6468
|
196 struct xen_memory_reservation *reservation = arg;
|
cl349@6389
|
197 long ret = -EINVAL;
|
cl349@6389
|
198
|
kaf24@6468
|
199 hypercall.op = __HYPERVISOR_memory_op;
|
kaf24@6468
|
200 hypercall.arg[0] = (unsigned long)cmd;
|
kaf24@6468
|
201 hypercall.arg[1] = (unsigned long)arg;
|
cl349@6389
|
202
|
kaf24@6468
|
203 switch ( cmd )
|
cl349@6389
|
204 {
|
kaf24@6468
|
205 case XENMEM_increase_reservation:
|
kaf24@6468
|
206 case XENMEM_decrease_reservation:
|
kaf24@6468
|
207 if ( mlock(reservation, sizeof(*reservation)) != 0 )
|
kaf24@6468
|
208 {
|
kaf24@6468
|
209 PERROR("Could not mlock");
|
kaf24@6468
|
210 goto out1;
|
kaf24@6468
|
211 }
|
kaf24@6468
|
212 if ( (reservation->extent_start != NULL) &&
|
kaf24@6468
|
213 (mlock(reservation->extent_start,
|
kaf24@6468
|
214 reservation->nr_extents * sizeof(unsigned long)) != 0) )
|
kaf24@6468
|
215 {
|
kaf24@6468
|
216 PERROR("Could not mlock");
|
kaf24@6468
|
217 safe_munlock(reservation, sizeof(*reservation));
|
kaf24@6468
|
218 goto out1;
|
kaf24@6468
|
219 }
|
kaf24@6468
|
220 break;
|
kaf24@6468
|
221 case XENMEM_maximum_ram_page:
|
kaf24@6468
|
222 if ( mlock(arg, sizeof(unsigned long)) != 0 )
|
kaf24@6468
|
223 {
|
kaf24@6468
|
224 PERROR("Could not mlock");
|
kaf24@6468
|
225 goto out1;
|
kaf24@6468
|
226 }
|
kaf24@6468
|
227 break;
|
cl349@6389
|
228 }
|
cl349@6389
|
229
|
cl349@6389
|
230 if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
|
cl349@6389
|
231 {
|
iap10@6680
|
232 fprintf(stderr, "hypercall failed (rc=%ld errno=%d)-- need to"
|
cl349@6389
|
233 " rebuild the user-space tool set?\n",ret,errno);
|
cl349@6389
|
234 }
|
cl349@6389
|
235
|
kaf24@6468
|
236 switch ( cmd )
|
kaf24@6468
|
237 {
|
kaf24@6468
|
238 case XENMEM_increase_reservation:
|
kaf24@6468
|
239 case XENMEM_decrease_reservation:
|
kaf24@6468
|
240 safe_munlock(reservation, sizeof(*reservation));
|
kaf24@6468
|
241 if ( reservation->extent_start != NULL )
|
kaf24@6468
|
242 safe_munlock(reservation->extent_start,
|
kaf24@6468
|
243 reservation->nr_extents * sizeof(unsigned long));
|
kaf24@6468
|
244 break;
|
kaf24@6468
|
245 case XENMEM_maximum_ram_page:
|
kaf24@6468
|
246 safe_munlock(arg, sizeof(unsigned long));
|
kaf24@6468
|
247 break;
|
kaf24@6468
|
248 }
|
cl349@6389
|
249
|
cl349@6389
|
250 out1:
|
cl349@6389
|
251 return ret;
|
cl349@6389
|
252 }
|
cl349@6389
|
253
|
mjw@1623
|
254
|
mafetter@3435
|
255 long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
|
mjw@1623
|
256 {
|
mjw@1623
|
257 dom0_op_t op;
|
mjw@1623
|
258
|
cl349@4849
|
259 op.cmd = DOM0_GETVCPUCONTEXT;
|
cl349@4849
|
260 op.u.getvcpucontext.domain = (domid_t)domid;
|
kaf24@4882
|
261 op.u.getvcpucontext.vcpu = (u16)vcpu;
|
kaf24@4882
|
262 op.u.getvcpucontext.ctxt = NULL;
|
cl349@4849
|
263 if ( (do_dom0_op(xc_handle, &op) < 0) )
|
mjw@1623
|
264 {
|
mjw@1623
|
265 PERROR("Could not get info on domain");
|
mjw@1623
|
266 return -1;
|
mjw@1623
|
267 }
|
cl349@4849
|
268 return op.u.getvcpucontext.cpu_time;
|
mjw@1623
|
269 }
|
mjw@1623
|
270
|
mjw@1623
|
271
|
iap10@2124
|
272 unsigned long xc_get_m2p_start_mfn ( int xc_handle )
|
iap10@2124
|
273 {
|
iap10@2124
|
274 unsigned long mfn;
|
iap10@2124
|
275
|
iap10@2124
|
276 if ( ioctl( xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN, &mfn ) < 0 )
|
iap10@2124
|
277 {
|
iap10@2124
|
278 perror("xc_get_m2p_start_mfn:");
|
iap10@2124
|
279 return 0;
|
iap10@2124
|
280 }
|
iap10@2124
|
281 return mfn;
|
iap10@2124
|
282 }
|
iap10@2124
|
283
|
mafetter@3434
|
284 int xc_get_pfn_list(int xc_handle,
|
mafetter@3434
|
285 u32 domid,
|
mafetter@3434
|
286 unsigned long *pfn_buf,
|
mafetter@3434
|
287 unsigned long max_pfns)
|
mafetter@3434
|
288 {
|
mafetter@3434
|
289 dom0_op_t op;
|
mafetter@3434
|
290 int ret;
|
mafetter@3434
|
291 op.cmd = DOM0_GETMEMLIST;
|
mafetter@3434
|
292 op.u.getmemlist.domain = (domid_t)domid;
|
mafetter@3434
|
293 op.u.getmemlist.max_pfns = max_pfns;
|
mafetter@3434
|
294 op.u.getmemlist.buffer = pfn_buf;
|
iap10@2124
|
295
|
iap10@2124
|
296
|
mafetter@3434
|
297 if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
|
mafetter@3434
|
298 {
|
cl349@5333
|
299 PERROR("xc_get_pfn_list: pfn_buf mlock failed");
|
mafetter@3434
|
300 return -1;
|
mafetter@3434
|
301 }
|
mafetter@3434
|
302
|
mafetter@3434
|
303 ret = do_dom0_op(xc_handle, &op);
|
mafetter@3434
|
304
|
kaf24@5543
|
305 safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
|
mafetter@3434
|
306
|
mafetter@3434
|
307 #if 0
|
mafetter@3434
|
308 #ifdef DEBUG
|
mafetter@3434
|
309 DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret));
|
mafetter@3434
|
310 if (ret >= 0) {
|
mafetter@3434
|
311 int i, j;
|
mafetter@3434
|
312 for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) {
|
mafetter@3434
|
313 fprintf(stderr, "0x%x: ", i);
|
mafetter@3434
|
314 for (j = 0; j < 16; j++)
|
mafetter@3434
|
315 fprintf(stderr, "0x%lx ", pfn_buf[i + j]);
|
mafetter@3434
|
316 fprintf(stderr, "\n");
|
mafetter@3434
|
317 }
|
mafetter@3434
|
318 }
|
mafetter@3434
|
319 #endif
|
mafetter@3434
|
320 #endif
|
mafetter@3434
|
321
|
mafetter@3434
|
322 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
|
mafetter@3434
|
323 }
|
mafetter@3434
|
324
|
kaf24@5914
|
325 #ifdef __ia64__
|
kaf24@5914
|
326 int xc_ia64_get_pfn_list(int xc_handle,
|
kaf24@5914
|
327 u32 domid,
|
kaf24@5914
|
328 unsigned long *pfn_buf,
|
kaf24@5914
|
329 unsigned int start_page,
|
kaf24@5914
|
330 unsigned int nr_pages)
|
kaf24@5914
|
331 {
|
kaf24@5914
|
332 dom0_op_t op;
|
kaf24@5914
|
333 int ret;
|
kaf24@5914
|
334
|
kaf24@5914
|
335 op.cmd = DOM0_GETMEMLIST;
|
kaf24@5914
|
336 op.u.getmemlist.domain = (domid_t)domid;
|
kaf24@5914
|
337 op.u.getmemlist.max_pfns = ((unsigned long)start_page << 32) | nr_pages;
|
kaf24@5914
|
338 op.u.getmemlist.buffer = pfn_buf;
|
kaf24@5914
|
339
|
kaf24@5914
|
340 if ( mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 )
|
kaf24@5914
|
341 {
|
kaf24@5914
|
342 PERROR("Could not lock pfn list buffer");
|
kaf24@5914
|
343 return -1;
|
kaf24@5914
|
344 }
|
kaf24@5914
|
345
|
kaf24@5914
|
346 /* XXX Hack to put pages in TLB, hypervisor should be able to handle this */
|
kaf24@5914
|
347 memset(pfn_buf, 0, nr_pages * sizeof(unsigned long));
|
kaf24@5914
|
348 ret = do_dom0_op(xc_handle, &op);
|
kaf24@5914
|
349
|
kaf24@5914
|
350 (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long));
|
kaf24@5914
|
351
|
kaf24@5914
|
352 return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
|
kaf24@5914
|
353 }
|
kaf24@5914
|
354 #endif
|
kaf24@5914
|
355
|
mafetter@3434
|
356 long xc_get_tot_pages(int xc_handle, u32 domid)
|
mafetter@3434
|
357 {
|
mafetter@3434
|
358 dom0_op_t op;
|
mafetter@3434
|
359 op.cmd = DOM0_GETDOMAININFO;
|
mafetter@3434
|
360 op.u.getdomaininfo.domain = (domid_t)domid;
|
mafetter@3434
|
361 return (do_dom0_op(xc_handle, &op) < 0) ?
|
mafetter@3434
|
362 -1 : op.u.getdomaininfo.tot_pages;
|
mafetter@3434
|
363 }
|
mafetter@3434
|
364
|
mafetter@3434
|
365 int xc_copy_to_domain_page(int xc_handle,
|
mafetter@3434
|
366 u32 domid,
|
mafetter@3434
|
367 unsigned long dst_pfn,
|
mafetter@3434
|
368 void *src_page)
|
mafetter@3434
|
369 {
|
mafetter@3434
|
370 void *vaddr = xc_map_foreign_range(
|
mafetter@3434
|
371 xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
|
mafetter@3434
|
372 if ( vaddr == NULL )
|
mafetter@3434
|
373 return -1;
|
mafetter@3434
|
374 memcpy(vaddr, src_page, PAGE_SIZE);
|
mafetter@3434
|
375 munmap(vaddr, PAGE_SIZE);
|
mafetter@3434
|
376 return 0;
|
mafetter@3434
|
377 }
|
mafetter@3434
|
378
|
mafetter@3434
|
379 unsigned long xc_get_filesz(int fd)
|
mafetter@3434
|
380 {
|
mafetter@3434
|
381 u16 sig;
|
mafetter@3434
|
382 u32 _sz = 0;
|
mafetter@3434
|
383 unsigned long sz;
|
mafetter@3434
|
384
|
mafetter@3434
|
385 lseek(fd, 0, SEEK_SET);
|
kaf24@3876
|
386 if ( read(fd, &sig, sizeof(sig)) != sizeof(sig) )
|
kaf24@3876
|
387 return 0;
|
mafetter@3434
|
388 sz = lseek(fd, 0, SEEK_END);
|
mafetter@3434
|
389 if ( sig == 0x8b1f ) /* GZIP signature? */
|
mafetter@3434
|
390 {
|
mafetter@3434
|
391 lseek(fd, -4, SEEK_END);
|
kaf24@3876
|
392 if ( read(fd, &_sz, 4) != 4 )
|
kaf24@3876
|
393 return 0;
|
mafetter@3434
|
394 sz = _sz;
|
mafetter@3434
|
395 }
|
mafetter@3434
|
396 lseek(fd, 0, SEEK_SET);
|
mafetter@3434
|
397
|
mafetter@3434
|
398 return sz;
|
mafetter@3434
|
399 }
|
mafetter@3434
|
400
|
mafetter@3434
|
401 void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
|
mafetter@3434
|
402 int xch, u32 dom, unsigned long *parray,
|
mafetter@3434
|
403 unsigned long vstart)
|
mafetter@3434
|
404 {
|
mafetter@3434
|
405 char *va;
|
mafetter@3434
|
406 unsigned long chunksz, done, pa;
|
mafetter@3434
|
407
|
mafetter@3434
|
408 for ( done = 0; done < size; done += chunksz )
|
mafetter@3434
|
409 {
|
mafetter@3434
|
410 pa = dst + done - vstart;
|
mafetter@3434
|
411 va = xc_map_foreign_range(
|
mafetter@3434
|
412 xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
|
mafetter@3434
|
413 chunksz = size - done;
|
mafetter@3434
|
414 if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
|
mafetter@3434
|
415 chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
|
mafetter@3434
|
416 memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
|
mafetter@3434
|
417 munmap(va, PAGE_SIZE);
|
mafetter@3434
|
418 }
|
mafetter@3434
|
419 }
|
kaf24@5318
|
420
|
kaf24@5318
|
421 int xc_dom0_op(int xc_handle, dom0_op_t *op)
|
kaf24@5318
|
422 {
|
kaf24@5318
|
423 return do_dom0_op(xc_handle, op);
|
kaf24@5318
|
424 }
|
vh249@6549
|
425
|
vh249@6549
|
426 int xc_version(int xc_handle, int cmd, void *arg)
|
vh249@6549
|
427 {
|
kaf24@6733
|
428 int rc, argsize = 0;
|
kaf24@6733
|
429
|
kaf24@6733
|
430 switch ( cmd )
|
kaf24@6733
|
431 {
|
kaf24@6733
|
432 case XENVER_extraversion: argsize = sizeof(xen_extraversion_t); break;
|
kaf24@6733
|
433 case XENVER_compile_info: argsize = sizeof(xen_compile_info_t); break;
|
kaf24@6733
|
434 case XENVER_capabilities: argsize = sizeof(xen_capabilities_info_t); break;
|
kaf24@6733
|
435 case XENVER_changeset: argsize = sizeof(xen_changeset_info_t); break;
|
kaf24@6733
|
436 case XENVER_parameters: argsize = sizeof(xen_parameters_info_t); break;
|
kaf24@6733
|
437 }
|
kaf24@6733
|
438
|
kaf24@6733
|
439 if ( (argsize != 0) && (mlock(arg, argsize) != 0) )
|
kaf24@6733
|
440 {
|
kaf24@6733
|
441 PERROR("Could not lock memory for version hypercall");
|
kaf24@6733
|
442 return -ENOMEM;
|
kaf24@6733
|
443 }
|
kaf24@6733
|
444
|
kaf24@6733
|
445 rc = do_xen_version(xc_handle, cmd, arg);
|
kaf24@6733
|
446
|
kaf24@6733
|
447 if ( argsize != 0 )
|
kaf24@6733
|
448 safe_munlock(arg, argsize);
|
kaf24@6733
|
449
|
kaf24@6733
|
450 return rc;
|
vh249@6549
|
451 }
|
iap10@6688
|
452
|
kaf24@6733
|
453 unsigned long xc_make_page_below_4G(
|
kaf24@6733
|
454 int xc_handle, u32 domid, unsigned long mfn)
|
iap10@6688
|
455 {
|
iap10@6688
|
456 unsigned long new_mfn;
|
kaf24@6733
|
457
|
iap10@6688
|
458 if ( xc_domain_memory_decrease_reservation(
|
kaf24@6733
|
459 xc_handle, domid, 1, 0, &mfn) != 1 )
|
iap10@6688
|
460 {
|
iap10@6688
|
461 fprintf(stderr,"xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
|
iap10@6688
|
462 return 0;
|
iap10@6688
|
463 }
|
kaf24@6733
|
464
|
kaf24@6733
|
465 if ( xc_domain_memory_increase_reservation(
|
kaf24@6733
|
466 xc_handle, domid, 1, 0, 32, &new_mfn) != 1 )
|
iap10@6688
|
467 {
|
iap10@6688
|
468 fprintf(stderr,"xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
|
iap10@6688
|
469 return 0;
|
iap10@6688
|
470 }
|
kaf24@6733
|
471
|
iap10@6688
|
472 return new_mfn;
|
iap10@6688
|
473 }
|