aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-23 16:39:46 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-23 16:39:46 +0100
commitce29ad450cc37e90052059118c075f80f79c9838 (patch)
tree944bbb8f868a5cf632d14cfcc1280233cf2b33e5
parent6de959a1f6dd5ef22036f1a1d74cdcfce25d327c (diff)
downloadxen-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.c28
-rw-r--r--tools/libxc/xc_domain_save.c42
-rw-r--r--tools/libxc/xc_hvm_build.c24
-rw-r--r--tools/libxc/xc_linux.c33
-rw-r--r--tools/libxc/xc_minios.c11
-rw-r--r--tools/libxc/xc_netbsd.c45
-rw-r--r--tools/libxc/xc_private.h5
-rw-r--r--tools/libxc/xc_solaris.c31
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);