aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Ryabinin <a.ryabinin@samsung.com>2015-02-13 17:40:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-14 00:21:42 -0500
commitcb9e3c292d0115499c660028ad35ac5501d722b5 (patch)
tree5345bc82199c3cd843ea36d34aadaa0894bdd340
parent71394fe50146202f2c8d92cf50f5ebc761acf254 (diff)
mm: vmalloc: pass additional vm_flags to __vmalloc_node_range()
For instrumenting global variables KASan will shadow memory backing memory for modules. So on module loading we will need to allocate memory for shadow and map it at address in shadow that corresponds to the address allocated in module_alloc(). __vmalloc_node_range() could be used for this purpose, except it puts a guard hole after allocated area. Guard hole in shadow memory should be a problem because at some future point we might need to have a shadow memory at address occupied by guard hole. So we could fail to allocate shadow for module_alloc(). Now we have VM_NO_GUARD flag disabling guard page, so we need to pass into __vmalloc_node_range(). Add new parameter 'vm_flags' to __vmalloc_node_range() function. Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Konstantin Serebryany <kcc@google.com> Cc: Dmitry Chernenkov <dmitryc@google.com> Signed-off-by: Andrey Konovalov <adech.fo@gmail.com> Cc: Yuri Gribov <tetra2005@gmail.com> Cc: Konstantin Khlebnikov <koct9i@gmail.com> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: Christoph Lameter <cl@linux.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm64/kernel/module.c4
-rw-r--r--arch/mips/kernel/module.c2
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/s390/kernel/module.c2
-rw-r--r--arch/sparc/kernel/module.c2
-rw-r--r--arch/unicore32/kernel/module.c2
-rw-r--r--arch/x86/kernel/module.c2
-rw-r--r--include/linux/vmalloc.h4
-rw-r--r--mm/vmalloc.c10
10 files changed, 18 insertions, 14 deletions
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index bea7db9e5b80..2e11961f65ae 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -41,7 +41,7 @@
41void *module_alloc(unsigned long size) 41void *module_alloc(unsigned long size)
42{ 42{
43 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, 43 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
44 GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, 44 GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
45 __builtin_return_address(0)); 45 __builtin_return_address(0));
46} 46}
47#endif 47#endif
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 9b6f71db2709..67bf4107f6ef 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -35,8 +35,8 @@
35void *module_alloc(unsigned long size) 35void *module_alloc(unsigned long size)
36{ 36{
37 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, 37 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
38 GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, 38 GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
39 __builtin_return_address(0)); 39 NUMA_NO_NODE, __builtin_return_address(0));
40} 40}
41 41
42enum aarch64_reloc_op { 42enum aarch64_reloc_op {
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index 2a52568dbcd6..1833f5171ccd 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -47,7 +47,7 @@ static DEFINE_SPINLOCK(dbe_lock);
47void *module_alloc(unsigned long size) 47void *module_alloc(unsigned long size)
48{ 48{
49 return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, 49 return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
50 GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, 50 GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
51 __builtin_return_address(0)); 51 __builtin_return_address(0));
52} 52}
53#endif 53#endif
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 5822e8e200e6..3c63a820fcda 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -219,7 +219,7 @@ void *module_alloc(unsigned long size)
219 * init_data correctly */ 219 * init_data correctly */
220 return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, 220 return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
221 GFP_KERNEL | __GFP_HIGHMEM, 221 GFP_KERNEL | __GFP_HIGHMEM,
222 PAGE_KERNEL_RWX, NUMA_NO_NODE, 222 PAGE_KERNEL_RWX, 0, NUMA_NO_NODE,
223 __builtin_return_address(0)); 223 __builtin_return_address(0));
224} 224}
225 225
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 409d152585be..36154a2f1814 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -50,7 +50,7 @@ void *module_alloc(unsigned long size)
50 if (PAGE_ALIGN(size) > MODULES_LEN) 50 if (PAGE_ALIGN(size) > MODULES_LEN)
51 return NULL; 51 return NULL;
52 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, 52 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
53 GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, 53 GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
54 __builtin_return_address(0)); 54 __builtin_return_address(0));
55} 55}
56#endif 56#endif
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index 97655e0fd243..192a617a32f3 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -29,7 +29,7 @@ static void *module_map(unsigned long size)
29 if (PAGE_ALIGN(size) > MODULES_LEN) 29 if (PAGE_ALIGN(size) > MODULES_LEN)
30 return NULL; 30 return NULL;
31 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, 31 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
32 GFP_KERNEL, PAGE_KERNEL, NUMA_NO_NODE, 32 GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
33 __builtin_return_address(0)); 33 __builtin_return_address(0));
34} 34}
35#else 35#else
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c
index dc41f6dfedb6..e191b3448bd3 100644
--- a/arch/unicore32/kernel/module.c
+++ b/arch/unicore32/kernel/module.c
@@ -25,7 +25,7 @@
25void *module_alloc(unsigned long size) 25void *module_alloc(unsigned long size)
26{ 26{
27 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, 27 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
28 GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, 28 GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
29 __builtin_return_address(0)); 29 __builtin_return_address(0));
30} 30}
31 31
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index e69f9882bf95..e830e61aae05 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -88,7 +88,7 @@ void *module_alloc(unsigned long size)
88 return __vmalloc_node_range(size, 1, 88 return __vmalloc_node_range(size, 1,
89 MODULES_VADDR + get_module_load_offset(), 89 MODULES_VADDR + get_module_load_offset(),
90 MODULES_END, GFP_KERNEL | __GFP_HIGHMEM, 90 MODULES_END, GFP_KERNEL | __GFP_HIGHMEM,
91 PAGE_KERNEL_EXEC, NUMA_NO_NODE, 91 PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
92 __builtin_return_address(0)); 92 __builtin_return_address(0));
93} 93}
94 94
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 1526fe712ca0..7d7acb35603d 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -76,7 +76,9 @@ extern void *vmalloc_32_user(unsigned long size);
76extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot); 76extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
77extern void *__vmalloc_node_range(unsigned long size, unsigned long align, 77extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
78 unsigned long start, unsigned long end, gfp_t gfp_mask, 78 unsigned long start, unsigned long end, gfp_t gfp_mask,
79 pgprot_t prot, int node, const void *caller); 79 pgprot_t prot, unsigned long vm_flags, int node,
80 const void *caller);
81
80extern void vfree(const void *addr); 82extern void vfree(const void *addr);
81 83
82extern void *vmap(struct page **pages, unsigned int count, 84extern void *vmap(struct page **pages, unsigned int count,
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2e74e99d4cfe..35b25e1340ca 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1619,6 +1619,7 @@ fail:
1619 * @end: vm area range end 1619 * @end: vm area range end
1620 * @gfp_mask: flags for the page level allocator 1620 * @gfp_mask: flags for the page level allocator
1621 * @prot: protection mask for the allocated pages 1621 * @prot: protection mask for the allocated pages
1622 * @vm_flags: additional vm area flags (e.g. %VM_NO_GUARD)
1622 * @node: node to use for allocation or NUMA_NO_NODE 1623 * @node: node to use for allocation or NUMA_NO_NODE
1623 * @caller: caller's return address 1624 * @caller: caller's return address
1624 * 1625 *
@@ -1628,7 +1629,8 @@ fail:
1628 */ 1629 */
1629void *__vmalloc_node_range(unsigned long size, unsigned long align, 1630void *__vmalloc_node_range(unsigned long size, unsigned long align,
1630 unsigned long start, unsigned long end, gfp_t gfp_mask, 1631 unsigned long start, unsigned long end, gfp_t gfp_mask,
1631 pgprot_t prot, int node, const void *caller) 1632 pgprot_t prot, unsigned long vm_flags, int node,
1633 const void *caller)
1632{ 1634{
1633 struct vm_struct *area; 1635 struct vm_struct *area;
1634 void *addr; 1636 void *addr;
@@ -1638,8 +1640,8 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
1638 if (!size || (size >> PAGE_SHIFT) > totalram_pages) 1640 if (!size || (size >> PAGE_SHIFT) > totalram_pages)
1639 goto fail; 1641 goto fail;
1640 1642
1641 area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED, 1643 area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED |
1642 start, end, node, gfp_mask, caller); 1644 vm_flags, start, end, node, gfp_mask, caller);
1643 if (!area) 1645 if (!area)
1644 goto fail; 1646 goto fail;
1645 1647
@@ -1688,7 +1690,7 @@ static void *__vmalloc_node(unsigned long size, unsigned long align,
1688 int node, const void *caller) 1690 int node, const void *caller)
1689{ 1691{
1690 return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END, 1692 return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
1691 gfp_mask, prot, node, caller); 1693 gfp_mask, prot, 0, node, caller);
1692} 1694}
1693 1695
1694void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) 1696void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)