From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Laura Abbott <labbott@redhat.com>
Date: Wed, 13 Nov 2019 14:44:31 -0500
Subject: [PATCH] Add Red Hat tainting

Message-id: <20191113144431.9403-5-labbott@redhat.com>
Patchwork-id: 286078
O-Subject: [ARK INTERNAL PATCHv2 4/4] [redhat] Add Red Hat tainting
Bugzilla:
RH-Acked-by: Don Zickus <dzickus@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>
RH-Acked-by: Jiri Benc <jbenc@redhat.com>

This is a combination of the following commits including support
for adding CONFIG_RH_DEPRECATED support

rh_taint: add support

Message-id: <1524831536-47239-1-git-send-email-darcari@redhat.com>
Patchwork-id: 211655
O-Subject: [RHEL8.0 BZ 1565704 v2] rh_taint: add support
Bugzilla: 1565704
RH-Acked-by: Jonathan Toppins <jtoppins@redhat.com>
RH-Acked-by: Jiri Benc <jbenc@redhat.com>

Bugzilla: http://bugzilla.redhat.com/1565704
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=15910441
Upstream: RHEL Only
Test: Sanity boot of brew build.  Previous private build testing of functions.

rh_taint.c adds the following functions which are utilized by Red Hat to
indicate limited or no support for hardware and/or drivers.

mark_hardware_unsupported
mark_hardware_deprecated
mark_tech_preview

See code comments for usage.

RHEL8 change: TAINT_AUX will be used in place of TAINT_TECH_PREVIEW as it
limits the number RHEL only changes that must be made to the kernel.

If at a later date it is determined that additional flags are required,
the associated RHEL only infrastructure can be added at that time.

Cc: David Arcari <darcari@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Herton R. Krzesinski <herton@redhat.com>

rh_taint: add support for marking driver as unsupported

Message-id: <f42d35b07bd02f34b14a6341a219c80b21a8aff9.1524523802.git.jtoppins@redhat.com>
Patchwork-id: 211020
O-Subject: [RHEL8.0] rh_taint: add support for marking driver as unsupported
Bugzilla: 1565704
RH-Acked-by: Jiri Benc <jbenc@redhat.com>
RH-Acked-by: David Arcari <darcari@redhat.com>

In some cases a driver needs to be enabled by Red Hat to support internal
testing but the driver is not intended to be supported on customer hardware.
This adds a function "make_driver_unsupported()" to facilitate such
situations. The function will print a kernel log message.

Bugzilla: 1565704
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=15873552
Tested: compile only

Signed-off-by: Jonathan Toppins <jtoppins@redhat.com>
Signed-off-by: Herton R. Krzesinski <herton@redhat.com>

rh_taint: correct loaddable module support dependencies

Message-id: <20181123111337.26898-5-prudo@redhat.com>
Patchwork-id: 233658
O-Subject: [ARK PATCH RESEND v2 4/8] [kernel] rh_taint: correct loaddable module support dependencies
Bugzilla: 1652266
RH-Acked-by: Jakub Racek <jracek@redhat.com>
RH-Acked-by: Jiri Benc <jbenc@redhat.com>
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>

Bugzilla: 1652266
Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=19252944
Upstream Status: RHEL_only

The kernel configuration for the s390/zfcpdump kernel variant turns
loaddable module support off.  The build breaks in rh_taint.c due to
compiler errors caused by dereferencing struct module variables which
is just a declaration if CONFIG_MODULES is not set.

To solve this build break, access struct module members only if
CONFIG_MODULES is enabled.

Upstream Status: RHEL only
Signed-off-by: Philipp Rudo <prudo@redhat.com>
---
 include/linux/kernel.h | 15 +++++++
 kernel/Makefile        |  1 +
 kernel/rh_taint.c      | 93 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 kernel/rh_taint.c

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index c25b8e41c0ea..c3dd56bf044f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -1037,4 +1037,19 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 	 /* OTHER_WRITABLE?  Generally considered a bad idea. */		\
 	 BUILD_BUG_ON_ZERO((perms) & 2) +					\
 	 (perms))
+
+struct module;
+
+#ifdef CONFIG_RH_DISABLE_DEPRECATED
+void mark_hardware_unsupported(const char *msg);
+void mark_hardware_deprecated(const char *msg);
+void mark_tech_preview(const char *msg, struct module *mod);
+void mark_driver_unsupported(const char *name);
+#else
+static inline void mark_hardware_unsupported(const char *msg) { }
+static inline void mark_hardware_deprecated(const char *msg) { }
+static inline void mark_tech_preview(const char *msg, struct module *mod) { }
+static inline void mark_driver_unsupported(const char *name) { }
+#endif
+
 #endif
