aboutsummaryrefslogtreecommitdiffstats
path: root/mm/nommu.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds_cb1@t-online.de>2010-05-26 02:43:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-26 11:19:23 -0400
commit3c7b204547bc3d342a4e31196fe14803581d279f (patch)
tree87a3300d266eed413012efd0a985a72caad4a856 /mm/nommu.c
parent0cae3457b1a6e88f31020272bcfd90c178716053 (diff)
nommu: allow private mappings of read-only devices
Slightly rearrange the logic that determines capabilities and vm_flags. Disable BDI_CAP_MAP_DIRECT in all cases if the device can't support the protections. Allow private readonly mappings of readonly backing devices. Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Acked-by: David McCullough <davidm@snapgear.com> Acked-by: Greg Ungerer <gerg@uclinux.org> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: David Howells <dhowells@redhat.com> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/nommu.c')
-rw-r--r--mm/nommu.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/mm/nommu.c b/mm/nommu.c
index 63fa17d121f..b76f3ee0abe 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -918,14 +918,6 @@ static int validate_mmap_request(struct file *file,
918 if (!(capabilities & BDI_CAP_MAP_DIRECT)) 918 if (!(capabilities & BDI_CAP_MAP_DIRECT))
919 return -ENODEV; 919 return -ENODEV;
920 920
921 if (((prot & PROT_READ) && !(capabilities & BDI_CAP_READ_MAP)) ||
922 ((prot & PROT_WRITE) && !(capabilities & BDI_CAP_WRITE_MAP)) ||
923 ((prot & PROT_EXEC) && !(capabilities & BDI_CAP_EXEC_MAP))
924 ) {
925 printk("MAP_SHARED not completely supported on !MMU\n");
926 return -EINVAL;
927 }
928
929 /* we mustn't privatise shared mappings */ 921 /* we mustn't privatise shared mappings */
930 capabilities &= ~BDI_CAP_MAP_COPY; 922 capabilities &= ~BDI_CAP_MAP_COPY;
931 } 923 }
@@ -941,6 +933,20 @@ static int validate_mmap_request(struct file *file,
941 capabilities &= ~BDI_CAP_MAP_DIRECT; 933 capabilities &= ~BDI_CAP_MAP_DIRECT;
942 } 934 }
943 935
936 if (capabilities & BDI_CAP_MAP_DIRECT) {
937 if (((prot & PROT_READ) && !(capabilities & BDI_CAP_READ_MAP)) ||
938 ((prot & PROT_WRITE) && !(capabilities & BDI_CAP_WRITE_MAP)) ||
939 ((prot & PROT_EXEC) && !(capabilities & BDI_CAP_EXEC_MAP))
940 ) {
941 capabilities &= ~BDI_CAP_MAP_DIRECT;
942 if (flags & MAP_SHARED) {
943 printk(KERN_WARNING
944 "MAP_SHARED not completely supported on !MMU\n");
945 return -EINVAL;
946 }
947 }
948 }
949
944 /* handle executable mappings and implied executable 950 /* handle executable mappings and implied executable
945 * mappings */ 951 * mappings */
946 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) { 952 if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
@@ -996,22 +1002,20 @@ static unsigned long determine_vm_flags(struct file *file,
996 unsigned long vm_flags; 1002 unsigned long vm_flags;
997 1003
998 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags); 1004 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags);
999 vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
1000 /* vm_flags |= mm->def_flags; */ 1005 /* vm_flags |= mm->def_flags; */
1001 1006
1002 if (!(capabilities & BDI_CAP_MAP_DIRECT)) { 1007 if (!(capabilities & BDI_CAP_MAP_DIRECT)) {
1003 /* attempt to share read-only copies of mapped file chunks */ 1008 /* attempt to share read-only copies of mapped file chunks */
1009 vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
1004 if (file && !(prot & PROT_WRITE)) 1010 if (file && !(prot & PROT_WRITE))
1005 vm_flags |= VM_MAYSHARE; 1011 vm_flags |= VM_MAYSHARE;
1006 } 1012 } else {
1007 else {
1008 /* overlay a shareable mapping on the backing device or inode 1013 /* overlay a shareable mapping on the backing device or inode
1009 * if possible - used for chardevs, ramfs/tmpfs/shmfs and 1014 * if possible - used for chardevs, ramfs/tmpfs/shmfs and
1010 * romfs/cramfs */ 1015 * romfs/cramfs */
1016 vm_flags |= VM_MAYSHARE | (capabilities & BDI_CAP_VMFLAGS);
1011 if (flags & MAP_SHARED) 1017 if (flags & MAP_SHARED)
1012 vm_flags |= VM_MAYSHARE | VM_SHARED; 1018 vm_flags |= VM_SHARED;
1013 else if ((((vm_flags & capabilities) ^ vm_flags) & BDI_CAP_VMFLAGS) == 0)
1014 vm_flags |= VM_MAYSHARE;
1015 } 1019 }
1016 1020
1017 /* refuse to let anyone share private mappings with this process if 1021 /* refuse to let anyone share private mappings with this process if