diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-07-23 16:39:46 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-07-23 16:39:46 +0100 |
commit | ce29ad450cc37e90052059118c075f80f79c9838 (patch) | |
tree | 944bbb8f868a5cf632d14cfcc1280233cf2b33e5 | |
parent | 6de959a1f6dd5ef22036f1a1d74cdcfce25d327c (diff) | |
download | xen-ce29ad450cc37e90052059118c075f80f79c9838.tar.gz xen-ce29ad450cc37e90052059118c075f80f79c9838.tar.bz2 xen-ce29ad450cc37e90052059118c075f80f79c9838.zip |
libxc: Clean up xc_map_foreign_ranges() interface to hide the
underlying mmap() invocation.
From: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | tools/libxc/xc_dom_boot.c | 28 | ||||
-rw-r--r-- | tools/libxc/xc_domain_save.c | 42 | ||||
-rw-r--r-- | tools/libxc/xc_hvm_build.c | 24 | ||||
-rw-r--r-- | tools/libxc/xc_linux.c | 33 | ||||
-rw-r--r-- | tools/libxc/xc_minios.c | 11 | ||||
-rw-r--r-- | tools/libxc/xc_netbsd.c | 45 | ||||
-rw-r--r-- | tools/libxc/xc_private.h | 5 | ||||
-rw-r--r-- | tools/libxc/xc_solaris.c | 31 |
8 files changed, 136 insertions, 83 deletions
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c index 30906ee993..7f37321ef7 100644 --- a/tools/libxc/xc_dom_boot.c +++ b/tools/libxc/xc_dom_boot.c @@ -153,7 +153,7 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, int page_shift = XC_DOM_PAGE_SHIFT(dom); privcmd_mmap_entry_t *entries; void *ptr; - int i, rc; + int i; int err; entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t)); @@ -165,9 +165,13 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, return NULL; } - ptr = mmap(NULL, count << page_shift, PROT_READ | PROT_WRITE, - MAP_SHARED, dom->guest_xc, 0); - if ( ptr == MAP_FAILED ) + for ( i = 0; i < count; i++ ) + entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); + + ptr = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, + count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift, + entries, count); + if ( ptr == NULL ) { err = errno; xc_dom_panic(XC_INTERNAL_ERROR, @@ -177,22 +181,6 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn, return NULL; } - for ( i = 0; i < count; i++ ) - { - entries[i].va = (uintptr_t) ptr + (i << page_shift); - entries[i].mfn = xc_dom_p2m_host(dom, pfn + i); - entries[i].npages = 1; - } - - rc = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid, - entries, count); - if ( rc < 0 ) - { - xc_dom_panic(XC_INTERNAL_ERROR, - "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn - " [xenctl, rc=%d]\n", __FUNCTION__, pfn, count, rc); - return NULL; - } return ptr; } diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index 8a16b928bc..687e0d84fa 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -568,16 +568,19 @@ static xen_pfn_t *xc_map_m2p(int xc_handle, unsigned long m2p_chunks, m2p_size; xen_pfn_t *m2p; xen_pfn_t *extent_start; - int i, rc; + int i; + m2p = NULL; m2p_size = M2P_SIZE(max_mfn); m2p_chunks = M2P_CHUNKS(max_mfn); xmml.max_extents = m2p_chunks; - if ( !(extent_start = malloc(m2p_chunks * sizeof(xen_pfn_t))) ) + + extent_start = calloc(m2p_chunks, sizeof(xen_pfn_t)); + if ( !extent_start ) { ERROR("failed to allocate space for m2p mfns"); - return NULL; + goto err0; } set_xen_guest_handle(xmml.extent_start, extent_start); @@ -585,41 +588,36 @@ static xen_pfn_t *xc_map_m2p(int xc_handle, (xmml.nr_extents != m2p_chunks) ) { ERROR("xc_get_m2p_mfns"); - return NULL; - } - - if ( (m2p = mmap(NULL, m2p_size, prot, - MAP_SHARED, xc_handle, 0)) == MAP_FAILED ) - { - ERROR("failed to mmap m2p"); - return NULL; + goto err1; } - if ( !(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t))) ) + entries = calloc(m2p_chunks, sizeof(privcmd_mmap_entry_t)); + if (entries == NULL) { ERROR("failed to allocate space for mmap entries"); - return NULL; + goto err1; } for ( i = 0; i < m2p_chunks; i++ ) - { - entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE)); entries[i].mfn = extent_start[i]; - entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT; - } - if ( (rc = xc_map_foreign_ranges(xc_handle, DOMID_XEN, - entries, m2p_chunks)) < 0 ) + m2p = xc_map_foreign_ranges(xc_handle, DOMID_XEN, + m2p_size, prot, M2P_CHUNK_SIZE, + entries, m2p_chunks); + if (m2p == NULL) { - ERROR("xc_mmap_foreign_ranges failed (rc = %d)", rc); - return NULL; + ERROR("xc_mmap_foreign_ranges failed"); + goto err2; } m2p_mfn0 = entries[0].mfn; - free(extent_start); +err2: free(entries); +err1: + free(extent_start); +err0: return m2p; } diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 8bf5549188..f442a791f8 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -115,27 +115,21 @@ static int loadelfimage( struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray) { privcmd_mmap_entry_t *entries = NULL; - int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT; + size_t pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT; int i, rc = -1; /* Map address space for initial elf image. */ - entries = malloc(pages * sizeof(privcmd_mmap_entry_t)); + entries = calloc(pages, sizeof(privcmd_mmap_entry_t)); if ( entries == NULL ) goto err; - elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, - MAP_SHARED, xch, 0); - if ( elf->dest == MAP_FAILED ) - goto err; for ( i = 0; i < pages; i++ ) - { - entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT); entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i]; - entries[i].npages = 1; - } - rc = xc_map_foreign_ranges(xch, dom, entries, pages); - if ( rc < 0 ) + elf->dest = xc_map_foreign_ranges(xch, dom, pages << PAGE_SHIFT, + PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT, + entries, pages); + if (elf->dest == NULL) goto err; /* Load the initial elf image. */ @@ -143,12 +137,6 @@ static int loadelfimage( rc = 0; err: - if ( elf->dest ) - { - munmap(elf->dest, pages << PAGE_SHIFT); - elf->dest = NULL; - } - if ( entries ) free(entries); diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c index d407299ff8..6df3e9957d 100644 --- a/tools/libxc/xc_linux.c +++ b/tools/libxc/xc_linux.c @@ -118,16 +118,41 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, return addr; } -int xc_map_foreign_ranges(int xc_handle, uint32_t dom, - privcmd_mmap_entry_t *entries, int nr) +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; - ioctlx.num = nr; + int i, rc; + void *addr; + + addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 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 >> PAGE_SHIFT; + } + + ioctlx.num = nentries; ioctlx.dom = dom; ioctlx.entry = entries; - return ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx); + 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__); + +mmap_failed: + return NULL; } static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data) diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index c57b7a5b7d..89ab9ad44d 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -76,6 +76,16 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot); } +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) +{ + ERROR("%s: implement me\n"); + return NULL; +} + + +#if 0 int xc_map_foreign_ranges(int xc_handle, uint32_t dom, privcmd_mmap_entry_t *entries, int nr) { @@ -86,6 +96,7 @@ int xc_map_foreign_ranges(int xc_handle, uint32_t dom, } return 0; } +#endif int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall) { diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c index 036f64879c..aab325f68a 100644 --- a/tools/libxc/xc_netbsd.c +++ b/tools/libxc/xc_netbsd.c @@ -11,7 +11,6 @@ #include "xc_private.h" -#include <xen/memory.h> #include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> @@ -114,23 +113,43 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, return addr; } -int xc_map_foreign_ranges(int xc_handle, uint32_t dom, - privcmd_mmap_entry_t *entries, int nr) +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 err; + privcmd_mmap_t ioctlx; + int i, rc; + void *addr; - ioctlx.num = nr; - ioctlx.dom = dom; - ioctlx.entry = entries; + addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0); + if (addr == MAP_FAILED) + goto mmap_failed; - err = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx); - if (err == 0) - return 0; - else - return -errno; + for (i = 0; i < nentries; i++) { + entries[i].va = (uintptr_t)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__); + +mmap_failed: + return NULL; } + static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data) { int err = ioctl(xc_handle, cmd, data); diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 2916903aef..6e49b749a0 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -184,8 +184,9 @@ static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl) return ret; } -int xc_map_foreign_ranges(int xc_handle, uint32_t dom, - privcmd_mmap_entry_t *entries, int nr); +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); void *map_domain_va_core(unsigned long domfd, int cpu, void *guest_va, vcpu_guest_context_any_t *ctxt); diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c index 86eee3c719..f88a928906 100644 --- a/tools/libxc/xc_solaris.c +++ b/tools/libxc/xc_solaris.c @@ -109,18 +109,41 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, return addr; } -int xc_map_foreign_ranges(int xc_handle, uint32_t dom, - privcmd_mmap_entry_t *entries, int nr) +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; + + addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 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 >> PAGE_SHIFT; + } - ioctlx.num = nr; + ioctlx.num = nentries; ioctlx.dom = dom; ioctlx.entry = entries; - return ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx); + rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx); + if (rc) + goto ioctl_failed; + +ioctl_failed: + rc = munmap(addr, size); + if (rc == -1) + ERROR("%s: error in error path\n", __FUNCTION__); + +mmap_failed: + return NULL; } + static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data) { return ioctl(xc_handle, cmd, data); |