diff --git a/kernel/Makefile b/kernel/Makefile
index 9a20016d4900..4fbfd2a0800c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -13,6 +13,7 @@ obj-y     = fork.o exec_domain.o panic.o \
 	    async.o range.o smpboot.o ucount.o regset.o

 obj-$(CONFIG_BPFILTER) += usermode_driver.o
+obj-$(CONFIG_RH_DISABLE_DEPRECATED) += rh_taint.o
 obj-$(CONFIG_MODULES) += kmod.o
 obj-$(CONFIG_MULTIUSER) += groups.o

diff --git a/kernel/rh_taint.c b/kernel/rh_taint.c
new file mode 100644
index 000000000000..8d1641710ed7
--- /dev/null
+++ b/kernel/rh_taint.c
@@ -0,0 +1,93 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+/*
+ * The following functions are used by Red Hat to indicate to users that
+ * hardware and drivers are unsupported, or have limited support in RHEL major
+ * and minor releases.  These functions output loud warning messages to the end
+ * user and should be USED WITH CAUTION.
+ *
+ * Any use of these functions _MUST_ be documented in the RHEL Release Notes,
+ * and have approval of management.
+ */
+
+/**
+ * mark_hardware_unsupported() - Mark hardware, class, or type as unsupported.
+ * @msg: Hardware name, class, or type
+ *
+ * Called to mark a device, class of devices, or types of devices as not having
+ * support in any RHEL minor release.  This does not TAINT the kernel.  Red Hat
+ * will not fix bugs against this hardware in this minor release.  Red Hat may
+ * declare support in a future major or minor update release.  This cannot be
+ * used to mark drivers unsupported.
+ */
+void mark_hardware_unsupported(const char *msg)
+{
+	/* Print one single message */
+	pr_crit("Warning: %s - this hardware has not undergone testing by Red Hat and might not be certified. Please consult https://hardware.redhat.com for certified hardware.\n", msg);
+}
+EXPORT_SYMBOL(mark_hardware_unsupported);
+
+/**
+ * mark_hardware_deprecated() - Mark hardware, class, or type as deprecated.
+ * @msg: Hardware name, class, or type
+ *
+ * Called to minimize the support status of a previously supported device in
+ * a minor release.  This does not TAINT the kernel.  Marking hardware
+ * deprecated is usually done in conjunction with the hardware vendor.  Future
+ * RHEL major releases may not include this driver.  Driver updates and fixes
+ * for this device will be limited to critical issues in future minor releases.
+ */
+void mark_hardware_deprecated(const char *msg)
+{
+	pr_crit("Warning: %s - this hardware is not recommended for new deployments. It continues to be supported in this RHEL release, but it is likely to be removed in the next major release. Driver updates and fixes for this device will be limited to critical issues. Please contact Red Hat Support or your device's hardware vendor for additional information.\n", msg);
+}
+EXPORT_SYMBOL(mark_hardware_deprecated);
+
+/**
+ * mark_tech_preview() - Mark driver or kernel subsystem as 'Tech Preview'
+ * @msg: Driver or kernel subsystem name
+ *
+ * Called to minimize the support status of a new driver.  This does TAINT the
+ * kernel.  Calling this function indicates that the driver or subsystem has
+ * had limited testing and is not marked for full support within this RHEL
+ * minor release.  The next RHEL minor release may contain full support for
+ * this driver.  Red Hat does not guarantee that bugs reported against this
+ * driver or subsystem will be resolved.
+ */
+void mark_tech_preview(const char *msg, struct module *mod)
+{
+	const char *str = NULL;
+
+	if (msg)
+		str = msg;
+#ifdef CONFIG_MODULES
+	else if (mod && mod->name)
+		str = mod->name;
+#endif
+
+	pr_warn("TECH PREVIEW: %s may not be fully supported.\n"
+		"Please review provided documentation for limitations.\n",
+		(str ? str : "kernel"));
+	add_taint(TAINT_AUX, LOCKDEP_STILL_OK);
+#ifdef CONFIG_MODULES
+	if (mod)
+		mod->taints |= (1U << TAINT_AUX);
+#endif
+}
+EXPORT_SYMBOL(mark_tech_preview);
+
+/**
+ * mark_driver_unsupported - drivers that we know we don't want to support
+ * @name: the name of the driver
+ *
+ * In some cases Red Hat has chosen to build a driver for internal QE
+ * use. Use this function to mark those drivers as unsupported for
+ * customers.
+ */
+void mark_driver_unsupported(const char *name)
+{
+	pr_crit("Warning: %s - This driver has not undergone sufficient testing by Red Hat for this release and therefore cannot be used in production systems.\n",
+	        name ? name : "kernel");
+}
+EXPORT_SYMBOL(mark_driver_unsupported);
-- 
2.26.2

