]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - 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
CommitLineData
00e5a55c
BS
1From: Andreas Gruenbacher <agruen@suse.de>
2Subject: Novell/external support flag in modules
3
4Upon module load, check if a module is supported, and set the
5N (TAINT_NO_SUPPORT) or X (TAINT_EXTERNAL_SUPPORT) tail flags
6for unsupported or externally suported modules.
7
8Changes:
9* Feb 21 2008 - jeffm
10- 2.6.25 claimed -S and bumped the flags up a bit, modpost now uses -N
11
12Signed-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);