|
@@ -48,6 +48,7 @@
|
|
|
#include <linux/uio.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
|
+#include <asm-generic/sections.h>
|
|
|
|
|
|
#define CREATE_TRACE_POINTS
|
|
|
#include <trace/events/printk.h>
|
|
@@ -2658,13 +2659,36 @@ int unregister_console(struct console *console)
|
|
|
}
|
|
|
EXPORT_SYMBOL(unregister_console);
|
|
|
|
|
|
+/*
|
|
|
+ * Some boot consoles access data that is in the init section and which will
|
|
|
+ * be discarded after the initcalls have been run. To make sure that no code
|
|
|
+ * will access this data, unregister the boot consoles in a late initcall.
|
|
|
+ *
|
|
|
+ * If for some reason, such as deferred probe or the driver being a loadable
|
|
|
+ * module, the real console hasn't registered yet at this point, there will
|
|
|
+ * be a brief interval in which no messages are logged to the console, which
|
|
|
+ * makes it difficult to diagnose problems that occur during this time.
|
|
|
+ *
|
|
|
+ * To mitigate this problem somewhat, only unregister consoles whose memory
|
|
|
+ * intersects with the init section. Note that code exists elsewhere to get
|
|
|
+ * rid of the boot console as soon as the proper console shows up, so there
|
|
|
+ * won't be side-effects from postponing the removal.
|
|
|
+ */
|
|
|
static int __init printk_late_init(void)
|
|
|
{
|
|
|
struct console *con;
|
|
|
|
|
|
for_each_console(con) {
|
|
|
if (!keep_bootcon && con->flags & CON_BOOT) {
|
|
|
- unregister_console(con);
|
|
|
+ /*
|
|
|
+ * Make sure to unregister boot consoles whose data
|
|
|
+ * resides in the init section before the init section
|
|
|
+ * is discarded. Boot consoles whose data will stick
|
|
|
+ * around will automatically be unregistered when the
|
|
|
+ * proper console replaces them.
|
|
|
+ */
|
|
|
+ if (init_section_intersects(con, sizeof(*con)))
|
|
|
+ unregister_console(con);
|
|
|
}
|
|
|
}
|
|
|
hotcpu_notifier(console_cpu_notify, 0);
|