aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_misc.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-01-13 08:12:56 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-01-13 08:12:56 +0000
commit9fececad98aa1259a9896edf7e7931822e3eef87 (patch)
tree5f7b5081edfee2647be16264a12e48c10465fc82 /tools/libxc/xc_misc.c
parentd092fb82a229773dad917f5a6eaa3cced9054d19 (diff)
downloadxen-9fececad98aa1259a9896edf7e7931822e3eef87.tar.gz
xen-9fececad98aa1259a9896edf7e7931822e3eef87.tar.bz2
xen-9fececad98aa1259a9896edf7e7931822e3eef87.zip
libxc: use new (replacement) mmap-batch ioctl
Replace all calls to xc_map_foreign_batch() where the caller doesn't look at the passed in array to check for errors by calls to xc_map_foreign_pages(). Replace all remaining calls by such to the newly introduced xc_map_foreign_bulk(). As a sideband modification (needed while writing the patch to ensure they're unused) eliminate unused parameters to uncanonicalize_pagetable() and xc_map_foreign_batch_single(). Also unmap live_p2m_frame_list earlier in map_and_save_p2m_table(), reducing the peak amount of virtual address space required. All supported OSes other than Linux continue to use the old ioctl for the time being. Also change libxc's MAJOR to 4.0 to reflect the API change. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'tools/libxc/xc_misc.c')
-rw-r--r--tools/libxc/xc_misc.c69
1 files changed, 55 insertions, 14 deletions
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