Open code it in __bpf_map_area_alloc, which is the only caller. Also clean up __bpf_map_area_alloc to have a single vmalloc call with slightly different flags instead of the current two different calls. For this to compile for the nommu case add a __vmalloc_node_range stub to nommu.c. [akpm@linux-foundation.org: fix nommu.c build] Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Christophe Leroy <christophe.leroy@c-s.fr> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: David Airlie <airlied@linux.ie> Cc: Gao Xiang <xiang@kernel.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Haiyang Zhang <haiyangz@microsoft.com> Cc: "K. Y. Srinivasan" <kys@microsoft.com> Cc: Laura Abbott <labbott@redhat.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Kelley <mikelley@microsoft.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Nitin Gupta <ngupta@vflare.org> Cc: Robin Murphy <robin.murphy@arm.com> Cc: Sakari Ailus <sakari.ailus@linux.intel.com> Cc: Stephen Hemminger <sthemmin@microsoft.com> Cc: Sumit Semwal <sumit.semwal@linaro.org> Cc: Wei Liu <wei.liu@kernel.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Paul Mackerras <paulus@ozlabs.org> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Will Deacon <will@kernel.org> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Link: http://lkml.kernel.org/r/20200414131348.444715-27-hch@lst.de Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Unified · Split
| @@ -106,7 +106,6 @@ extern void *vzalloc(unsigned long size); · 105 unmodified lines | |||
| 106 | extern void *vmalloc_user(unsigned long size); | 106 | extern void *vmalloc_user(unsigned long size); |
| 107 | extern void *vmalloc_node(unsigned long size, int node); | 107 | extern void *vmalloc_node(unsigned long size, int node); |
| 108 | extern void *vzalloc_node(unsigned long size, int node); | 108 | extern void *vzalloc_node(unsigned long size, int node); |
| 109 | extern void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags); | ||
| 110 | extern void *vmalloc_exec(unsigned long size); | 109 | extern void *vmalloc_exec(unsigned long size); |
| 111 | extern void *vmalloc_32(unsigned long size); | 110 | extern void *vmalloc_32(unsigned long size); |
| 112 | extern void *vmalloc_32_user(unsigned long size); | 111 | extern void *vmalloc_32_user(unsigned long size); |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | #include <linux/nospec.h> | 25 | #include <linux/nospec.h> |
| 26 | #include <linux/audit.h> | 26 | #include <linux/audit.h> |
| 27 | #include <uapi/linux/btf.h> | 27 | #include <uapi/linux/btf.h> |
| 28 | #include <asm/pgtable.h> | ||
| 28 | #include <linux/bpf_lsm.h> | 29 | #include <linux/bpf_lsm.h> |
| 29 | 30 | ||
| 30 | #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ | 31 | #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ |
| @@ -281,26 +282,29 @@ static void *__bpf_map_area_alloc(u64 size, int numa_node, bool mmapable) · 250 unmodified lines | |||
| 281 | * __GFP_RETRY_MAYFAIL to avoid such situations. | 282 | * __GFP_RETRY_MAYFAIL to avoid such situations. |
| 282 | */ | 283 | */ |
| 283 | 284 | ||
| 284 | const gfp_t flags = __GFP_NOWARN | __GFP_ZERO; | 285 | const gfp_t gfp = __GFP_NOWARN | __GFP_ZERO; |
| 286 | unsigned int flags = 0; | ||
| 287 | unsigned long align = 1; | ||
| 285 | void *area; | 288 | void *area; |
| 286 | 289 | ||
| 287 | if (size >= SIZE_MAX) | 290 | if (size >= SIZE_MAX) |
| 288 | return NULL; | 291 | return NULL; |
| 289 | 292 | ||
| 290 | /* kmalloc()'ed memory can't be mmap()'ed */ | 293 | /* kmalloc()'ed memory can't be mmap()'ed */ |
| 291 | if (!mmapable && size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { | 294 | if (mmapable) { |
| 292 | area = kmalloc_node(size, GFP_USER | __GFP_NORETRY | flags, | 295 | BUG_ON(!PAGE_ALIGNED(size)); |
| 296 | align = SHMLBA; | ||
| 297 | flags = VM_USERMAP; | ||
| 298 | } else if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { | ||
| 299 | area = kmalloc_node(size, gfp | GFP_USER | __GFP_NORETRY, | ||
| 293 | numa_node); | 300 | numa_node); |
| 294 | if (area != NULL) | 301 | if (area != NULL) |
| 295 | return area; | 302 | return area; |
| 296 | } | 303 | } |
| 297 | if (mmapable) { | 304 | |
| 298 | BUG_ON(!PAGE_ALIGNED(size)); | 305 | return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END, |
| 299 | return vmalloc_user_node_flags(size, numa_node, GFP_KERNEL | | 306 | gfp | GFP_KERNEL | __GFP_RETRY_MAYFAIL, PAGE_KERNEL, |
| 300 | __GFP_RETRY_MAYFAIL | flags); | 307 | flags, numa_node, __builtin_return_address(0)); |
| 301 | } | ||
| 302 | return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_RETRY_MAYFAIL | flags, | ||
| 303 | numa_node, __builtin_return_address(0)); | ||
| 304 | } | 308 | } |
| 305 | 309 | ||
| 306 | void *bpf_map_area_alloc(u64 size, int numa_node) | 310 | void *bpf_map_area_alloc(u64 size, int numa_node) |
| @@ -150,6 +150,14 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask) · 149 unmodified lines | |||
| 150 | } | 150 | } |
| 151 | EXPORT_SYMBOL(__vmalloc); | 151 | EXPORT_SYMBOL(__vmalloc); |
| 152 | 152 | ||
| 153 | void *__vmalloc_node_range(unsigned long size, unsigned long align, | ||
| 154 | unsigned long start, unsigned long end, gfp_t gfp_mask, | ||
| 155 | pgprot_t prot, unsigned long vm_flags, int node, | ||
| 156 | const void *caller) | ||
| 157 | { | ||
| 158 | return __vmalloc(size, gfp_mask); | ||
| 159 | } | ||
| 160 | |||
| 153 | void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask, | 161 | void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask, |
| 154 | int node, const void *caller) | 162 | int node, const void *caller) |
| 155 | { | 163 | { |
| @@ -180,12 +188,6 @@ void *vmalloc_user(unsigned long size) · 24 unmodified lines | |||
| 180 | } | 188 | } |
| 181 | EXPORT_SYMBOL(vmalloc_user); | 189 | EXPORT_SYMBOL(vmalloc_user); |
| 182 | 190 | ||
| 183 | void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags) | ||
| 184 | { | ||
| 185 | return __vmalloc_user_flags(size, flags | __GFP_ZERO); | ||
| 186 | } | ||
| 187 | EXPORT_SYMBOL(vmalloc_user_node_flags); | ||
| 188 | |||
| 189 | struct page *vmalloc_to_page(const void *addr) | 191 | struct page *vmalloc_to_page(const void *addr) |
| 190 | { | 192 | { |
| 191 | return virt_to_page(addr); | 193 | return virt_to_page(addr); |
| @@ -2659,26 +2659,6 @@ void *vzalloc_node(unsigned long size, int node) · 2658 unmodified lines | |||
| 2659 | } | 2659 | } |
| 2660 | EXPORT_SYMBOL(vzalloc_node); | 2660 | EXPORT_SYMBOL(vzalloc_node); |
| 2661 | 2661 | ||
| 2662 | /** | ||
| 2663 | * vmalloc_user_node_flags - allocate memory for userspace on a specific node | ||
| 2664 | * @size: allocation size | ||
| 2665 | * @node: numa node | ||
| 2666 | * @flags: flags for the page level allocator | ||
| 2667 | * | ||
| 2668 | * The resulting memory area is zeroed so it can be mapped to userspace | ||
| 2669 | * without leaking data. | ||
| 2670 | * | ||
| 2671 | * Return: pointer to the allocated memory or %NULL on error | ||
| 2672 | */ | ||
| 2673 | void *vmalloc_user_node_flags(unsigned long size, int node, gfp_t flags) | ||
| 2674 | { | ||
| 2675 | return __vmalloc_node_range(size, SHMLBA, VMALLOC_START, VMALLOC_END, | ||
| 2676 | flags | __GFP_ZERO, PAGE_KERNEL, | ||
| 2677 | VM_USERMAP, node, | ||
| 2678 | __builtin_return_address(0)); | ||
| 2679 | } | ||
| 2680 | EXPORT_SYMBOL(vmalloc_user_node_flags); | ||
| 2681 | |||
| 2682 | /** | 2662 | /** |
| 2683 | * vmalloc_exec - allocate virtually contiguous, executable memory | 2663 | * vmalloc_exec - allocate virtually contiguous, executable memory |
| 2684 | * @size: allocation size | 2664 | * @size: allocation size |