forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Reviewed-by: Oleksandr Andrushchenko <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Signed-off-by: Juergen Gross <[email protected]>
- Loading branch information
Showing
3 changed files
with
11 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,12 +55,10 @@ MODULE_AUTHOR("Derek G. Murray <[email protected]>, " | |
"Gerd Hoffmann <[email protected]>"); | ||
MODULE_DESCRIPTION("User-space granted page access driver"); | ||
|
||
static int limit = 1024*1024; | ||
module_param(limit, int, 0644); | ||
MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped by " | ||
"the gntdev device"); | ||
|
||
static atomic_t pages_mapped = ATOMIC_INIT(0); | ||
static unsigned int limit = 64*1024; | ||
module_param(limit, uint, 0644); | ||
MODULE_PARM_DESC(limit, | ||
"Maximum number of grants that may be mapped by one mapping request"); | ||
|
||
static int use_ptemod; | ||
|
||
|
@@ -71,9 +69,9 @@ static struct miscdevice gntdev_miscdev; | |
|
||
/* ------------------------------------------------------------------ */ | ||
|
||
bool gntdev_account_mapped_pages(int count) | ||
bool gntdev_test_page_count(unsigned int count) | ||
{ | ||
return atomic_add_return(count, &pages_mapped) > limit; | ||
return !count || count > limit; | ||
} | ||
|
||
static void gntdev_print_maps(struct gntdev_priv *priv, | ||
|
@@ -241,8 +239,6 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) | |
if (!refcount_dec_and_test(&map->users)) | ||
return; | ||
|
||
atomic_sub(map->count, &pages_mapped); | ||
|
||
if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { | ||
notify_remote_via_evtchn(map->notify.event); | ||
evtchn_put(map->notify.event); | ||
|
@@ -568,20 +564,14 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv, | |
if (copy_from_user(&op, u, sizeof(op)) != 0) | ||
return -EFAULT; | ||
pr_debug("priv %p, add %d\n", priv, op.count); | ||
if (unlikely(op.count <= 0)) | ||
if (unlikely(gntdev_test_page_count(op.count))) | ||
return -EINVAL; | ||
|
||
err = -ENOMEM; | ||
map = gntdev_alloc_map(priv, op.count, 0 /* This is not a dma-buf. */); | ||
if (!map) | ||
return err; | ||
|
||
if (unlikely(gntdev_account_mapped_pages(op.count))) { | ||
pr_debug("can't map: over limit\n"); | ||
gntdev_put_map(NULL, map); | ||
return err; | ||
} | ||
|
||
if (copy_from_user(map->grants, &u->refs, | ||
sizeof(map->grants[0]) * op.count) != 0) { | ||
gntdev_put_map(NULL, map); | ||
|