aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/include/xen-sys/Linux/privcmd.h10
-rw-r--r--tools/libxc/Makefile2
-rw-r--r--tools/libxc/xc_domain_restore.c16
-rw-r--r--tools/libxc/xc_domain_save.c49
-rw-r--r--tools/libxc/xc_linux.c133
-rw-r--r--tools/libxc/xc_misc.c69
-rw-r--r--tools/libxc/xc_resume.c4
-rw-r--r--tools/libxc/xenctrl.h10
-rw-r--r--tools/xenpaging/xenpaging.c13
9 files changed, 249 insertions, 57 deletions
diff --git a/tools/include/xen-sys/Linux/privcmd.h b/tools/include/xen-sys/Linux/privcmd.h
index d1162eebb0..d35aac9baa 100644
--- a/tools/include/xen-sys/Linux/privcmd.h
+++ b/tools/include/xen-sys/Linux/privcmd.h
@@ -64,6 +64,14 @@ typedef struct privcmd_mmapbatch {
xen_pfn_t __user *arr; /* array of mfns - top nibble set on err */
} privcmd_mmapbatch_t;
+typedef struct privcmd_mmapbatch_v2 {
+ unsigned int num; /* number of pages to populate */
+ domid_t dom; /* target domain */
+ __u64 addr; /* virtual address */
+ const xen_pfn_t __user *arr; /* array of mfns */
+ int __user *err; /* array of error codes */
+} privcmd_mmapbatch_v2_t;
+
/*
* @cmd: IOCTL_PRIVCMD_HYPERCALL
* @arg: &privcmd_hypercall_t
@@ -75,5 +83,7 @@ typedef struct privcmd_mmapbatch {
_IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
#define IOCTL_PRIVCMD_MMAPBATCH \
_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
+#define IOCTL_PRIVCMD_MMAPBATCH_V2 \
+ _IOC(_IOC_NONE, 'P', 4, sizeof(privcmd_mmapbatch_v2_t))
#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 8a5bdb5ced..8a565e1370 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -1,7 +1,7 @@
XEN_ROOT = ../..
include $(XEN_ROOT)/tools/Rules.mk
-MAJOR = 3.4
+MAJOR = 4.0
MINOR = 0
CTRL_SRCS-y :=
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 827ba6bfd0..3999569582 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -118,7 +118,7 @@ static int break_super_page(int xc_handle,
page_array[i] = start_pfn + i;
}
- ram_base = xc_map_foreign_batch(xc_handle, dom, PROT_READ,
+ ram_base = xc_map_foreign_pages(xc_handle, dom, PROT_READ,
page_array, tot_pfns);
if ( ram_base == NULL )
@@ -166,7 +166,7 @@ static int break_super_page(int xc_handle,
page_array[i] = start_pfn + i;
}
- ram_base = xc_map_foreign_batch(xc_handle, dom, PROT_WRITE,
+ ram_base = xc_map_foreign_pages(xc_handle, dom, PROT_WRITE,
page_array, tot_pfns);
if ( ram_base == NULL )
{
@@ -494,7 +494,7 @@ static ssize_t read_exact_timed(int fd, void* buf, size_t size)
** the (now known) appropriate mfn values.
*/
static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, struct restore_ctx *ctx,
- unsigned long type, void *page, int superpages)
+ void *page, int superpages)
{
int i, pte_last;
unsigned long pfn;
@@ -1186,7 +1186,7 @@ static int apply_batch(int xc_handle, uint32_t dom, struct restore_ctx *ctx,
}
/* Map relevant mfns */
- region_base = xc_map_foreign_batch(
+ region_base = xc_map_foreign_pages(
xc_handle, dom, PROT_WRITE, region_mfn, j);
if ( region_base == NULL )
@@ -1240,7 +1240,7 @@ static int apply_batch(int xc_handle, uint32_t dom, struct restore_ctx *ctx,
(pagetype != XEN_DOMCTL_PFINFO_L1TAB)) {
if (!uncanonicalize_pagetable(xc_handle, dom, ctx,
- pagetype, page, superpages)) {
+ page, superpages)) {
/*
** Failing to uncanonicalize a page table can be ok
** under live migration since the pages type may have
@@ -1655,7 +1655,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
if ( (i == (dinfo->p2m_size-1)) || (j == MAX_BATCH_SIZE) )
{
- region_base = xc_map_foreign_batch(
+ region_base = xc_map_foreign_pages(
xc_handle, dom, PROT_READ | PROT_WRITE, region_mfn, j);
if ( region_base == NULL )
{
@@ -1666,7 +1666,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
for ( k = 0; k < j; k++ )
{
if ( !uncanonicalize_pagetable(
- xc_handle, dom, ctx, XEN_DOMCTL_PFINFO_L1TAB,
+ xc_handle, dom, ctx,
region_base + k*PAGE_SIZE, superpages) )
{
ERROR("failed uncanonicalize pt!");
@@ -1949,7 +1949,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
}
/* Copy the P2M we've constructed to the 'live' P2M */
- if ( !(ctx->live_p2m = xc_map_foreign_batch(xc_handle, dom, PROT_WRITE,
+ if ( !(ctx->live_p2m = xc_map_foreign_pages(xc_handle, dom, PROT_WRITE,
p2m_frame_list, P2M_FL_ENTRIES)) )
{
ERROR("Couldn't map p2m table");
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 3f351ad071..87ec7dbbd6 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -709,7 +709,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
live_p2m_frame_list =
- xc_map_foreign_batch(xc_handle, dom, PROT_READ,
+ xc_map_foreign_pages(xc_handle, dom, PROT_READ,
p2m_frame_list_list,
P2M_FLL_ENTRIES);
if ( !live_p2m_frame_list )
@@ -727,6 +727,9 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE);
memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE);
+ munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
+ live_p2m_frame_list = NULL;
+
/* Canonicalize guest's unsigned long vs ours */
if ( dinfo->guest_width > sizeof(unsigned long) )
for ( i = 0; i < P2M_FL_ENTRIES; i++ )
@@ -741,7 +744,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
(its not clear why it would want to change them, and we'll be OK
from a safety POV anyhow. */
- p2m = xc_map_foreign_batch(xc_handle, dom, PROT_READ,
+ p2m = xc_map_foreign_pages(xc_handle, dom, PROT_READ,
p2m_frame_list,
P2M_FL_ENTRIES);
if ( !p2m )
@@ -873,8 +876,9 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
vcpu_guest_context_any_t ctxt;
/* A table containing the type of each PFN (/not/ MFN!). */
- unsigned long *pfn_type = NULL;
+ xen_pfn_t *pfn_type = NULL;
unsigned long *pfn_batch = NULL;
+ int *pfn_err = NULL;
/* A copy of one frame of guest memory. */
char page[PAGE_SIZE];
@@ -1263,8 +1267,8 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
if ( batch == 0 )
goto skip; /* vanishingly unlikely... */
- region_base = xc_map_foreign_batch(
- xc_handle, dom, PROT_READ, pfn_type, batch);
+ region_base = xc_map_foreign_bulk(
+ xc_handle, dom, PROT_READ, pfn_type, pfn_err, batch);
if ( region_base == NULL )
{
ERROR("map batch failed");
@@ -1275,14 +1279,19 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
{
/* Look for and skip completely empty batches. */
for ( j = 0; j < batch; j++ )
- if ( (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) !=
- XEN_DOMCTL_PFINFO_XTAB )
+ {
+ if ( !pfn_err[j] )
break;
+ pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
+ }
if ( j == batch )
{
munmap(region_base, batch*PAGE_SIZE);
continue; /* bail on this batch: no valid pages */
}
+ for ( ; j < batch; j++ )
+ if ( pfn_err[j] )
+ pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
}
else
{
@@ -1296,16 +1305,17 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
goto out;
}
for ( j = batch-1; j >= 0; j-- )
- pfn_type[j] = ((uint32_t *)pfn_type)[j];
+ pfn_type[j] = ((uint32_t *)pfn_type)[j] &
+ XEN_DOMCTL_PFINFO_LTAB_MASK;
for ( j = 0; j < batch; j++ )
{
+ unsigned long mfn = pfn_to_mfn(pfn_batch[j]);
- if ( (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) ==
- XEN_DOMCTL_PFINFO_XTAB )
+ if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB )
{
DPRINTF("type fail: page %i mfn %08lx\n",
- j, pfn_type[j]);
+ j, mfn);
continue;
}
@@ -1313,16 +1323,13 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
" sum= %08lx\n",
iter,
- (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) |
- pfn_batch[j],
- pfn_type[j],
- mfn_to_pfn(pfn_type[j] &
- ~XEN_DOMCTL_PFINFO_LTAB_MASK),
+ pfn_type[j] | pfn_batch[j],
+ mfn,
+ mfn_to_pfn(mfn),
csum_page(region_base + (PAGE_SIZE*j)));
/* canonicalise mfn->pfn */
- pfn_type[j] = (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) |
- pfn_batch[j];
+ pfn_type[j] |= pfn_batch[j];
}
}
@@ -1332,11 +1339,17 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
goto out;
}
+ if ( sizeof(unsigned long) < sizeof(*pfn_type) )
+ for ( j = 0; j < batch; j++ )
+ ((unsigned long *)pfn_type)[j] = pfn_type[j];
if ( write_exact(io_fd, pfn_type, sizeof(unsigned long)*batch) )
{
PERROR("Error when writing to state file (3)");
goto out;
}
+ if ( sizeof(unsigned long) < sizeof(*pfn_type) )
+ while ( --j >= 0 )
+ pfn_type[j] = ((unsigned long *)pfn_type)[j];
/* entering this loop, pfn_type is now in pfns (Not mfns) */
run = 0;
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c
index 0f1b78aa57..e0e807f2cc 100644
--- a/tools/libxc/xc_linux.c
+++ b/tools/libxc/xc_linux.c
@@ -64,7 +64,7 @@ int xc_interface_close(int xc_handle)
return close(xc_handle);
}
-static int xc_map_foreign_batch_single(int xc_handle, uint32_t dom, int prot,
+static int xc_map_foreign_batch_single(int xc_handle, uint32_t dom,
xen_pfn_t *mfn, unsigned long addr)
{
privcmd_mmapbatch_t ioctlx;
@@ -116,7 +116,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
XEN_DOMCTL_PFINFO_PAGEDTAB )
{
unsigned long paged_addr = (unsigned long)addr + (i << PAGE_SHIFT);
- rc = xc_map_foreign_batch_single(xc_handle, dom, prot, &arr[i],
+ rc = xc_map_foreign_batch_single(xc_handle, dom, &arr[i],
paged_addr);
if ( rc < 0 )
goto out;
@@ -137,6 +137,131 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
return addr;
}
+void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+ const xen_pfn_t *arr, int *err, unsigned int num)
+{
+ privcmd_mmapbatch_v2_t ioctlx;
+ void *addr;
+ unsigned int i;
+ int rc;
+
+ addr = mmap(NULL, (unsigned long)num << PAGE_SHIFT, prot, MAP_SHARED,
+ xc_handle, 0);
+ if ( addr == MAP_FAILED )
+ {
+ perror("xc_map_foreign_batch: mmap failed");
+ return NULL;
+ }
+
+ ioctlx.num = num;
+ ioctlx.dom = dom;
+ ioctlx.addr = (unsigned long)addr;
+ ioctlx.arr = arr;
+ ioctlx.err = err;
+
+ rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
+
+ if ( rc < 0 && errno == ENOENT )
+ {
+ for ( i = rc = 0; rc == 0 && i < num; i++ )
+ {
+ if ( err[i] != -ENOENT )
+ continue;
+
+ ioctlx.num = 1;
+ ioctlx.dom = dom;
+ ioctlx.addr = (unsigned long)addr + ((unsigned long)i<<PAGE_SHIFT);
+ ioctlx.arr = arr + i;
+ ioctlx.err = err + i;
+ do {
+ usleep(100);
+ rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
+ } while ( rc < 0 && err[i] == -ENOENT );
+ }
+ }
+
+ if ( rc < 0 && errno == ENOTTY && (int)num > 0 )
+ {
+ /*
+ * IOCTL_PRIVCMD_MMAPBATCH_V2 is not supported - fall back to
+ * IOCTL_PRIVCMD_MMAPBATCH.
+ */
+ xen_pfn_t *pfn = calloc(num, sizeof(*pfn));
+
+ if ( pfn )
+ {
+ privcmd_mmapbatch_t ioctlx;
+
+ memcpy(pfn, arr, num * sizeof(*arr));
+
+ ioctlx.num = num;
+ ioctlx.dom = dom;
+ ioctlx.addr = (unsigned long)addr;
+ ioctlx.arr = pfn;
+
+ rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
+
+ rc = rc < 0 ? -errno : 0;
+
+ for ( i = 0; i < num; ++i )
+ {
+ switch ( pfn[i] ^ arr[i] )
+ {
+ case 0:
+ err[i] = rc != -ENOENT ? rc : 0;
+ continue;
+ default:
+ err[i] = -EINVAL;
+ continue;
+ case XEN_DOMCTL_PFINFO_PAGEDTAB:
+ if ( rc != -ENOENT )
+ {
+ err[i] = rc ?: -EINVAL;
+ continue;
+ }
+ rc = xc_map_foreign_batch_single(xc_handle, dom, pfn + i,
+ (unsigned long)addr + ((unsigned long)i<<PAGE_SHIFT));
+ if ( rc < 0 )
+ {
+ rc = -errno;
+ break;
+ }
+ rc = -ENOENT;
+ continue;
+ }
+ break;
+ }
+
+ free(pfn);
+
+ if ( rc == -ENOENT && i == num )
+ rc = 0;
+ else if ( rc )
+ {
+ errno = -rc;
+ rc = -1;
+ }
+ }
+ else
+ {
+ errno = -ENOMEM;
+ rc = -1;
+ }
+ }
+
+ if ( rc < 0 )
+ {
+ int saved_errno = errno;
+
+ perror("xc_map_foreign_bulk: ioctl failed");
+ (void)munmap(addr, (unsigned long)num << PAGE_SHIFT);
+ errno = saved_errno;
+ return NULL;
+ }
+
+ return addr;
+}
+
void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot,
unsigned long mfn)
{
@@ -151,7 +276,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot,
for ( i = 0; i < num; i++ )
arr[i] = mfn + i;
- ret = xc_map_foreign_batch(xc_handle, dom, prot, arr, num);
+ ret = xc_map_foreign_pages(xc_handle, dom, prot, arr, num);
free(arr);
return ret;
}
@@ -175,7 +300,7 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom, size_t size, int prot,
for ( j = 0; j < num_per_entry; j++ )
arr[i * num_per_entry + j] = entries[i].mfn + j;
- ret = xc_map_foreign_batch(xc_handle, dom, prot, arr, num);
+ ret = xc_map_foreign_pages(xc_handle, dom, prot, arr, num);
free(arr);
return ret;
}
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index ffc04fb50f..e237b7862d 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -352,25 +352,23 @@ int xc_hvm_set_mem_type(
void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
const xen_pfn_t *arr, int num)
{
- xen_pfn_t *pfn;
void *res;
- int i;
+ int i, *err;
+
+ if (num < 0) {
+ errno = -EINVAL;
+ return NULL;
+ }
- pfn = malloc(num * sizeof(*pfn));
- if (!pfn)
+ err = calloc(num, sizeof(*err));
+ if (!err)
return NULL;
- memcpy(pfn, arr, num * sizeof(*pfn));
- res = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
+ res = xc_map_foreign_bulk(xc_handle, dom, prot, arr, err, num);
if (res) {
for (i = 0; i < num; i++) {
- if ((pfn[i] & 0xF0000000UL) == 0xF0000000UL) {
- /*
- * xc_map_foreign_batch() doesn't give us an error
- * code, so we have to make one up. May not be the
- * appropriate one.
- */
- errno = EINVAL;
+ if (err[i]) {
+ errno = -err[i];
munmap(res, num * PAGE_SIZE);
res = NULL;
break;
@@ -378,10 +376,53 @@ void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
}
}
- free(pfn);
+ free(err);
return res;
}
+/* stub for all not yet converted OSes */
+void *
+#ifdef __GNUC__
+__attribute__((__weak__))
+#endif
+xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+ const xen_pfn_t *arr, int *err, unsigned int num)
+{
+ xen_pfn_t *pfn;
+ unsigned int i;
+ void *ret;
+
+ if ((int)num <= 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ pfn = calloc(num, sizeof(*pfn));
+ if (!pfn) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ memcpy(pfn, arr, num * sizeof(*arr));
+ ret = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
+
+ if (ret) {
+ for (i = 0; i < num; ++i)
+ switch (pfn[i] ^ arr[i]) {
+ case 0:
+ err[i] = 0;
+ break;
+ default:
+ err[i] = -EINVAL;
+ break;
+ }
+ }
+
+ free(pfn);
+
+ return ret;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xc_resume.c b/tools/libxc/xc_resume.c
index 2816609b0d..c17ae262d3 100644
--- a/tools/libxc/xc_resume.c
+++ b/tools/libxc/xc_resume.c
@@ -158,7 +158,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
goto out;
}
- p2m_frame_list = xc_map_foreign_batch(xc_handle, domid, PROT_READ,
+ p2m_frame_list = xc_map_foreign_pages(xc_handle, domid, PROT_READ,
p2m_frame_list_list,
P2M_FLL_ENTRIES);
if ( p2m_frame_list == NULL )
@@ -171,7 +171,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t domid)
the guest must not change which frames are used for this purpose.
(its not clear why it would want to change them, and we'll be OK
from a safety POV anyhow. */
- p2m = xc_map_foreign_batch(xc_handle, domid, PROT_READ,
+ p2m = xc_map_foreign_pages(xc_handle, domid, PROT_READ,
p2m_frame_list,
P2M_FL_ENTRIES);
if ( p2m == NULL )
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 4be69a814f..7a35a1439c 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -749,6 +749,8 @@ void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
const xen_pfn_t *arr, int num );
/**
+ * DEPRECATED - use xc_map_foreign_bulk() instead.
+ *
* Like xc_map_foreign_pages(), except it can succeeed partially.
* When a page cannot be mapped, its PFN in @arr is or'ed with
* 0xF0000000 to indicate the error.
@@ -757,6 +759,14 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
xen_pfn_t *arr, int num );
/**
+ * Like xc_map_foreign_pages(), except it can succeed partially.
+ * When a page cannot be mapped, its respective field in @err is
+ * set to the corresponding errno value.
+ */
+void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+ const xen_pfn_t *arr, int *err, unsigned int num);
+
+/**
* Translates a virtual address in the context of a given domain and
* vcpu returning the GFN containing the address (that is, an MFN for
* PV guests, a PFN for HVM guests). Returns 0 for failure.
diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c
index 2817cb7312..a207ca8ac9 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -310,9 +310,9 @@ int xenpaging_evict_page(xenpaging_t *paging, xenpaging_victim_t *victim, int fd
/* Map page */
gfn = victim->gfn;
ret = -EFAULT;
- page = xc_map_foreign_batch(paging->xc_handle, victim->domain_id,
+ page = xc_map_foreign_pages(paging->xc_handle, victim->domain_id,
PROT_READ | PROT_WRITE, &gfn, 1);
- if ( (gfn & XEN_DOMCTL_PFINFO_LTAB_MASK) == XEN_DOMCTL_PFINFO_XTAB )
+ if ( page == NULL )
{
ERROR("Error mapping page");
goto out;
@@ -386,7 +386,7 @@ int xenpaging_populate_page(xenpaging_t *paging, unsigned long *gfn, int fd, int
/* Map page */
ret = -EFAULT;
- page = xc_map_foreign_batch(paging->xc_handle, paging->mem_event.domain_id,
+ page = xc_map_foreign_pages(paging->xc_handle, paging->mem_event.domain_id,
PROT_READ | PROT_WRITE, gfn, 1);
if ( page == NULL )
{
@@ -394,13 +394,6 @@ int xenpaging_populate_page(xenpaging_t *paging, unsigned long *gfn, int fd, int
goto out_map;
}
- /* Check that the page exists */
- if ( (*gfn & XEN_DOMCTL_PFINFO_LTAB_MASK) == XEN_DOMCTL_PFINFO_XTAB )
- {
- ERROR("Error mapping page: gfn is invalid");
- goto out;
- }
-
/* Read page */
ret = read_page(fd, page, i);
if ( ret != 0 )