diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-09-07 11:39:10 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-09-07 11:39:10 +0100 |
commit | 05cf544b87c791d183da579b6e9a6af06f2b93b8 (patch) | |
tree | dbdf964f1bf5f2ac789c2986a6430d38c89c5872 /tools | |
parent | 986fc80c6864d87d9578a2fc696fcc9fd1851a77 (diff) | |
download | xen-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.c | 2 | ||||
-rw-r--r-- | tools/ioemu/vl.c | 2 | ||||
-rw-r--r-- | tools/libxc/xc_misc.c | 33 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 8 | ||||
-rw-r--r-- | tools/xenfb/xenfb.c | 10 |
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; |