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/gntdev.c | |
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/gntdev.c')
-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 4687cd557c97..2c4cc940c429 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -258,6 +258,9 @@ static int map_grant_pages(struct grant_map *map) | |||
258 | phys_addr_t addr; | 258 | phys_addr_t addr; |
259 | 259 | ||
260 | if (!use_ptemod) { | 260 | if (!use_ptemod) { |
261 | /* Note: it could already be mapped */ | ||
262 | if (map->map_ops[0].handle) | ||
263 | return 0; | ||
261 | for (i = 0; i < map->count; i++) { | 264 | for (i = 0; i < map->count; i++) { |
262 | addr = (phys_addr_t) | 265 | addr = (phys_addr_t) |
263 | pfn_to_kaddr(page_to_pfn(map->pages[i])); | 266 | 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) | |||
668 | if (use_ptemod) | 671 | if (use_ptemod) |
669 | map->vma = vma; | 672 | map->vma = vma; |
670 | 673 | ||
671 | map->flags = GNTMAP_host_map; | 674 | if (map->flags) { |
672 | if (!(vma->vm_flags & VM_WRITE)) | 675 | if ((vma->vm_flags & VM_WRITE) && |
673 | map->flags |= GNTMAP_readonly; | 676 | (map->flags & GNTMAP_readonly)) |
677 | return -EINVAL; | ||
678 | } else { | ||
679 | map->flags = GNTMAP_host_map; | ||
680 | if (!(vma->vm_flags & VM_WRITE)) | ||
681 | map->flags |= GNTMAP_readonly; | ||
682 | } | ||
674 | 683 | ||
675 | spin_unlock(&priv->lock); | 684 | spin_unlock(&priv->lock); |
676 | 685 | ||