[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH XEN v2 13/15] tools: Implement xc_map_foreign_range(s) in terms of common helper
Both Linux and FreeBSD already implemented these functions using identical helpers based on xc_map_foreign_pages. Make one copy of these common helpers and switch all OSes to use them, even those which previously had a specific lower level implementation of this functionality. This is makes two fewer low level interfaces to think about. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- docs/misc/toolstack-library-abis.pandoc | 35 +++++------------ tools/libxc/xc_foreign_memory.c | 50 +++++++++++++++++++++++ tools/libxc/xc_freebsd_osdep.c | 50 ----------------------- tools/libxc/xc_linux_osdep.c | 49 ----------------------- tools/libxc/xc_minios.c | 43 -------------------- tools/libxc/xc_netbsd.c | 70 --------------------------------- tools/libxc/xc_solaris.c | 67 ------------------------------- 7 files changed, 60 insertions(+), 304 deletions(-) diff --git a/docs/misc/toolstack-library-abis.pandoc b/docs/misc/toolstack-library-abis.pandoc index 4ad6c7d..35674cc 100644 --- a/docs/misc/toolstack-library-abis.pandoc +++ b/docs/misc/toolstack-library-abis.pandoc @@ -876,36 +876,25 @@ functionality areas: # Foreign memory mapping functions -The `xc_map_foreign_*` functions are a bit of a twisty maze. +The `xc_map_foreign_*` functions were once a bit of a twisty maze, but +now all are implemented in terms of a single underlying per-OS +function. osdep level interfaces: Interface Linux Minios Netbsd Freebsd Solaris -------------------- ----- ------ ------ ------- ------- `map_foreign_bulk` Y Y compat Y compat -`map_foreign_range` Y Y Y Y Y -`map_foreign_ranges` Y Y Y Y Y -_compat_ means using `xc_map_foreign_bulk_compat` - -`xc_map_foreign_pages` is common and implemented using -`xc_map_foreign_bulk`. - -Some osdep call other `xc_map_foreign_*` recursivley: - -Interface Linux FreeBSD --------------------- ---------------------------- ------------------------- -`map_foreign_bulk` `IOCTL_PRIVCMD_MMAPBATCH_V2` `IOCTL_PRIVCMD_MMAPBATCH` -`map_foreign_range` `xc_map_foreign_pages` `xc_map_foreign_pages` -`map_foreign_ranges` `xc_map_foreign_pages` `xc_map_foreign_pages` +_compat_ means using `osdep_map_foreign_batch` layer libxenctrl level interfaces: Interface Underlying interface ---------------------- --------------------------- `xc_map_foreign_pages` `xc_map_foreign_bulk` -`xc_map_foreign_range` `osdep: map_foreign_range` -`xc_map_foreign_ranges` `osdep: map_foreign_ranges` +`xc_map_foreign_range` `xc_map_foreign_pages` +`xc_map_foreign_ranges` `xc_map_foreign_pages` `xc_map_foreign_bulk` `osdep: map_foreign_bulk` `osdep: *` have been collapsed since osdep layer was removed. @@ -915,17 +904,13 @@ which have not implemented their own version. It used to use `xc_map_foreign_batch` which is now an osdep for those OSes which need it. -Interface Internal users External users ----------------------- -------------- -------------- +Interface In-tree users External users +---------------------- ------------- -------------- `xc_map_foreign_pages` xenpaging qemu-pv `xc_map_foreign_range` xenconsole, kdd, libxl, qemu-dm, qemu-pv mfndump, memshrtool, xenmon, xenstored, xentrace -`xc_map_foreign_ranges` NONE +`xc_map_foreign_ranges` libxc internal `xc_map_foreign_bulk` used recursively qemu-dm -Only one interface should become a stable API. Something based on -`xc_map_foreign_bulk` seems most appropriate (it is used by -`xc_map_foreign_pages` as well as by xc_map_foreign_range` and -`xc_map_foreign_ranges` on Linux + FreeBSD. A compat version exists in -terms of `xc_map_foreign_batch` for other OSes. +`xc_map_foreign_bulk` should become an underlying stable API. diff --git a/tools/libxc/xc_foreign_memory.c b/tools/libxc/xc_foreign_memory.c index ae133a1..c96489d 100644 --- a/tools/libxc/xc_foreign_memory.c +++ b/tools/libxc/xc_foreign_memory.c @@ -51,6 +51,56 @@ void *xc_map_foreign_pages(xc_interface *xch, uint32_t dom, int prot, return res; } +void *xc_map_foreign_range(xc_interface *xch, + uint32_t dom, int size, int prot, + unsigned long mfn) +{ + xen_pfn_t *arr; + int num; + int i; + void *ret; + + num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT; + arr = calloc(num, sizeof(xen_pfn_t)); + if ( arr == NULL ) + return NULL; + + for ( i = 0; i < num; i++ ) + arr[i] = mfn + i; + + ret = xc_map_foreign_pages(xch, dom, prot, arr, num); + free(arr); + return ret; +} + +void *xc_map_foreign_ranges(xc_interface *xch, + uint32_t dom, size_t size, + int prot, size_t chunksize, + privcmd_mmap_entry_t entries[], + int nentries) +{ + xen_pfn_t *arr; + int num_per_entry; + int num; + int i; + int j; + void *ret; + + num_per_entry = chunksize >> XC_PAGE_SHIFT; + num = num_per_entry * nentries; + arr = calloc(num, sizeof(xen_pfn_t)); + if ( arr == NULL ) + return NULL; + + for ( i = 0; i < nentries; i++ ) + for ( j = 0; j < num_per_entry; j++ ) + arr[i * num_per_entry + j] = entries[i].mfn + j; + + ret = xc_map_foreign_pages(xch, dom, prot, arr, num); + free(arr); + return ret; +} + /* * stub for all not yet converted OSes (NetBSD and Solaris). New OSes should * just implement xc_map_foreign_bulk. diff --git a/tools/libxc/xc_freebsd_osdep.c b/tools/libxc/xc_freebsd_osdep.c index b0ec965..d09e0da 100644 --- a/tools/libxc/xc_freebsd_osdep.c +++ b/tools/libxc/xc_freebsd_osdep.c @@ -126,56 +126,6 @@ void *xc_map_foreign_bulk(xc_interface *xch, return addr; } -void *xc_map_foreign_range(xc_interface *xch, - uint32_t dom, int size, int prot, - unsigned long mfn) -{ - xen_pfn_t *arr; - int num; - int i; - void *ret; - - num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT; - arr = calloc(num, sizeof(xen_pfn_t)); - if ( arr == NULL ) - return NULL; - - for ( i = 0; i < num; i++ ) - arr[i] = mfn + i; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - -void *xc_map_foreign_ranges(xc_interface *xch, - uint32_t dom, size_t size, - int prot, size_t chunksize, - privcmd_mmap_entry_t entries[], - int nentries) -{ - xen_pfn_t *arr; - int num_per_entry; - int num; - int i; - int j; - void *ret; - - num_per_entry = chunksize >> XC_PAGE_SHIFT; - num = num_per_entry * nentries; - arr = calloc(num, sizeof(xen_pfn_t)); - if ( arr == NULL ) - return NULL; - - for ( i = 0; i < nentries; i++ ) - for ( j = 0; j < num_per_entry; j++ ) - arr[i * num_per_entry + j] = entries[i].mfn + j; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - /* * Local variables: * mode: C diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c index 6641bd1..9f8805a 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -285,55 +285,6 @@ void *xc_map_foreign_bulk(xc_interface *xch, return addr; } -void *xc_map_foreign_range(xc_interface *xch, - uint32_t dom, int size, int prot, - unsigned long mfn) -{ - xen_pfn_t *arr; - int num; - int i; - void *ret; - - num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT; - arr = calloc(num, sizeof(xen_pfn_t)); - if ( arr == NULL ) - return NULL; - - for ( i = 0; i < num; i++ ) - arr[i] = mfn + i; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - -void *xc_map_foreign_ranges(xc_interface *xch, - uint32_t dom, size_t size, int prot, - size_t chunksize, privcmd_mmap_entry_t entries[], - int nentries) -{ - xen_pfn_t *arr; - int num_per_entry; - int num; - int i; - int j; - void *ret; - - num_per_entry = chunksize >> XC_PAGE_SHIFT; - num = num_per_entry * nentries; - arr = calloc(num, sizeof(xen_pfn_t)); - if ( arr == NULL ) - return NULL; - - for ( i = 0; i < nentries; i++ ) - for ( j = 0; j < num_per_entry; j++ ) - arr[i * num_per_entry + j] = entries[i].mfn + j; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - /* * Local variables: * mode: C diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index ed20652..1616c58 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -74,49 +74,6 @@ void *xc_map_foreign_bulk(xc_interface *xch, return map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot); } -void *xc_map_foreign_range(xc_interface *xch, - uint32_t dom, - int size, int prot, - unsigned long mfn) -{ - unsigned long pt_prot = 0; - - if (prot & PROT_READ) - pt_prot = L1_PROT_RO; - if (prot & PROT_WRITE) - pt_prot = L1_PROT; - - assert(!(size % getpagesize())); - return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, NULL, pt_prot); -} - -void *xc_map_foreign_ranges(xc_interface *xch, - uint32_t dom, - size_t size, int prot, size_t chunksize, - privcmd_mmap_entry_t entries[], int nentries) -{ - unsigned long *mfns; - int i, j, n; - unsigned long pt_prot = 0; - void *ret; - - if (prot & PROT_READ) - pt_prot = L1_PROT_RO; - if (prot & PROT_WRITE) - pt_prot = L1_PROT; - - mfns = malloc((size / XC_PAGE_SIZE) * sizeof(*mfns)); - - n = 0; - for (i = 0; i < nentries; i++) - for (j = 0; j < chunksize / XC_PAGE_SIZE; j++) - mfns[n++] = entries[i].mfn + j; - - ret = map_frames_ex(mfns, n, 1, 0, 1, dom, NULL, pt_prot); - free(mfns); - return ret; -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c index f02015c..2654d18 100644 --- a/tools/libxc/xc_netbsd.c +++ b/tools/libxc/xc_netbsd.c @@ -97,76 +97,6 @@ void *osdep_map_foreign_batch(xc_interface *xch, } -void *xc_map_foreign_range(xc_interface *xch, - uint32_t dom, - int size, int prot, - unsigned long mfn) -{ - int fd = xch->privcmdfd; - privcmd_mmap_t ioctlx; - privcmd_mmap_entry_t entry; - void *addr; - addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0); - if ( addr == MAP_FAILED ) { - PERROR("xc_map_foreign_range: mmap failed"); - return NULL; - } - - ioctlx.num=1; - ioctlx.dom=dom; - ioctlx.entry=&entry; - entry.va=(unsigned long) addr; - entry.mfn=mfn; - entry.npages=(size+XC_PAGE_SIZE-1)>>XC_PAGE_SHIFT; - if ( ioctl(fd, 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; -} - -void *xc_map_foreign_ranges(xc_interface *xch, - uint32_t dom, - size_t size, int prot, size_t chunksize, - privcmd_mmap_entry_t entries[], int nentries) -{ - int fd = xch->privcmdfd; - privcmd_mmap_t ioctlx; - int i, rc; - void *addr; - - addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0); - if (addr == MAP_FAILED) - goto mmap_failed; - - for (i = 0; i < nentries; i++) { - entries[i].va = (uintptr_t)addr + (i * chunksize); - entries[i].npages = chunksize >> XC_PAGE_SHIFT; - } - - ioctlx.num = nentries; - ioctlx.dom = dom; - ioctlx.entry = entries; - - rc = ioctl(fd, 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__); - -mmap_failed: - return NULL; -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c index 0a0fd14..e1e126d 100644 --- a/tools/libxc/xc_solaris.c +++ b/tools/libxc/xc_solaris.c @@ -95,73 +95,6 @@ void *osdep_map_foreign_batch(xc_interface *xch, } -void *xc_map_foreign_range(xc_interface *xch, - uint32_t dom, - int size, int prot, - unsigned long mfn) -{ - int fd = xch->privcmdfd; - privcmd_mmap_t ioctlx; - privcmd_mmap_entry_t entry; - void *addr; - addr = mmap(NULL, size, prot, MAP_SHARED, fd, 0); - if ( addr == MAP_FAILED ) - return NULL; - - ioctlx.num=1; - ioctlx.dom=dom; - ioctlx.entry=&entry; - entry.va=(unsigned long) addr; - entry.mfn=mfn; - entry.npages=(size+XC_PAGE_SIZE-1)>>XC_PAGE_SHIFT; - if ( ioctl(fd, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 ) - { - int saved_errno = errno; - (void)munmap(addr, size); - errno = saved_errno; - return NULL; - } - return addr; -} - -void *xc_map_foreign_ranges(xc_interface *xch, - uint32_t dom, - size_t size, int prot, size_t chunksize, - privcmd_mmap_entry_t entries[], int nentries) -{ - int fd = xch->privcmdfd; - privcmd_mmap_t ioctlx; - int i, rc; - void *addr; - - addr = mmap(NULL, size, prot, MAP_SHARED, fd, 0); - if (addr == MAP_FAILED) - goto mmap_failed; - - for (i = 0; i < nentries; i++) { - entries[i].va = (uintptr_t)addr + (i * chunksize); - entries[i].npages = chunksize >> XC_PAGE_SHIFT; - } - - ioctlx.num = nentries; - ioctlx.dom = dom; - ioctlx.entry = entries; - - rc = ioctl(fd, IOCTL_PRIVCMD_MMAP, &ioctlx); - if (rc) - goto ioctl_failed; - - return addr; - -ioctl_failed: - rc = munmap(addr, size); - if (rc == -1) - PERROR("%s: error in error path", __FUNCTION__); - -mmap_failed: - return NULL; -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |