aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-09-07 11:39:10 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-09-07 11:39:10 +0100
commit05cf544b87c791d183da579b6e9a6af06f2b93b8 (patch)
treedbdf964f1bf5f2ac789c2986a6430d38c89c5872 /tools
parent986fc80c6864d87d9578a2fc696fcc9fd1851a77 (diff)
downloadxen-05cf544b87c791d183da579b6e9a6af06f2b93b8.tar.gz
xen-05cf544b87c791d183da579b6e9a6af06f2b93b8.tar.bz2
xen-05cf544b87c791d183da579b6e9a6af06f2b93b8.zip
xc_map_foreign_pages(), a convenient alternative to xc_map_foreign_batch()
xc_map_foreign_batch() can succeed partially. It is awkward to use when you're only interested in complete success. Provide new xc_map_foreign_pages() convenience function for that kind of use. Also convert two obvious calls to use it. Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/hw/cirrus_vga.c2
-rw-r--r--tools/ioemu/vl.c2
-rw-r--r--tools/libxc/xc_misc.c33
-rw-r--r--tools/libxc/xenctrl.h8
-rw-r--r--tools/xenfb/xenfb.c10
5 files changed, 45 insertions, 10 deletions
diff --git a/tools/ioemu/hw/cirrus_vga.c b/tools/ioemu/hw/cirrus_vga.c
index cc73390716..68ec0b392b 100644
--- a/tools/ioemu/hw/cirrus_vga.c
+++ b/tools/ioemu/hw/cirrus_vga.c
@@ -2565,7 +2565,7 @@ static void *set_vram_mapping(unsigned long begin, unsigned long end)
return NULL;
}
- vram_pointer = xc_map_foreign_batch(xc_handle, domid,
+ vram_pointer = xc_map_foreign_pages(xc_handle, domid,
PROT_READ|PROT_WRITE,
extent_start, nr_extents);
if (vram_pointer == NULL) {
diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
index b1c3cca009..350a1e2e20 100644
--- a/tools/ioemu/vl.c
+++ b/tools/ioemu/vl.c
@@ -6948,7 +6948,7 @@ static void qemu_remap_bucket(struct map_cache *entry,
j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
(MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
while (j > 0)
- word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
+ word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
entry->valid_mapping[i / BITS_PER_LONG] = word;
}
}
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index 13fa65ff18..ba50866b56 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -226,6 +226,39 @@ int xc_hvm_set_pci_link_route(
return rc;
}
+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;
+
+ pfn = malloc(num * sizeof(*pfn));
+ if (!pfn)
+ return NULL;
+ memcpy(pfn, arr, num * sizeof(*pfn));
+
+ res = xc_map_foreign_batch(xc_handle, dom, prot, pfn, 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;
+ munmap(res, num * PAGE_SIZE);
+ res = NULL;
+ break;
+ }
+ }
+ }
+
+ free(pfn);
+ return res;
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 591e6c25a3..e39e899cc6 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -646,6 +646,14 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
int size, int prot,
unsigned long mfn );
+void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
+ const xen_pfn_t *arr, int num );
+
+/**
+ * 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.
+ */
void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
xen_pfn_t *arr, int num );
diff --git a/tools/xenfb/xenfb.c b/tools/xenfb/xenfb.c
index fcc83e6355..e94e01eee4 100644
--- a/tools/xenfb/xenfb.c
+++ b/tools/xenfb/xenfb.c
@@ -398,21 +398,15 @@ static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
if (!pgmfns || !fbmfns)
goto out;
- /*
- * Bug alert: xc_map_foreign_batch() can fail partly and
- * return a non-null value. This is a design flaw. When it
- * happens, we happily continue here, and later crash on
- * access.
- */
xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
- map = xc_map_foreign_batch(xenfb->xc, domid,
+ map = xc_map_foreign_pages(xenfb->xc, domid,
PROT_READ, pgmfns, n_fbdirs);
if (map == NULL)
goto out;
xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
munmap(map, n_fbdirs * XC_PAGE_SIZE);
- xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
+ xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
if (xenfb->pub.pixels == NULL)
goto out;