Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc/mm: Use generic_get_unmapped_area() and call it from arch_get_unmapped_area()

Use the generic version of arch_get_unmapped_area() which
is now available at all time instead of its copy
radix__arch_get_unmapped_area()

To allow that for PPC64, add arch_get_mmap_base() and
arch_get_mmap_end() macros.

Instead of setting mm->get_unmapped_area() to either
arch_get_unmapped_area() or generic_get_unmapped_area(),
always set it to arch_get_unmapped_area() and call
generic_get_unmapped_area() from there when radix is enabled.

Do the same with radix__arch_get_unmapped_area_topdown()

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/393be1fa386446443682fdb74544d733f68ef3bb.1649523076.git.christophe.leroy@csgroup.eu

authored by

Christophe Leroy and committed by
Michael Ellerman
76a345ed f693d38d

+14 -121
+8
arch/powerpc/include/asm/task_size_64.h
··· 72 72 #define STACK_TOP_MAX TASK_SIZE_USER64 73 73 #define STACK_TOP (is_32bit_task() ? STACK_TOP_USER32 : STACK_TOP_USER64) 74 74 75 + #define arch_get_mmap_base(addr, base) \ 76 + (((addr) > DEFAULT_MAP_WINDOW) ? (base) + TASK_SIZE - DEFAULT_MAP_WINDOW : (base)) 77 + 78 + #define arch_get_mmap_end(addr, len, flags) \ 79 + (((addr) > DEFAULT_MAP_WINDOW) || \ 80 + (((flags) & MAP_FIXED) && ((addr) + (len) > DEFAULT_MAP_WINDOW)) ? TASK_SIZE : \ 81 + DEFAULT_MAP_WINDOW) 82 + 75 83 #endif /* _ASM_POWERPC_TASK_SIZE_64_H */
+6 -121
arch/powerpc/mm/mmap.c
··· 81 81 } 82 82 83 83 #ifdef HAVE_ARCH_UNMAPPED_AREA 84 - #ifdef CONFIG_PPC_RADIX_MMU 85 - /* 86 - * Same function as generic code used only for radix, because we don't need to overload 87 - * the generic one. But we will have to duplicate, because hash select 88 - * HAVE_ARCH_UNMAPPED_AREA 89 - */ 90 - static unsigned long 91 - radix__arch_get_unmapped_area(struct file *filp, unsigned long addr, 92 - unsigned long len, unsigned long pgoff, 93 - unsigned long flags) 94 - { 95 - struct mm_struct *mm = current->mm; 96 - struct vm_area_struct *vma; 97 - int fixed = (flags & MAP_FIXED); 98 - unsigned long high_limit; 99 - struct vm_unmapped_area_info info; 100 - 101 - high_limit = DEFAULT_MAP_WINDOW; 102 - if (addr >= high_limit || (fixed && (addr + len > high_limit))) 103 - high_limit = TASK_SIZE; 104 - 105 - if (len > high_limit) 106 - return -ENOMEM; 107 - 108 - if (fixed) { 109 - if (addr > high_limit - len) 110 - return -ENOMEM; 111 - return addr; 112 - } 113 - 114 - if (addr) { 115 - addr = PAGE_ALIGN(addr); 116 - vma = find_vma(mm, addr); 117 - if (high_limit - len >= addr && addr >= mmap_min_addr && 118 - (!vma || addr + len <= vm_start_gap(vma))) 119 - return addr; 120 - } 121 - 122 - info.flags = 0; 123 - info.length = len; 124 - info.low_limit = mm->mmap_base; 125 - info.high_limit = high_limit; 126 - info.align_mask = 0; 127 - 128 - return vm_unmapped_area(&info); 129 - } 130 - 131 - static unsigned long 132 - radix__arch_get_unmapped_area_topdown(struct file *filp, 133 - const unsigned long addr0, 134 - const unsigned long len, 135 - const unsigned long pgoff, 136 - const unsigned long flags) 137 - { 138 - struct vm_area_struct *vma; 139 - struct mm_struct *mm = current->mm; 140 - unsigned long addr = addr0; 141 - int fixed = (flags & MAP_FIXED); 142 - unsigned long high_limit; 143 - struct vm_unmapped_area_info info; 144 - 145 - high_limit = DEFAULT_MAP_WINDOW; 146 - if (addr >= high_limit || (fixed && (addr + len > high_limit))) 147 - high_limit = TASK_SIZE; 148 - 149 - if (len > high_limit) 150 - return -ENOMEM; 151 - 152 - if (fixed) { 153 - if (addr > high_limit - len) 154 - return -ENOMEM; 155 - return addr; 156 - } 157 - 158 - if (addr) { 159 - addr = PAGE_ALIGN(addr); 160 - vma = find_vma(mm, addr); 161 - if (high_limit - len >= addr && addr >= mmap_min_addr && 162 - (!vma || addr + len <= vm_start_gap(vma))) 163 - return addr; 164 - } 165 - 166 - info.flags = VM_UNMAPPED_AREA_TOPDOWN; 167 - info.length = len; 168 - info.low_limit = max(PAGE_SIZE, mmap_min_addr); 169 - info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW); 170 - info.align_mask = 0; 171 - 172 - addr = vm_unmapped_area(&info); 173 - if (!(addr & ~PAGE_MASK)) 174 - return addr; 175 - VM_BUG_ON(addr != -ENOMEM); 176 - 177 - /* 178 - * A failed mmap() very likely causes application failure, 179 - * so fall back to the bottom-up function here. This scenario 180 - * can happen with large stack limits and large mmap() 181 - * allocations. 182 - */ 183 - return radix__arch_get_unmapped_area(filp, addr0, len, pgoff, flags); 184 - } 185 - #endif 186 - 187 84 unsigned long arch_get_unmapped_area(struct file *filp, 188 85 unsigned long addr, 189 86 unsigned long len, 190 87 unsigned long pgoff, 191 88 unsigned long flags) 192 89 { 90 + if (radix_enabled()) 91 + return generic_get_unmapped_area(filp, addr, len, pgoff, flags); 92 + 193 93 #ifdef CONFIG_PPC_64S_HASH_MMU 194 94 return slice_get_unmapped_area(addr, len, flags, 195 95 mm_ctx_user_psize(&current->mm->context), 0); ··· 104 204 const unsigned long pgoff, 105 205 const unsigned long flags) 106 206 { 207 + if (radix_enabled()) 208 + return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags); 209 + 107 210 #ifdef CONFIG_PPC_64S_HASH_MMU 108 211 return slice_get_unmapped_area(addr0, len, flags, 109 212 mm_ctx_user_psize(&current->mm->context), 1); ··· 115 212 #endif 116 213 } 117 214 #endif /* HAVE_ARCH_UNMAPPED_AREA */ 118 - 119 - static void radix__arch_pick_mmap_layout(struct mm_struct *mm, 120 - unsigned long random_factor, 121 - struct rlimit *rlim_stack) 122 - { 123 - #ifdef CONFIG_PPC_RADIX_MMU 124 - if (mmap_is_legacy(rlim_stack)) { 125 - mm->mmap_base = TASK_UNMAPPED_BASE; 126 - mm->get_unmapped_area = radix__arch_get_unmapped_area; 127 - } else { 128 - mm->mmap_base = mmap_base(random_factor, rlim_stack); 129 - mm->get_unmapped_area = radix__arch_get_unmapped_area_topdown; 130 - } 131 - #endif 132 - } 133 215 134 216 /* 135 217 * This function, called very early during the creation of a new ··· 127 239 if (current->flags & PF_RANDOMIZE) 128 240 random_factor = arch_mmap_rnd(); 129 241 130 - if (radix_enabled()) 131 - return radix__arch_pick_mmap_layout(mm, random_factor, 132 - rlim_stack); 133 242 /* 134 243 * Fall back to the standard layout if the personality 135 244 * bit is set, or if the expected stack growth is unlimited: