From: Jeff Mahoney Subject: Make the supported flag configurable at build time References: bnc#528097 Patch-mainline: Never, SLES feature In the enterprise kernels, it makes sense to have the supportability facility. For openSUSE, it's unnecessary, cumbersome, and just plain wrong. The support commitments for the two releases are totally different and it doesn't make any sense to pretend that they are. This patch adds a CONFIG_ENTERPRISE_SUPPORT option, which enables the support reporting facility. When it is disabled, the reporting and checking are too. Signed-off-by: Jeff Mahoney --- Documentation/kernel-parameters.txt | 3 +++ include/linux/kernel.h | 2 ++ init/Kconfig | 18 ++++++++++++++++++ kernel/ksysfs.c | 4 ++++ kernel/module.c | 19 ++++++++++++++++++- kernel/panic.c | 2 ++ kernel/sysctl.c | 2 +- scripts/Makefile.modpost | 5 +++-- 8 files changed, 51 insertions(+), 4 deletions(-) --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2509,6 +2509,9 @@ and is between 256 and 4096 characters. 1 = warn when loading unsupported modules, 2 = don't warn. + CONFIG_ENTERPRISE_SUPPORT must be enabled for this + to have any effect. + usbcore.autosuspend= [USB] The autosuspend time delay (in seconds) used for newly-detected USB devices (default 2). This --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -253,12 +253,14 @@ extern enum system_states { #define TAINT_CRAP 10 #define TAINT_FIRMWARE_WORKAROUND 11 +#ifdef CONFIG_ENTERPRISE_SUPPORT /* * Take the upper bits to hopefully allow them * to stay the same for more than one release. */ #define TAINT_NO_SUPPORT 30 #define TAINT_EXTERNAL_SUPPORT 31 +#endif extern const char hex_asc[]; #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] --- a/init/Kconfig +++ b/init/Kconfig @@ -1,6 +1,23 @@ config SUSE_KERNEL def_bool y +config ENTERPRISE_SUPPORT + bool "Enable enterprise support facility" + depends on SUSE_KERNEL + help + This feature enables the handling of the "supported" module flag. + This flag can be used to report unsupported module loads or even + refuse them entirely. It is useful when ensuring that the kernel + remains in a state that Novell Technical Services, or its + technical partners, is prepared to support. + + Modules in the list of supported modules will be marked supported + on build. The default enforcement mode is to report, but not + deny, loading of unsupported modules. + + If you aren't building a kernel for an enterprise distribution, + say n. + config SPLIT_PACKAGE bool "Split the kernel package into multiple RPMs" depends on SUSE_KERNEL && MODULES --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -157,6 +157,7 @@ static struct bin_attribute notes_attr = struct kobject *kernel_kobj; EXPORT_SYMBOL_GPL(kernel_kobj); +#ifdef CONFIG_ENTERPRISE_SUPPORT const char *supported_printable(int taint) { int mask = TAINT_PROPRIETARY_MODULE|TAINT_NO_SUPPORT; @@ -178,6 +179,7 @@ static ssize_t supported_show(struct kob return sprintf(buf, "%s\n", supported_printable(get_taint())); } KERNEL_ATTR_RO(supported); +#endif static struct attribute * kernel_attrs[] = { #if defined(CONFIG_HOTPLUG) @@ -193,7 +195,9 @@ static struct attribute * kernel_attrs[] &kexec_crash_size_attr.attr, &vmcoreinfo_attr.attr, #endif +#ifdef CONFIG_ENTERPRISE_SUPPORT &supported_attr.attr, +#endif NULL }; --- a/kernel/module.c +++ b/kernel/module.c @@ -73,6 +73,7 @@ /* If this is set, the section belongs in the init part of the module */ #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) +#ifdef CONFIG_ENTERPRISE_SUPPORT /* Allow unsupported modules switch. */ #ifdef UNSUPPORTED_MODULES int unsupported = UNSUPPORTED_MODULES; @@ -86,6 +87,7 @@ static int __init unsupported_setup(char return 1; } __setup("unsupported=", unsupported_setup); +#endif /* * Mutex protects: @@ -945,6 +947,7 @@ static struct module_attribute initstate .show = show_initstate, }; +#ifdef CONFIG_ENTERPRISE_SUPPORT static void setup_modinfo_supported(struct module *mod, const char *s) { if (!s) { @@ -969,12 +972,15 @@ static struct module_attribute modinfo_s .show = show_modinfo_supported, .setup = setup_modinfo_supported, }; +#endif static struct module_attribute *modinfo_attrs[] = { &modinfo_version, &modinfo_srcversion, &initstate, +#ifdef CONFIG_ENTERPRISE_SUPPORT &modinfo_supported, +#endif #ifdef CONFIG_MODULE_UNLOAD &refcnt, #endif @@ -1516,6 +1522,7 @@ static int mod_sysfs_setup(struct module add_sect_attrs(mod, info); add_notes_attrs(mod, info); +#ifdef CONFIG_ENTERPRISE_SUPPORT /* We don't use add_taint() here because it also disables lockdep. */ if (mod->taints & (1 << TAINT_EXTERNAL_SUPPORT)) add_nonfatal_taint(TAINT_EXTERNAL_SUPPORT); @@ -1525,7 +1532,7 @@ static int mod_sysfs_setup(struct module "Novell, refusing to load. To override, echo " "1 > /proc/sys/kernel/unsupported\n", mod->name); err = -ENOEXEC; - goto free_hdr; + goto out_remove_attrs; } add_nonfatal_taint(TAINT_NO_SUPPORT); if (unsupported == 1) { @@ -1535,10 +1542,16 @@ static int mod_sysfs_setup(struct module "fault.\n", mod->name); } } +#endif kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); return 0; +out_remove_attrs: + remove_notes_attrs(mod); + remove_sect_attrs(mod); + del_usage_links(mod); + module_remove_modinfo_attrs(mod); out_unreg_param: module_param_sysfs_remove(mod); out_unreg_holders: @@ -3065,10 +3078,12 @@ static char *module_flags(struct module buf[bx++] = 'F'; if (mod->taints & (1 << TAINT_CRAP)) buf[bx++] = 'C'; +#ifdef CONFIG_ENTERPRISE_SUPPORT if (mod->taints & (1 << TAINT_NO_SUPPORT)) buf[bx++] = 'N'; if (mod->taints & (1 << TAINT_EXTERNAL_SUPPORT)) buf[bx++] = 'X'; +#endif /* * TAINT_FORCED_RMMOD: could be added. * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't @@ -3281,7 +3296,9 @@ void print_modules(void) if (last_unloaded_module[0]) printk(" [last unloaded: %s]", last_unloaded_module); printk("\n"); +#ifdef CONFIG_ENTERPRISE_SUPPORT printk("Supported: %s\n", supported_printable(get_taint())); +#endif } #ifdef CONFIG_MODVERSIONS --- a/kernel/panic.c +++ b/kernel/panic.c @@ -174,8 +174,10 @@ static const struct tnt tnts[] = { { TAINT_WARN, 'W', ' ' }, { TAINT_CRAP, 'C', ' ' }, { TAINT_FIRMWARE_WORKAROUND, 'I', ' ' }, +#ifdef CONFIG_ENTERPRISE_SUPPORT { TAINT_NO_SUPPORT, 'N', ' ' }, { TAINT_EXTERNAL_SUPPORT, 'X', ' ' }, +#endif }; /** --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -664,7 +664,7 @@ static struct ctl_table kern_table[] = { .extra1 = &pid_max_min, .extra2 = &pid_max_max, }, -#ifdef CONFIG_MODULES +#if defined(CONFIG_MODULES) && defined(CONFIG_ENTERPRISE_SUPPORT) { .procname = "unsupported", .data = &unsupported, --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -82,8 +82,9 @@ modpost = scripts/mod/modpost $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ $(if $(cross_build),-c) \ - -N $(firstword $(wildcard $(dir $(MODVERDIR))/Module.supported \ - $(objtree)/Module.supported /dev/null)) + $(if $(CONFIG_ENTERPRISE_SUPPORT), \ + -N $(firstword $(wildcard $(dir $(MODVERDIR))/Module.supported \ + $(objtree)/Module.supported /dev/null))) quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules cmd_modpost = $(modpost) -s