xen-vtx-unstable
annotate tools/libxc/xc_private.c @ 6796:0d8c0db04258
Don't return failure when trying to delete a non-existent node.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Tue Sep 13 21:52:24 2005 +0000 (2005-09-13) |
parents | 72e4e2aab342 |
children |
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 } |