ia64/xen-unstable

changeset 15854:9071521d4864

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>
author kfraser@localhost.localdomain
date Fri Sep 07 11:39:10 2007 +0100 (2007-09-07)
parents 0c14d0bf369e
children f8e7f06b351c
files tools/ioemu/hw/cirrus_vga.c tools/ioemu/vl.c tools/libxc/xc_misc.c tools/libxc/xenctrl.h tools/xenfb/xenfb.c
line diff
     1.1 --- a/tools/ioemu/hw/cirrus_vga.c	Fri Sep 07 11:30:18 2007 +0100
     1.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Fri Sep 07 11:39:10 2007 +0100
     1.3 @@ -2565,7 +2565,7 @@ static void *set_vram_mapping(unsigned l
     1.4          return NULL;
     1.5      }
     1.6  
     1.7 -    vram_pointer = xc_map_foreign_batch(xc_handle, domid,
     1.8 +    vram_pointer = xc_map_foreign_pages(xc_handle, domid,
     1.9                                          PROT_READ|PROT_WRITE,
    1.10                                          extent_start, nr_extents);
    1.11      if (vram_pointer == NULL) {
     2.1 --- a/tools/ioemu/vl.c	Fri Sep 07 11:30:18 2007 +0100
     2.2 +++ b/tools/ioemu/vl.c	Fri Sep 07 11:39:10 2007 +0100
     2.3 @@ -6948,7 +6948,7 @@ static void qemu_remap_bucket(struct map
     2.4          j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
     2.5              (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
     2.6          while (j > 0)
     2.7 -            word = (word << 1) | !(pfns[i + --j] & 0xF0000000UL);
     2.8 +            word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
     2.9          entry->valid_mapping[i / BITS_PER_LONG] = word;
    2.10      }
    2.11  }
     3.1 --- a/tools/libxc/xc_misc.c	Fri Sep 07 11:30:18 2007 +0100
     3.2 +++ b/tools/libxc/xc_misc.c	Fri Sep 07 11:39:10 2007 +0100
     3.3 @@ -226,6 +226,39 @@ int xc_hvm_set_pci_link_route(
     3.4      return rc;
     3.5  }
     3.6  
     3.7 +void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
     3.8 +                           const xen_pfn_t *arr, int num)
     3.9 +{
    3.10 +    xen_pfn_t *pfn;
    3.11 +    void *res;
    3.12 +    int i;
    3.13 +
    3.14 +    pfn = malloc(num * sizeof(*pfn));
    3.15 +    if (!pfn)
    3.16 +        return NULL;
    3.17 +    memcpy(pfn, arr, num * sizeof(*pfn));
    3.18 +
    3.19 +    res = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
    3.20 +    if (res) {
    3.21 +        for (i = 0; i < num; i++) {
    3.22 +            if ((pfn[i] & 0xF0000000UL) == 0xF0000000UL) {
    3.23 +                /*
    3.24 +                 * xc_map_foreign_batch() doesn't give us an error
    3.25 +                 * code, so we have to make one up.  May not be the
    3.26 +                 * appropriate one.
    3.27 +                 */
    3.28 +                errno = EINVAL;
    3.29 +                munmap(res, num * PAGE_SIZE);
    3.30 +                res = NULL;
    3.31 +                break;
    3.32 +            }
    3.33 +        }
    3.34 +    }
    3.35 +
    3.36 +    free(pfn);
    3.37 +    return res;
    3.38 +}
    3.39 +
    3.40  /*
    3.41   * Local variables:
    3.42   * mode: C
     4.1 --- a/tools/libxc/xenctrl.h	Fri Sep 07 11:30:18 2007 +0100
     4.2 +++ b/tools/libxc/xenctrl.h	Fri Sep 07 11:39:10 2007 +0100
     4.3 @@ -646,6 +646,14 @@ void *xc_map_foreign_range(int xc_handle
     4.4                              int size, int prot,
     4.5                              unsigned long mfn );
     4.6  
     4.7 +void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
     4.8 +                           const xen_pfn_t *arr, int num );
     4.9 +
    4.10 +/**
    4.11 + * Like xc_map_foreign_pages(), except it can succeeed partially.
    4.12 + * When a page cannot be mapped, its PFN in @arr is or'ed with
    4.13 + * 0xF0000000 to indicate the error.
    4.14 + */
    4.15  void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
    4.16                             xen_pfn_t *arr, int num );
    4.17  
     5.1 --- a/tools/xenfb/xenfb.c	Fri Sep 07 11:30:18 2007 +0100
     5.2 +++ b/tools/xenfb/xenfb.c	Fri Sep 07 11:39:10 2007 +0100
     5.3 @@ -398,21 +398,15 @@ static int xenfb_map_fb(struct xenfb_pri
     5.4  	if (!pgmfns || !fbmfns)
     5.5  		goto out;
     5.6  
     5.7 -	/*
     5.8 -	 * Bug alert: xc_map_foreign_batch() can fail partly and
     5.9 -	 * return a non-null value.  This is a design flaw.  When it
    5.10 -	 * happens, we happily continue here, and later crash on
    5.11 -	 * access.
    5.12 -	 */
    5.13  	xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
    5.14 -	map = xc_map_foreign_batch(xenfb->xc, domid,
    5.15 +	map = xc_map_foreign_pages(xenfb->xc, domid,
    5.16  				   PROT_READ, pgmfns, n_fbdirs);
    5.17  	if (map == NULL)
    5.18  		goto out;
    5.19  	xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
    5.20  	munmap(map, n_fbdirs * XC_PAGE_SIZE);
    5.21  
    5.22 -	xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
    5.23 +	xenfb->pub.pixels = xc_map_foreign_pages(xenfb->xc, domid,
    5.24  				PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
    5.25  	if (xenfb->pub.pixels == NULL)
    5.26  		goto out;