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 |    2 ++
 include/linux/kernel.h              |    2 ++
 init/Kconfig                        |   18 ++++++++++++++++++
 kernel/ksysfs.c                     |    4 ++++
 kernel/module.c                     |   12 ++++++++++++
 kernel/panic.c                      |    2 ++
 kernel/sysctl.c                     |    2 +-
 scripts/Makefile.modpost            |    5 +++--
 8 files changed, 44 insertions(+), 3 deletions(-)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2554,6 +2554,8 @@ 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.
 
 	swiotlb=	[IA-64] Number of I/O TLB slabs
 
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -347,12 +347,14 @@ extern enum system_states {
 #define TAINT_WARN			9
 #define TAINT_CRAP			10
 
+#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 void dump_stack(void) __cold;
 
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2,6 +2,24 @@ config SUSE_KERNEL
 	bool
 	default y
 
+config ENTERPRISE_SUPPORT
+	bool "Enable enterprise support facility"
+	depends on SUSE_KERNEL
+	default n
+	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
@@ -156,6 +156,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;
@@ -177,6 +178,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)
@@ -192,7 +194,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
@@ -74,6 +74,7 @@ EXPORT_TRACEPOINT_SYMBOL(module_get);
 /* 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;
@@ -87,6 +88,7 @@ static int __init unsupported_setup(char
 	return 1;
 }
 __setup("unsupported=", unsupported_setup);
+#endif
 
 /* List of modules, protected by module_mutex or preempt_disable
  * (delete uses stop_machine/add uses RCU list operations). */
@@ -870,6 +872,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) {
@@ -894,12 +897,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
@@ -2421,6 +2427,7 @@ static noinline struct module *load_modu
 	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
 	add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
 
+#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);
@@ -2440,6 +2447,7 @@ static noinline struct module *load_modu
 			       "fault.\n", mod->name);
 		}
 	}
+#endif
 
 	/* Get rid of temporary copy */
 	vfree(hdr);
@@ -2808,10 +2816,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
@@ -3024,7 +3034,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
@@ -178,8 +178,10 @@ static const struct tnt tnts[] = {
 	{ TAINT_OVERRIDDEN_ACPI_TABLE,	'A', ' ' },
 	{ TAINT_WARN,			'W', ' ' },
 	{ TAINT_CRAP,			'C', ' ' },
+#ifdef CONFIG_ENTERPRISE_SUPPORT
 	{ TAINT_NO_SUPPORT,		'N', ' ' },
 	{ TAINT_EXTERNAL_SUPPORT,	'X', ' ' },
+#endif
 };
 
 /**
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -636,7 +636,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
