early_printk: Add 'force_early_printk' kernel parameter

Add add the 'force_early_printk' kernel parameter to override printk()
and force it into early_printk(). This bypasses all the cruft and fail
from printk() and makes things work again.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 65731b0..33d2c23 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1519,6 +1519,11 @@
 	floppy=		[HW]
 			See Documentation/admin-guide/blockdev/floppy.rst.
 
+	force_early_printk
+			Forcefully uses early_console (as per earlyprintk=)
+			usage for regular printk, bypassing everything,
+			including the syslog (dmesg will be empty).
+
 	forcepae	[X86-32]
 			Forcefully enable Physical Address Extension (PAE).
 			Many Pentium M systems disable PAE but may have a
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index baa0434..8908142 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -63,6 +63,15 @@
 #ifdef CONFIG_EARLY_PRINTK
 struct console *early_console;
 
+static bool __read_mostly force_early_printk;
+
+static int __init force_early_printk_setup(char *str)
+{
+	force_early_printk = true;
+	return 0;
+}
+early_param("force_early_printk", force_early_printk_setup);
+
 static int early_vprintk(const char *fmt, va_list args)
 {
 	char buf[512];
@@ -2301,6 +2310,11 @@ asmlinkage int vprintk_emit(int facility, int level,
 	    atomic_read(&panic_cpu) != raw_smp_processor_id())
 		return 0;
 
+#ifdef CONFIG_EARLY_PRINTK
+	if (force_early_printk && early_console)
+		return early_vprintk(fmt, args);
+#endif
+
 	if (level == LOGLEVEL_SCHED) {
 		level = LOGLEVEL_DEFAULT;
 		in_sched = true;