underlying mmap() invocation.
From: Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
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));
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,
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;
}
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);
(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;
}
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. */
rc = 0;
err:
- if ( elf->dest )
- {
- munmap(elf->dest, pages << PAGE_SHIFT);
- elf->dest = NULL;
- }
-
if ( entries )
free(entries);
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)
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)
{
}
return 0;
}
+#endif
int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
{
#include "xc_private.h"
-#include <xen/memory.h>
#include <xen/sys/evtchn.h>
#include <unistd.h>
#include <fcntl.h>
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);
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);
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);