summaryrefslogtreecommitdiffstats
path: root/drivers/xen/gntdev-dmabuf.c
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2019-11-07 12:15:45 +0100
committerJuergen Gross <jgross@suse.com>2019-12-02 07:39:18 +0100
commit3b06ac6707c196b5036fe013c460da86c9060085 (patch)
treed6f3af7ef5da97dd674cb2461e30db2297457fbc /drivers/xen/gntdev-dmabuf.c
parentxen/gntdev: remove redundant non-zero check on ret (diff)
downloadlinux-3b06ac6707c196b5036fe013c460da86c9060085.tar.xz
linux-3b06ac6707c196b5036fe013c460da86c9060085.zip
xen/gntdev: replace global limit of mapped pages by limit per call
Today there is a global limit of pages mapped via /dev/xen/gntdev set to 1 million pages per default. There is no reason why that limit is existing, as total number of grant mappings is limited by the hypervisor anyway and preferring kernel mappings over userspace ones doesn't make sense. It should be noted that the gntdev device is usable by root only. Additionally checking of that limit is fragile, as the number of pages to map via one call is specified in a 32-bit unsigned variable which isn't tested to stay within reasonable limits (the only test is the value to be <= zero, which basically excludes only calls without any mapping requested). So trying to map e.g. 0xffff0000 pages while already nearly 1000000 pages are mapped will effectively lower the global number of mapped pages such that a parallel call mapping a reasonable amount of pages can succeed in spite of the global limit being violated. So drop the global limit and introduce per call limit instead. This per call limit (default: 65536 grant mappings) protects against allocating insane large arrays in the kernel for doing a hypercall which will fail anyway in case a user is e.g. trying to map billions of pages. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Signed-off-by: Juergen Gross <jgross@suse.com>
Diffstat (limited to 'drivers/xen/gntdev-dmabuf.c')
-rw-r--r--drivers/xen/gntdev-dmabuf.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 2c4f324f8626..63f0857bf62d 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -446,7 +446,7 @@ dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags,
{
struct gntdev_grant_map *map;
- if (unlikely(count <= 0))
+ if (unlikely(gntdev_test_page_count(count)))
return ERR_PTR(-EINVAL);
if ((dmabuf_flags & GNTDEV_DMA_FLAG_WC) &&
@@ -459,11 +459,6 @@ dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags,
if (!map)
return ERR_PTR(-ENOMEM);
- if (unlikely(gntdev_account_mapped_pages(count))) {
- pr_debug("can't map %d pages: over limit\n", count);
- gntdev_put_map(NULL, map);
- return ERR_PTR(-ENOMEM);
- }
return map;
}
@@ -771,7 +766,7 @@ long gntdev_ioctl_dmabuf_exp_from_refs(struct gntdev_priv *priv, int use_ptemod,
if (copy_from_user(&op, u, sizeof(op)) != 0)
return -EFAULT;
- if (unlikely(op.count <= 0))
+ if (unlikely(gntdev_test_page_count(op.count)))
return -EINVAL;
refs = kcalloc(op.count, sizeof(*refs), GFP_KERNEL);
@@ -818,7 +813,7 @@ long gntdev_ioctl_dmabuf_imp_to_refs(struct gntdev_priv *priv,
if (copy_from_user(&op, u, sizeof(op)) != 0)
return -EFAULT;
- if (unlikely(op.count <= 0))
+ if (unlikely(gntdev_test_page_count(op.count)))
return -EINVAL;
gntdev_dmabuf = dmabuf_imp_to_refs(priv->dmabuf_priv,