aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2015-09-09 18:39:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-10 16:29:01 -0400
commit1fcfd8db7f82fa1f533a6f0e4155614ff4144d56 (patch)
tree958b38ccd3bdd3bc97de154bf7bf322ff09637db
parent7cbea8dc0127a95226c7722a738ac6534950ef67 (diff)
mm, mpx: add "vm_flags_t vm_flags" arg to do_mmap_pgoff()
Add the additional "vm_flags_t vm_flags" argument to do_mmap_pgoff(), rename it to do_mmap(), and re-introduce do_mmap_pgoff() as a simple wrapper on top of do_mmap(). Perhaps we should update the callers of do_mmap_pgoff() and kill it later. This way mpx_mmap() can simply call do_mmap(vm_flags => VM_MPX) and do not play with vm internals. After this change mmap_region() has a single user outside of mmap.c, arch/tile/mm/elf.c:arch_setup_additional_pages(). It would be nice to change arch/tile/ and unexport mmap_region(). [kirill@shutemov.name: fix build] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> Tested-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Ingo Molnar <mingo@elte.hu> Cc: Minchan Kim <minchan@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/mm/mpx.c51
-rw-r--r--include/linux/mm.h12
-rw-r--r--mm/mmap.c10
-rw-r--r--mm/nommu.c19
4 files changed, 31 insertions, 61 deletions
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index db1b0bc5017c..134948b0926f 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -42,58 +42,21 @@ static inline unsigned long mpx_bt_size_bytes(struct mm_struct *mm)
42 */ 42 */
43static unsigned long mpx_mmap(unsigned long len) 43static unsigned long mpx_mmap(unsigned long len)
44{ 44{
45 unsigned long ret;
46 unsigned long addr, pgoff;
47 struct mm_struct *mm = current->mm; 45 struct mm_struct *mm = current->mm;
48 vm_flags_t vm_flags; 46 unsigned long addr, populate;
49 struct vm_area_struct *vma;
50 47
51 /* Only bounds table can be allocated here */ 48 /* Only bounds table can be allocated here */
52 if (len != mpx_bt_size_bytes(mm)) 49 if (len != mpx_bt_size_bytes(mm))
53 return -EINVAL; 50 return -EINVAL;
54 51
55 down_write(&mm->mmap_sem); 52 down_write(&mm->mmap_sem);
56 53 addr = do_mmap(NULL, 0, len, PROT_READ | PROT_WRITE,
57 /* Too many mappings? */ 54 MAP_ANONYMOUS | MAP_PRIVATE, VM_MPX, 0, &populate);
58 if (mm->map_count > sysctl_max_map_count) {
59 ret = -ENOMEM;
60 goto out;
61 }
62
63 /* Obtain the address to map to. we verify (or select) it and ensure
64 * that it represents a valid section of the address space.
65 */
66 addr = get_unmapped_area(NULL, 0, len, 0, MAP_ANONYMOUS | MAP_PRIVATE);
67 if (addr & ~PAGE_MASK) {
68 ret = addr;
69 goto out;
70 }
71
72 vm_flags = VM_READ | VM_WRITE | VM_MPX |
73 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
74
75 /* Set pgoff according to addr for anon_vma */
76 pgoff = addr >> PAGE_SHIFT;
77
78 ret = mmap_region(NULL, addr, len, vm_flags, pgoff);
79 if (IS_ERR_VALUE(ret))
80 goto out;
81
82 vma = find_vma(mm, ret);
83 if (!vma) {
84 ret = -ENOMEM;
85 goto out;
86 }
87
88 if (vm_flags & VM_LOCKED) {
89 up_write(&mm->mmap_sem);
90 mm_populate(ret, len);
91 return ret;
92 }
93
94out:
95 up_write(&mm->mmap_sem); 55 up_write(&mm->mmap_sem);
96 return ret; 56 if (populate)
57 mm_populate(addr, populate);
58
59 return addr;
97} 60}
98 61
99enum reg_type { 62enum reg_type {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f25a957bf0ab..fda728e3c27d 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1873,11 +1873,19 @@ extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned lo
1873 1873
1874extern unsigned long mmap_region(struct file *file, unsigned long addr, 1874extern unsigned long mmap_region(struct file *file, unsigned long addr,
1875 unsigned long len, vm_flags_t vm_flags, unsigned long pgoff); 1875 unsigned long len, vm_flags_t vm_flags, unsigned long pgoff);
1876extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, 1876extern unsigned long do_mmap(struct file *file, unsigned long addr,
1877 unsigned long len, unsigned long prot, unsigned long flags, 1877 unsigned long len, unsigned long prot, unsigned long flags,
1878 unsigned long pgoff, unsigned long *populate); 1878 vm_flags_t vm_flags, unsigned long pgoff, unsigned long *populate);
1879extern int do_munmap(struct mm_struct *, unsigned long, size_t); 1879extern int do_munmap(struct mm_struct *, unsigned long, size_t);
1880 1880
1881static inline unsigned long
1882do_mmap_pgoff(struct file *file, unsigned long addr,
1883 unsigned long len, unsigned long prot, unsigned long flags,
1884 unsigned long pgoff, unsigned long *populate)
1885{
1886 return do_mmap(file, addr, len, prot, flags, 0, pgoff, populate);
1887}
1888
1881#ifdef CONFIG_MMU 1889#ifdef CONFIG_MMU
1882extern int __mm_populate(unsigned long addr, unsigned long len, 1890extern int __mm_populate(unsigned long addr, unsigned long len,
1883 int ignore_errors); 1891 int ignore_errors);
diff --git a/mm/mmap.c b/mm/mmap.c
index b6be3249f0a9..c739d6db7193 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1260,14 +1260,12 @@ static inline int mlock_future_check(struct mm_struct *mm,
1260/* 1260/*
1261 * The caller must hold down_write(&current->mm->mmap_sem). 1261 * The caller must hold down_write(&current->mm->mmap_sem).
1262 */ 1262 */
1263 1263unsigned long do_mmap(struct file *file, unsigned long addr,
1264unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
1265 unsigned long len, unsigned long prot, 1264 unsigned long len, unsigned long prot,
1266 unsigned long flags, unsigned long pgoff, 1265 unsigned long flags, vm_flags_t vm_flags,
1267 unsigned long *populate) 1266 unsigned long pgoff, unsigned long *populate)
1268{ 1267{
1269 struct mm_struct *mm = current->mm; 1268 struct mm_struct *mm = current->mm;
1270 vm_flags_t vm_flags;
1271 1269
1272 *populate = 0; 1270 *populate = 0;
1273 1271
@@ -1311,7 +1309,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
1311 * to. we assume access permissions have been handled by the open 1309 * to. we assume access permissions have been handled by the open
1312 * of the memory object, so we don't do any here. 1310 * of the memory object, so we don't do any here.
1313 */ 1311 */
1314 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | 1312 vm_flags |= calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
1315 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; 1313 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
1316 1314
1317 if (flags & MAP_LOCKED) 1315 if (flags & MAP_LOCKED)
diff --git a/mm/nommu.c b/mm/nommu.c
index 1cc0709fcaa5..ab14a2014dea 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1233,18 +1233,19 @@ enomem:
1233/* 1233/*
1234 * handle mapping creation for uClinux 1234 * handle mapping creation for uClinux
1235 */ 1235 */
1236unsigned long do_mmap_pgoff(struct file *file, 1236unsigned long do_mmap(struct file *file,
1237 unsigned long addr, 1237 unsigned long addr,
1238 unsigned long len, 1238 unsigned long len,
1239 unsigned long prot, 1239 unsigned long prot,
1240 unsigned long flags, 1240 unsigned long flags,
1241 unsigned long pgoff, 1241 vm_flags_t vm_flags,
1242 unsigned long *populate) 1242 unsigned long pgoff,
1243 unsigned long *populate)
1243{ 1244{
1244 struct vm_area_struct *vma; 1245 struct vm_area_struct *vma;
1245 struct vm_region *region; 1246 struct vm_region *region;
1246 struct rb_node *rb; 1247 struct rb_node *rb;
1247 unsigned long capabilities, vm_flags, result; 1248 unsigned long capabilities, result;
1248 int ret; 1249 int ret;
1249 1250
1250 *populate = 0; 1251 *populate = 0;
@@ -1262,7 +1263,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1262 1263
1263 /* we've determined that we can make the mapping, now translate what we 1264 /* we've determined that we can make the mapping, now translate what we
1264 * now know into VMA flags */ 1265 * now know into VMA flags */
1265 vm_flags = determine_vm_flags(file, prot, flags, capabilities); 1266 vm_flags |= determine_vm_flags(file, prot, flags, capabilities);
1266 1267
1267 /* we're going to need to record the mapping */ 1268 /* we're going to need to record the mapping */
1268 region = kmem_cache_zalloc(vm_region_jar, GFP_KERNEL); 1269 region = kmem_cache_zalloc(vm_region_jar, GFP_KERNEL);