]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/supported-flag
Changed checkfs to auto reboot after correctable fsck fixes.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / supported-flag
1 From: Andreas Gruenbacher <agruen@suse.de>
2 Subject: Novell/external support flag in modules
3
4 Upon module load, check if a module is supported, and set the
5 N (TAINT_NO_SUPPORT) or X (TAINT_EXTERNAL_SUPPORT) tail flags
6 for unsupported or externally suported modules.
7
8 Changes:
9 * Feb 21 2008 - jeffm
10 - 2.6.25 claimed -S and bumped the flags up a bit, modpost now uses -N
11
12 Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
13
14 ---
15
16 Documentation/kernel-parameters.txt | 6 +++
17 Documentation/sysctl/kernel.txt | 12 ++++++
18 Makefile | 5 ++
19 include/linux/kernel.h | 8 ++++
20 kernel/module.c | 41 ++++++++++++++++++++++
21 kernel/panic.c | 8 +++-
22 kernel/sysctl.c | 10 +++++
23 scripts/Makefile.modpost | 4 +-
24 scripts/mod/modpost.c | 65 +++++++++++++++++++++++++++++++++++-
25 9 files changed, 155 insertions(+), 4 deletions(-)
26
27 --- a/Documentation/kernel-parameters.txt
28 +++ b/Documentation/kernel-parameters.txt
29 @@ -2113,6 +2113,12 @@ and is between 256 and 4096 characters.
30 pernode one pool for each NUMA node (equivalent
31 to global on non-NUMA machines)
32
33 + unsupported Allow loading of unsupported kernel modules:
34 + 0 = only allow supported modules,
35 + 1 = warn when loading unsupported modules,
36 + 2 = don't warn.
37 +
38 +
39 swiotlb= [IA-64] Number of I/O TLB slabs
40
41 switches= [HW,M68k]
42 --- a/Documentation/sysctl/kernel.txt
43 +++ b/Documentation/sysctl/kernel.txt
44 @@ -369,4 +369,16 @@ can be ORed together:
45 2 - A module was force loaded by insmod -f.
46 Set by modutils >= 2.4.9 and module-init-tools.
47 4 - Unsafe SMP processors: SMP with CPUs not designed for SMP.
48 + 0x40000000 - An unsupported kernel module was loaded.
49 + 0x80000000 - An kernel module with external support was loaded.
50 +
51 +==============================================================
52 +
53 +unsupported:
54 +
55 +Allow to load unsupported kernel modules:
56 +
57 + 0 - refuse to load unsupported modules,
58 + 1 - warn when loading unsupported modules,
59 + 2 - don't warn.
60
61 --- a/Makefile
62 +++ b/Makefile
63 @@ -343,6 +343,11 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstric
64 -Werror-implicit-function-declaration
65 KBUILD_AFLAGS := -D__ASSEMBLY__
66
67 +# Warn about unsupported modules in kernels built inside Autobuild
68 +ifneq ($(wildcard /.buildenv),)
69 +CFLAGS += -DUNSUPPORTED_MODULES=2
70 +endif
71 +
72 # Read KERNELRELEASE from include/config/kernel.release (if it exists)
73 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
74 KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
75 --- a/include/linux/kernel.h
76 +++ b/include/linux/kernel.h
77 @@ -236,6 +236,7 @@ extern int panic_timeout;
78 extern int panic_on_oops;
79 extern int panic_on_unrecovered_nmi;
80 extern int tainted;
81 +extern int unsupported;
82 extern const char *print_tainted(void);
83 extern void add_taint(unsigned);
84 extern int root_mountflags;
85 @@ -261,6 +262,13 @@ extern enum system_states {
86 #define TAINT_OVERRIDDEN_ACPI_TABLE (1<<8)
87 #define TAINT_WARN (1<<9)
88
89 +/*
90 + * Take the upper bits to hopefully allow them
91 + * to stay the same for more than one release.
92 + */
93 +#define TAINT_NO_SUPPORT (1<<30)
94 +#define TAINT_EXTERNAL_SUPPORT (1<<31)
95 +
96 extern void dump_stack(void) __cold;
97
98 enum {
99 --- a/kernel/module.c
100 +++ b/kernel/module.c
101 @@ -60,6 +60,20 @@
102 /* If this is set, the section belongs in the init part of the module */
103 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
104
105 +/* Allow unsupported modules switch. */
106 +#ifdef UNSUPPORTED_MODULES
107 +int unsupported = UNSUPPORTED_MODULES;
108 +#else
109 +int unsupported = 2; /* don't warn when loading unsupported modules. */
110 +#endif
111 +
112 +static int __init unsupported_setup(char *str)
113 +{
114 + get_option(&str, &unsupported);
115 + return 1;
116 +}
117 +__setup("unsupported=", unsupported_setup);
118 +
119 /* List of modules, protected by module_mutex or preempt_disable
120 * (add/delete uses stop_machine). */
121 static DEFINE_MUTEX(module_mutex);
122 @@ -1806,6 +1820,7 @@ static noinline struct module *load_modu
123 Elf_Ehdr *hdr;
124 Elf_Shdr *sechdrs;
125 char *secstrings, *args, *modmagic, *strtab = NULL;
126 + char *supported;
127 unsigned int i;
128 unsigned int symindex = 0;
129 unsigned int strindex = 0;
130 @@ -1960,6 +1975,28 @@ static noinline struct module *load_modu
131 goto free_hdr;
132 }
133
134 + supported = get_modinfo(sechdrs, infoindex, "supported");
135 + if (supported) {
136 + if (!strcmp(supported, "external"))
137 + add_taint_module(mod, TAINT_EXTERNAL_SUPPORT);
138 + else if (strcmp(supported, "yes"))
139 + supported = NULL;
140 + }
141 + if (!supported) {
142 + if (unsupported == 0) {
143 + printk(KERN_WARNING "%s: module not supported by "
144 + "Novell, refusing to load. To override, echo "
145 + "1 > /proc/sys/kernel/unsupported\n", mod->name);
146 + err = -ENOEXEC;
147 + goto free_hdr;
148 + }
149 + add_taint_module(mod, TAINT_NO_SUPPORT);
150 + if (unsupported == 1) {
151 + printk(KERN_WARNING "%s: module not supported by "
152 + "Novell, setting U taint flag.\n", mod->name);
153 + }
154 + }
155 +
156 /* Now copy in args */
157 args = strndup_user(uargs, ~0UL >> 1);
158 if (IS_ERR(args)) {
159 @@ -2554,6 +2591,10 @@ static char *module_flags(struct module
160 buf[bx++] = 'P';
161 if (mod->taints & TAINT_FORCED_MODULE)
162 buf[bx++] = 'F';
163 + if (mod->taints & TAINT_NO_SUPPORT)
164 + buf[bx++] = 'N';
165 + if (mod->taints & TAINT_EXTERNAL_SUPPORT)
166 + buf[bx++] = 'X';
167 /*
168 * TAINT_FORCED_RMMOD: could be added.
169 * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
170 --- a/kernel/panic.c
171 +++ b/kernel/panic.c
172 @@ -155,6 +155,8 @@ EXPORT_SYMBOL(panic);
173 * 'U' - Userspace-defined naughtiness.
174 * 'A' - ACPI table overridden.
175 * 'W' - Taint on warning.
176 + * 'N' - Unsuported modules loaded.
177 + * 'X' - Modules with external support loaded.
178 *
179 * The string is overwritten by the next call to print_taint().
180 */
181 @@ -163,7 +165,7 @@ const char *print_tainted(void)
182 {
183 static char buf[20];
184 if (tainted) {
185 - snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c",
186 + snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c%c%c",
187 tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
188 tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
189 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
190 @@ -173,7 +175,9 @@ const char *print_tainted(void)
191 tainted & TAINT_USER ? 'U' : ' ',
192 tainted & TAINT_DIE ? 'D' : ' ',
193 tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ',
194 - tainted & TAINT_WARN ? 'W' : ' ');
195 + tainted & TAINT_WARN ? 'W' : ' ',
196 + tainted & TAINT_NO_SUPPORT ? 'N' : ' ',
197 + tainted & TAINT_EXTERNAL_SUPPORT ? 'X' : ' ');
198 }
199 else
200 snprintf(buf, sizeof(buf), "Not tainted");
201 --- a/kernel/sysctl.c
202 +++ b/kernel/sysctl.c
203 @@ -550,6 +550,16 @@ static struct ctl_table kern_table[] = {
204 .mode = 0644,
205 .proc_handler = &proc_dointvec,
206 },
207 +#ifdef CONFIG_MODULES
208 + {
209 + .ctl_name = CTL_UNNUMBERED,
210 + .procname = "unsupported",
211 + .data = &unsupported,
212 + .maxlen = sizeof(int),
213 + .mode = 0644,
214 + .proc_handler = &proc_dointvec,
215 + },
216 +#endif
217 {
218 .ctl_name = KERN_RANDOM,
219 .procname = "random",
220 --- a/scripts/Makefile.modpost
221 +++ b/scripts/Makefile.modpost
222 @@ -88,7 +88,9 @@ modpost = scripts/mod/modpost
223 $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
224 $(if $(CONFIG_MARKERS),-M $(markersfile)) \
225 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
226 - $(if $(cross_build),-c)
227 + $(if $(cross_build),-c) \
228 + -N $(firstword $(wildcard $(dir $(MODVERDIR))/Module.supported \
229 + $(objtree)/Module.supported /dev/null))
230
231 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
232 cmd_modpost = $(modpost) -s
233 --- a/scripts/mod/modpost.c
234 +++ b/scripts/mod/modpost.c
235 @@ -1545,6 +1545,48 @@ static void get_markers(struct elf_info
236 }
237 }
238
239 +void *supported_file;
240 +unsigned long supported_size;
241 +
242 +const char *supported(struct module *mod)
243 +{
244 + unsigned long pos = 0;
245 + char *line;
246 +
247 + /* In a first shot, do a simple linear scan. */
248 + while ((line = get_next_line(&pos, supported_file,
249 + supported_size))) {
250 + const char *basename, *how = "yes";
251 + char *l = line;
252 +
253 + /* optional type-of-support flag */
254 + for (l = line; *l != '\0'; l++) {
255 + if (*l == ' ' || *l == '\t') {
256 + *l = '\0';
257 + how = l + 1;
258 + break;
259 + }
260 + }
261 +
262 + /* skip directory components */
263 + if ((l = strrchr(line, '/')))
264 + line = l + 1;
265 + /* strip .ko extension */
266 + l = line + strlen(line);
267 + if (l - line > 3 && !strcmp(l-3, ".ko"))
268 + *(l-3) = '\0';
269 +
270 + /* skip directory components */
271 + if ((basename = strrchr(mod->name, '/')))
272 + basename++;
273 + else
274 + basename = mod->name;
275 + if (!strcmp(basename, line))
276 + return how;
277 + }
278 + return NULL;
279 +}
280 +
281 static void read_symbols(char *modname)
282 {
283 const char *symname;
284 @@ -1726,6 +1768,13 @@ static void add_header(struct buffer *b,
285 buf_printf(b, "};\n");
286 }
287
288 +void add_supported_flag(struct buffer *b, struct module *mod)
289 +{
290 + const char *how = supported(mod);
291 + if (how)
292 + buf_printf(b, "\nMODULE_INFO(supported, \"%s\");\n", how);
293 +}
294 +
295 /**
296 * Record CRCs for unresolved symbols
297 **/
298 @@ -1866,6 +1915,13 @@ static void write_if_changed(struct buff
299 fclose(file);
300 }
301
302 +void read_supported(const char *fname)
303 +{
304 + supported_file = grab_file(fname, &supported_size);
305 + if (!supported_file)
306 + ; /* ignore error */
307 +}
308 +
309 /* parse Module.symvers file. line format:
310 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
311 **/
312 @@ -2051,12 +2107,13 @@ int main(int argc, char **argv)
313 char *dump_write = NULL;
314 char *markers_read = NULL;
315 char *markers_write = NULL;
316 + const char *supported = NULL;
317 int opt;
318 int err;
319 struct ext_sym_list *extsym_iter;
320 struct ext_sym_list *extsym_start = NULL;
321
322 - while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:")) != -1) {
323 + while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:N:")) != -1) {
324 switch (opt) {
325 case 'i':
326 kernel_read = optarg;
327 @@ -2100,11 +2157,16 @@ int main(int argc, char **argv)
328 case 'K':
329 markers_read = optarg;
330 break;
331 + case 'N':
332 + supported = optarg;
333 + break;
334 default:
335 exit(1);
336 }
337 }
338
339 + if (supported)
340 + read_supported(supported);
341 if (kernel_read)
342 read_dump(kernel_read, 1);
343 if (module_read)
344 @@ -2136,6 +2198,7 @@ int main(int argc, char **argv)
345 buf.pos = 0;
346
347 add_header(&buf, mod);
348 + add_supported_flag(&buf, mod);
349 err |= add_versions(&buf, mod);
350 add_depends(&buf, mod, modules);
351 add_moddevtable(&buf, mod);