From: Jeff Mahoney <jeffm@suse.com>
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 <jeffm@suse.com>
---
 Documentation/kernel-parameters.txt |    3 +++
 include/linux/kernel.h              |    2 ++
 init/Kconfig                        |   17 +++++++++++++++++
 kernel/ksysfs.c                     |    4 ++++
 kernel/module.c                     |   12 ++++++++++++
 kernel/panic.c                      |    2 ++
 kernel/sysctl.c                     |    2 +-
 scripts/Makefile.modpost            |    7 ++++---
 8 files changed, 45 insertions(+), 4 deletions(-)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2545,6 +2545,9 @@ bytes respectively. Such letter suffixes
 			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
@@ -377,12 +377,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
@@ -2,6 +2,23 @@ config SUSE_KERNEL
 	bool
 	default 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 SUSE, 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
@@ -166,6 +166,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 = (1 << TAINT_PROPRIETARY_MODULE) | (1 << TAINT_NO_SUPPORT);
@@ -187,6 +188,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[] = {
 	&fscaps_attr.attr,
@@ -203,7 +205,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
@@ -95,6 +95,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;
@@ -108,6 +109,7 @@ static int __init unsupported_setup(char
 	return 1;
 }
 __setup("unsupported=", unsupported_setup);
+#endif
 
 /*
  * Mutex protects:
@@ -989,6 +991,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) {
@@ -1013,12 +1016,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
@@ -1560,6 +1566,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);
@@ -1579,6 +1586,7 @@ static int mod_sysfs_setup(struct module
 			       "involves a kernel fault.\n", mod->name);
 		}
 	}
+#endif
 
 	kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
 	return 0;
@@ -3263,10 +3271,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
@@ -3479,7 +3489,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
@@ -175,8 +175,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
@@ -666,7 +666,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,9 +82,10 @@ 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 \
-			   $(srctree)/Module.supported /dev/null))
+ $(if $(CONFIG_ENTERPRISE_SUPPORT),              \
+      -N $(firstword $(wildcard $(dir $(MODVERDIR))/Module.supported \
+				$(objtree)/Module.supported \
+				$(srctree)/Module.supported /dev/null)))
 
 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
       cmd_modpost = $(modpost) -s
