diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-07-20 10:58:06 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-07-20 10:58:06 +0100 |
commit | 07a34def028cf0737533b834a0e29f0ce639d9ea (patch) | |
tree | a700f2b72fdb665876369567b2140b823ee934db /tools/libxc/xc_linux.c | |
parent | 787d3b69de1e4619caafc2ff9884b47746eaa91f (diff) | |
download | xen-07a34def028cf0737533b834a0e29f0ce639d9ea.tar.gz xen-07a34def028cf0737533b834a0e29f0ce639d9ea.tar.bz2 xen-07a34def028cf0737533b834a0e29f0ce639d9ea.zip |
libxc: Use a single mmap interface to Linux
Modify xc_map_foreign_range and xc_map_foreign_ranges to call
mmap_map_foreign_batch. This eliminates the need for multiple privcmd
mmap ioctls. Now only IOCTL_PRIVCMD_MMAPBATCH is required.
Signed-off-by: Patrick Colp <Patrick.Colp@citrix.com>
Diffstat (limited to 'tools/libxc/xc_linux.c')
-rw-r--r-- | tools/libxc/xc_linux.c | 71 |
1 files changed, 21 insertions, 50 deletions
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c index 2004106b15..45f8ecfccb 100644 --- a/tools/libxc/xc_linux.c +++ b/tools/libxc/xc_linux.c @@ -92,67 +92,38 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot, unsigned long mfn) { - privcmd_mmap_t ioctlx; - privcmd_mmap_entry_t entry; - void *addr; - addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0); - if ( addr == MAP_FAILED ) { - perror("xc_map_foreign_range: mmap failed"); - return NULL; - } + xen_pfn_t *arr; + int num; + int i; - ioctlx.num=1; - ioctlx.dom=dom; - ioctlx.entry=&entry; - entry.va=(unsigned long) addr; - entry.mfn=mfn; - entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT; - if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 ) - { - int saved_errno = errno; - perror("xc_map_foreign_range: ioctl failed"); - (void)munmap(addr, size); - errno = saved_errno; - return NULL; - } - return addr; + num = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + arr = calloc(num, sizeof(xen_pfn_t)); + + for ( i = 0; i < num; i++ ) + arr[i] = mfn + i; + + return xc_map_foreign_batch(xc_handle, dom, prot, arr, num); } void *xc_map_foreign_ranges(int xc_handle, uint32_t dom, size_t size, int prot, size_t chunksize, privcmd_mmap_entry_t entries[], int nentries) { - privcmd_mmap_t ioctlx; - int i, rc; - void *addr; + xen_pfn_t *arr; + int num_per_entry; + int num; + int i; + int j; - addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0); - if ( addr == MAP_FAILED ) - goto mmap_failed; + num_per_entry = chunksize >> PAGE_SHIFT; + num = num_per_entry * nentries; + arr = calloc(num, sizeof(xen_pfn_t)); for ( i = 0; i < nentries; i++ ) - { - entries[i].va = (unsigned long)addr + (i * chunksize); - entries[i].npages = chunksize >> PAGE_SHIFT; - } - - ioctlx.num = nentries; - ioctlx.dom = dom; - ioctlx.entry = entries; - - rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx); - if ( rc ) - goto ioctl_failed; - - return addr; - -ioctl_failed: - rc = munmap(addr, size); - if ( rc == -1 ) - ERROR("%s: error in error path\n", __FUNCTION__); + for ( j = 0; j < num_per_entry; j++ ) + arr[i * num_per_entry + j] = entries[i].mfn + j; -mmap_failed: - return NULL; + return xc_map_foreign_batch(xc_handle, dom, prot, arr, num); } static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data) |