d00f751cdcdab1e587a9816da9ed3b55e5aeb2a4
[openwrt/staging/chunkeey.git] / target / linux / generic / patches-3.18 / 099-module_arch_freeing_init-new-hook-for-archs-before-m.patch
1 From: Rusty Russell <rusty@rustcorp.com.au>
2 Date: Tue, 20 Jan 2015 09:07:04 +1030
3 Subject: [PATCH] module_arch_freeing_init(): new hook for archs before module->module_init freed.
4
5 Archs have been abusing module_free() to clean up their arch-specific
6 allocations. Since module_free() is also (ab)used by BPF and trace code,
7 let's keep it to simple allocations, and provide a hook called before
8 that.
9
10 This means that avr32, ia64, parisc and s390 no longer need to implement
11 their own module_free() at all. avr32 doesn't need module_finalize()
12 either.
13
14 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
15 Cc: Chris Metcalf <cmetcalf@ezchip.com>
16 Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
17 Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
18 Cc: Tony Luck <tony.luck@intel.com>
19 Cc: Fenghua Yu <fenghua.yu@intel.com>
20 Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
21 Cc: Helge Deller <deller@gmx.de>
22 Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
23 Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
24 Cc: linux-kernel@vger.kernel.org
25 Cc: linux-ia64@vger.kernel.org
26 Cc: linux-parisc@vger.kernel.org
27 Cc: linux-s390@vger.kernel.org
28
29 Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=d453cded05ee219b77815ea194dc36efa5398bca
30 ---
31 arch/avr32/kernel/module.c | 13 +------------
32 arch/ia64/kernel/module.c | 6 ++----
33 arch/parisc/kernel/module.c | 6 +-----
34 arch/s390/kernel/module.c | 10 +++-------
35 arch/tile/kernel/module.c | 2 +-
36 include/linux/moduleloader.h | 2 ++
37 kernel/module.c | 7 +++++++
38 7 files changed, 17 insertions(+), 29 deletions(-)
39
40 --- a/arch/avr32/kernel/module.c
41 +++ b/arch/avr32/kernel/module.c
42 @@ -19,12 +19,10 @@
43 #include <linux/moduleloader.h>
44 #include <linux/vmalloc.h>
45
46 -void module_free(struct module *mod, void *module_region)
47 +void module_arch_freeing_init(struct module *mod)
48 {
49 vfree(mod->arch.syminfo);
50 mod->arch.syminfo = NULL;
51 -
52 - vfree(module_region);
53 }
54
55 static inline int check_rela(Elf32_Rela *rela, struct module *module,
56 @@ -291,12 +289,3 @@ int apply_relocate_add(Elf32_Shdr *sechd
57
58 return ret;
59 }
60 -
61 -int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
62 - struct module *module)
63 -{
64 - vfree(module->arch.syminfo);
65 - module->arch.syminfo = NULL;
66 -
67 - return 0;
68 -}
69 --- a/arch/ia64/kernel/module.c
70 +++ b/arch/ia64/kernel/module.c
71 @@ -305,14 +305,12 @@ plt_target (struct plt_entry *plt)
72 #endif /* !USE_BRL */
73
74 void
75 -module_free (struct module *mod, void *module_region)
76 +module_arch_freeing_init (struct module *mod)
77 {
78 - if (mod && mod->arch.init_unw_table &&
79 - module_region == mod->module_init) {
80 + if (mod->arch.init_unw_table) {
81 unw_remove_unwind_table(mod->arch.init_unw_table);
82 mod->arch.init_unw_table = NULL;
83 }
84 - vfree(module_region);
85 }
86
87 /* Have we already seen one of these relocations? */
88 --- a/arch/parisc/kernel/module.c
89 +++ b/arch/parisc/kernel/module.c
90 @@ -298,14 +298,10 @@ static inline unsigned long count_stubs(
91 }
92 #endif
93
94 -
95 -/* Free memory returned from module_alloc */
96 -void module_free(struct module *mod, void *module_region)
97 +void module_arch_freeing_init(struct module *mod)
98 {
99 kfree(mod->arch.section);
100 mod->arch.section = NULL;
101 -
102 - vfree(module_region);
103 }
104
105 /* Additional bytes needed in front of individual sections */
106 --- a/arch/s390/kernel/module.c
107 +++ b/arch/s390/kernel/module.c
108 @@ -55,14 +55,10 @@ void *module_alloc(unsigned long size)
109 }
110 #endif
111
112 -/* Free memory returned from module_alloc */
113 -void module_free(struct module *mod, void *module_region)
114 +void module_arch_freeing_init(struct module *mod)
115 {
116 - if (mod) {
117 - vfree(mod->arch.syminfo);
118 - mod->arch.syminfo = NULL;
119 - }
120 - vfree(module_region);
121 + vfree(mod->arch.syminfo);
122 + mod->arch.syminfo = NULL;
123 }
124
125 static void check_rela(Elf_Rela *rela, struct module *me)
126 --- a/arch/tile/kernel/module.c
127 +++ b/arch/tile/kernel/module.c
128 @@ -83,7 +83,7 @@ void module_free(struct module *mod, voi
129 0, 0, 0, NULL, NULL, 0);
130
131 /*
132 - * FIXME: If module_region == mod->module_init, trim exception
133 + * FIXME: Add module_arch_freeing_init to trim exception
134 * table entries.
135 */
136 }
137 --- a/include/linux/moduleloader.h
138 +++ b/include/linux/moduleloader.h
139 @@ -82,4 +82,6 @@ int module_finalize(const Elf_Ehdr *hdr,
140 /* Any cleanup needed when module leaves. */
141 void module_arch_cleanup(struct module *mod);
142
143 +/* Any cleanup before freeing mod->module_init */
144 +void module_arch_freeing_init(struct module *mod);
145 #endif
146 --- a/kernel/module.c
147 +++ b/kernel/module.c
148 @@ -1833,6 +1833,10 @@ void __weak module_arch_cleanup(struct m
149 {
150 }
151
152 +void __weak module_arch_freeing_init(struct module *mod)
153 +{
154 +}
155 +
156 /* Free a module, remove from lists, etc. */
157 static void free_module(struct module *mod)
158 {
159 @@ -1865,6 +1869,7 @@ static void free_module(struct module *m
160
161 /* This may be NULL, but that's OK */
162 unset_module_init_ro_nx(mod);
163 + module_arch_freeing_init(mod);
164 module_free(mod, mod->module_init);
165 kfree(mod->args);
166 percpu_modfree(mod);
167 @@ -2954,6 +2959,7 @@ static struct module *layout_and_allocat
168 static void module_deallocate(struct module *mod, struct load_info *info)
169 {
170 percpu_modfree(mod);
171 + module_arch_freeing_init(mod);
172 module_free(mod, mod->module_init);
173 module_free(mod, mod->module_core);
174 }
175 @@ -3077,6 +3083,7 @@ static int do_init_module(struct module
176 mod->strtab = mod->core_strtab;
177 #endif
178 unset_module_init_ro_nx(mod);
179 + module_arch_freeing_init(mod);
180 module_free(mod, mod->module_init);
181 mod->module_init = NULL;
182 mod->init_size = 0;