[patch 06/14] remap_file_pages protection support: enhance syscall interface



From: Ingo Molnar <mingo@xxxxxxx>, Paolo 'Blaisorblade' Giarrusso <blaisorblade@xxxxxxxx>

Enable the 'prot' parameter for shared-writable mappings (the ones which are
the primary target for remap_file_pages), without breaking up the vma.

This contains simply the changes to the syscall code, based on Ingo's patch.
Differently from his one, I've *not* added a new syscall, choosing to add a
new flag (MAP_CHGPROT) which the application must specify to get the new
behavior (prot != 0 is accepted and prot == 0 means PROT_NONE).

Upon Hugh's suggestion, simplify the permission checking on the VMA, reusing
mprotect()'s trick.

Index: linux-2.6.git/mm/fremap.c
===================================================================
--- linux-2.6.git.orig/mm/fremap.c
+++ linux-2.6.git/mm/fremap.c
@@ -4,6 +4,10 @@
* Explicit pagetable population and nonlinear (random) mappings support.
*
* started by Ingo Molnar, Copyright (C) 2002, 2003
+ *
+ * support of nonuniform remappings:
+ * Copyright (C) 2004 Ingo Molnar
+ * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso
*/

#include <linux/mm.h>
@@ -126,18 +130,14 @@ out:
* file within an existing vma.
* @start: start of the remapped virtual memory range
* @size: size of the remapped virtual memory range
- * @prot: new protection bits of the range
+ * @prot: new protection bits of the range, must be 0 if not using MAP_CHGPROT
* @pgoff: to be mapped page of the backing store file
- * @flags: 0 or MAP_NONBLOCKED - the later will cause no IO.
+ * @flags: bits MAP_CHGPROT or MAP_NONBLOCKED - the later will cause no IO.
*
* this syscall works purely via pagetables, so it's the most efficient
* way to map the same (large) file into a given virtual window. Unlike
* mmap()/mremap() it does not create any new vmas. The new mappings are
* also safe across swapout.
- *
- * NOTE: the 'prot' parameter right now is ignored, and the vma's default
- * protection is used. Arbitrary protections might be implemented in the
- * future.
*/
asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
unsigned long prot, unsigned long pgoff, unsigned long flags)
@@ -150,7 +150,7 @@ asmlinkage long sys_remap_file_pages(uns
int has_write_lock = 0;
pgprot_t pgprot;

- if (prot)
+ if (prot && !(flags & MAP_CHGPROT))
goto out;
/*
* Sanitize the syscall parameters:
@@ -193,7 +193,19 @@ retry:
if (end <= start || start < vma->vm_start || end > vma->vm_end)
goto out_unlock;

- pgprot = vma->vm_page_prot;
+ if (flags & MAP_CHGPROT) {
+ unsigned long vm_prots = calc_vm_prot_bits(prot);
+
+ /* vma->vm_flags >> 4 shifts VM_MAY% in place of VM_% */
+ if ((vm_prots & ~(vma->vm_flags >> 4)) &
+ (VM_READ | VM_WRITE | VM_EXEC)) {
+ err = -EPERM;
+ goto out_unlock;
+ }
+
+ pgprot = protection_map[vm_prots | VM_SHARED];
+ } else
+ pgprot = vma->vm_page_prot;

if (!vma->vm_private_data || (vma->vm_flags & VM_NONLINEAR)) {
/* Must set VM_NONLINEAR before any pages are populated. */
@@ -215,6 +227,17 @@ retry:
spin_unlock(&mapping->i_mmap_lock);
}

+ if (pgprot_val(pgprot) != pgprot_val(vma->vm_page_prot) &&
+ !(vma->vm_flags & VM_MANYPROTS)) {
+ if (!has_write_lock) {
+ up_read(&mm->mmap_sem);
+ down_write(&mm->mmap_sem);
+ has_write_lock = 1;
+ goto retry;
+ }
+ vma->vm_flags |= VM_MANYPROTS;
+ }
+
err = vma->vm_ops->populate(vma, start, size, pgprot, pgoff,
flags & MAP_NONBLOCK);


--
Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!".
Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894)
http://www.user-mode-linux.org/~blaisorblade
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • [PATCH RFP-V4 07/13] RFP prot support: enhance syscall interface
    ... Enable the 'prot' parameter for shared-writable mappings (the ones which are ... This contains simply the changes to the syscall code, ... Upon Hugh's suggestion, simplify the permission checking on the VMA, reusing ... Explicit pagetable population and nonlinear mappings support. ...
    (Linux-Kernel)
  • Re: [git pull] drm patches for 2.6.27-rc1
    ... [The *non-atomic* kmapfunctions are fairly high-overhead, in that they want to keep track of cached mappings and remember page addresses etc. So those are the ones we don't want to support for non-HIGHMEM setups. ... Looking at it, it also looks like kmap_atomic_prot() is actually incorrect right now, and doesn't do a "prot" thing for ... Grand prize is a trip for two to an Open Source event anywhere in the world ...
    (Linux-Kernel)
  • [tip:x86/urgent] x86, PAT: Remove page granularity tracking for vm_insert_pfn maps
    ... Remove page level granularity track and untrack of vm_insert_pfn. ... If the vma has a linear pfn mapping for the entire range, we get the prot ... from pte and reserve the entire vma range with single reserve_pfn_range call. ...
    (Linux-Kernel)
  • [patch 090/100] x86, PAT: Remove page granularity tracking for vm_insert_pfn maps
    ... If the vma has a linear pfn mapping for the entire range, we get the prot ... from pte and reserve the entire vma range with single reserve_pfn_range call. ...
    (Linux-Kernel)
  • Re: [git pull] drm patches for 2.6.27-rc1
    ... int prot); ... The important thing is that mappings need to be per-CPU, ... trivial FIXMAP support. ...
    (Linux-Kernel)