diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 20:13:58 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 20:29:13 -0400 |
| commit | 6be5ceb02e98eaf6cfc4f8b12a896d04023f340d (patch) | |
| tree | f34de1392300bbf63549f4eeb20f7606d6f7b1f9 | |
| parent | a46ef99d80817a167477ed1c8b4d90ee0c2e726f (diff) | |
VM: add "vm_mmap()" helper function
This continues the theme started with vm_brk() and vm_munmap():
vm_mmap() does the same thing as do_mmap(), but additionally does the
required VM locking.
This uninlines (and rewrites it to be clearer) do_mmap(), which sadly
duplicates it in mm/mmap.c and mm/nommu.c. But that way we don't have
to export our internal do_mmap_pgoff() function.
Some day we hopefully don't have to export do_mmap() either, if all
modular users can become the simpler vm_mmap() instead. We're actually
very close to that already, with the notable exception of the (broken)
use in i810, and a couple of stragglers in binfmt_elf.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | arch/tile/kernel/single_step.c | 4 | ||||
| -rw-r--r-- | arch/x86/ia32/ia32_aout.c | 12 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_bufs.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i810/i810_dma.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 4 | ||||
| -rw-r--r-- | fs/binfmt_aout.c | 12 | ||||
| -rw-r--r-- | fs/binfmt_elf.c | 8 | ||||
| -rw-r--r-- | fs/binfmt_elf_fdpic.c | 18 | ||||
| -rw-r--r-- | fs/binfmt_flat.c | 12 | ||||
| -rw-r--r-- | fs/binfmt_som.c | 12 | ||||
| -rw-r--r-- | include/linux/mm.h | 23 | ||||
| -rw-r--r-- | mm/mmap.c | 29 | ||||
| -rw-r--r-- | mm/nommu.c | 29 |
15 files changed, 87 insertions, 97 deletions
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c index 9efbc1391b3c..89529c9f0605 100644 --- a/arch/tile/kernel/single_step.c +++ b/arch/tile/kernel/single_step.c | |||
| @@ -346,12 +346,10 @@ void single_step_once(struct pt_regs *regs) | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | /* allocate a cache line of writable, executable memory */ | 348 | /* allocate a cache line of writable, executable memory */ |
| 349 | down_write(¤t->mm->mmap_sem); | 349 | buffer = (void __user *) vm_mmap(NULL, 0, 64, |
| 350 | buffer = (void __user *) do_mmap(NULL, 0, 64, | ||
| 351 | PROT_EXEC | PROT_READ | PROT_WRITE, | 350 | PROT_EXEC | PROT_READ | PROT_WRITE, |
| 352 | MAP_PRIVATE | MAP_ANONYMOUS, | 351 | MAP_PRIVATE | MAP_ANONYMOUS, |
| 353 | 0); | 352 | 0); |
| 354 | up_write(¤t->mm->mmap_sem); | ||
| 355 | 353 | ||
| 356 | if (IS_ERR((void __force *)buffer)) { | 354 | if (IS_ERR((void __force *)buffer)) { |
| 357 | kfree(state); | 355 | kfree(state); |
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index b6817ee9033f..4824fb45560f 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
| @@ -379,26 +379,22 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
| 379 | goto beyond_if; | 379 | goto beyond_if; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | down_write(¤t->mm->mmap_sem); | 382 | error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, |
| 383 | error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, | ||
| 384 | PROT_READ | PROT_EXEC, | 383 | PROT_READ | PROT_EXEC, |
| 385 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | | 384 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | |
| 386 | MAP_EXECUTABLE | MAP_32BIT, | 385 | MAP_EXECUTABLE | MAP_32BIT, |
| 387 | fd_offset); | 386 | fd_offset); |
| 388 | up_write(¤t->mm->mmap_sem); | ||
| 389 | 387 | ||
| 390 | if (error != N_TXTADDR(ex)) { | 388 | if (error != N_TXTADDR(ex)) { |
| 391 | send_sig(SIGKILL, current, 0); | 389 | send_sig(SIGKILL, current, 0); |
| 392 | return error; | 390 | return error; |
| 393 | } | 391 | } |
| 394 | 392 | ||
| 395 | down_write(¤t->mm->mmap_sem); | 393 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
| 396 | error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | ||
| 397 | PROT_READ | PROT_WRITE | PROT_EXEC, | 394 | PROT_READ | PROT_WRITE | PROT_EXEC, |
| 398 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | | 395 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | |
| 399 | MAP_EXECUTABLE | MAP_32BIT, | 396 | MAP_EXECUTABLE | MAP_32BIT, |
| 400 | fd_offset + ex.a_text); | 397 | fd_offset + ex.a_text); |
| 401 | up_write(¤t->mm->mmap_sem); | ||
| 402 | if (error != N_DATADDR(ex)) { | 398 | if (error != N_DATADDR(ex)) { |
| 403 | send_sig(SIGKILL, current, 0); | 399 | send_sig(SIGKILL, current, 0); |
| 404 | return error; | 400 | return error; |
| @@ -482,12 +478,10 @@ static int load_aout_library(struct file *file) | |||
| 482 | goto out; | 478 | goto out; |
| 483 | } | 479 | } |
| 484 | /* Now use mmap to map the library into memory. */ | 480 | /* Now use mmap to map the library into memory. */ |
| 485 | down_write(¤t->mm->mmap_sem); | 481 | error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, |
| 486 | error = do_mmap(file, start_addr, ex.a_text + ex.a_data, | ||
| 487 | PROT_READ | PROT_WRITE | PROT_EXEC, | 482 | PROT_READ | PROT_WRITE | PROT_EXEC, |
| 488 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, | 483 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, |
| 489 | N_TXTOFF(ex)); | 484 | N_TXTOFF(ex)); |
| 490 | up_write(¤t->mm->mmap_sem); | ||
| 491 | retval = error; | 485 | retval = error; |
| 492 | if (error != start_addr) | 486 | if (error != start_addr) |
| 493 | goto out; | 487 | goto out; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8beb9ce79364..1457be305fb1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -6336,13 +6336,11 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, | |||
| 6336 | if (npages && !old.rmap) { | 6336 | if (npages && !old.rmap) { |
| 6337 | unsigned long userspace_addr; | 6337 | unsigned long userspace_addr; |
| 6338 | 6338 | ||
| 6339 | down_write(¤t->mm->mmap_sem); | 6339 | userspace_addr = vm_mmap(NULL, 0, |
| 6340 | userspace_addr = do_mmap(NULL, 0, | ||
| 6341 | npages * PAGE_SIZE, | 6340 | npages * PAGE_SIZE, |
| 6342 | PROT_READ | PROT_WRITE, | 6341 | PROT_READ | PROT_WRITE, |
| 6343 | map_flags, | 6342 | map_flags, |
| 6344 | 0); | 6343 | 0); |
| 6345 | up_write(¤t->mm->mmap_sem); | ||
| 6346 | 6344 | ||
| 6347 | if (IS_ERR((void *)userspace_addr)) | 6345 | if (IS_ERR((void *)userspace_addr)) |
| 6348 | return PTR_ERR((void *)userspace_addr); | 6346 | return PTR_ERR((void *)userspace_addr); |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 30372f7b2d45..348b367debeb 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
| @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, | |||
| 1510 | * \param arg pointer to a drm_buf_map structure. | 1510 | * \param arg pointer to a drm_buf_map structure. |
| 1511 | * \return zero on success or a negative number on failure. | 1511 | * \return zero on success or a negative number on failure. |
| 1512 | * | 1512 | * |
| 1513 | * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information | 1513 | * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information |
| 1514 | * about each buffer into user space. For PCI buffers, it calls do_mmap() with | 1514 | * about each buffer into user space. For PCI buffers, it calls vm_mmap() with |
| 1515 | * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls | 1515 | * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls |
| 1516 | * drm_mmap_dma(). | 1516 | * drm_mmap_dma(). |
| 1517 | */ | 1517 | */ |
| @@ -1553,18 +1553,14 @@ int drm_mapbufs(struct drm_device *dev, void *data, | |||
| 1553 | retcode = -EINVAL; | 1553 | retcode = -EINVAL; |
| 1554 | goto done; | 1554 | goto done; |
| 1555 | } | 1555 | } |
| 1556 | down_write(¤t->mm->mmap_sem); | 1556 | virtual = vm_mmap(file_priv->filp, 0, map->size, |
| 1557 | virtual = do_mmap(file_priv->filp, 0, map->size, | ||
| 1558 | PROT_READ | PROT_WRITE, | 1557 | PROT_READ | PROT_WRITE, |
| 1559 | MAP_SHARED, | 1558 | MAP_SHARED, |
| 1560 | token); | 1559 | token); |
| 1561 | up_write(¤t->mm->mmap_sem); | ||
| 1562 | } else { | 1560 | } else { |
| 1563 | down_write(¤t->mm->mmap_sem); | 1561 | virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, |
| 1564 | virtual = do_mmap(file_priv->filp, 0, dma->byte_count, | ||
| 1565 | PROT_READ | PROT_WRITE, | 1562 | PROT_READ | PROT_WRITE, |
| 1566 | MAP_SHARED, 0); | 1563 | MAP_SHARED, 0); |
| 1567 | up_write(¤t->mm->mmap_sem); | ||
| 1568 | } | 1564 | } |
| 1569 | if (virtual > -1024UL) { | 1565 | if (virtual > -1024UL) { |
| 1570 | /* Real error */ | 1566 | /* Real error */ |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 26d51979116b..392ce71ed6a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
| @@ -581,10 +581,8 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
| 581 | obj->filp->f_op = &exynos_drm_gem_fops; | 581 | obj->filp->f_op = &exynos_drm_gem_fops; |
| 582 | obj->filp->private_data = obj; | 582 | obj->filp->private_data = obj; |
| 583 | 583 | ||
| 584 | down_write(¤t->mm->mmap_sem); | 584 | addr = vm_mmap(obj->filp, 0, args->size, |
| 585 | addr = do_mmap(obj->filp, 0, args->size, | ||
| 586 | PROT_READ | PROT_WRITE, MAP_SHARED, 0); | 585 | PROT_READ | PROT_WRITE, MAP_SHARED, 0); |
| 587 | up_write(¤t->mm->mmap_sem); | ||
| 588 | 586 | ||
| 589 | drm_gem_object_unreference_unlocked(obj); | 587 | drm_gem_object_unreference_unlocked(obj); |
| 590 | 588 | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index b85337f06fbf..a4ba453b3d27 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
| @@ -129,6 +129,7 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) | |||
| 129 | if (buf_priv->currently_mapped == | ||
