diff options
author | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2011-02-09 16:11:32 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-02-14 14:16:22 -0500 |
commit | 12996fc38a2d760f3b30c9ceae26d0eeb92fe52d (patch) | |
tree | 2f41f71bff2077360c435c134f1d22217f89958e /drivers/xen | |
parent | b57c18694ea1641b691fa05ed8af0ce339fa430b (diff) |
xen-gntdev: Avoid double-mapping memory
If an already-mapped area of the device was mapped into userspace a
second time, a hypercall was incorrectly made to remap the memory
again. Avoid the hypercall on later mmap calls, and fail the mmap call
if a writable mapping is attempted on a read-only range.
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/gntdev.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 4687cd557c9..2c4cc940c42 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -258,6 +258,9 @@ static int map_grant_pages(struct grant_map *map) phys_addr_t addr; if (!use_ptemod) { + /* Note: it could already be mapped */ + if (map->map_ops[0].handle) + return 0; for (i = 0; i < map->count; i++) { addr = (phys_addr_t) pfn_to_kaddr(page_to_pfn(map->pages[i])); @@ -668,9 +671,15 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) if (use_ptemod) map->vma = vma; - map->flags = GNTMAP_host_map; - if (!(vma->vm_flags & VM_WRITE)) - map->flags |= GNTMAP_readonly; + if (map->flags) { + if ((vma->vm_flags & VM_WRITE) && + (map->flags & GNTMAP_readonly)) + return -EINVAL; + } else { + map->flags = GNTMAP_host_map; + if (!(vma->vm_flags & VM_WRITE)) + map->flags |= GNTMAP_readonly; + } spin_unlock(&priv->lock); |