|
48 | 48 | #include <linux/uio.h>
|
49 | 49 |
|
50 | 50 | #include <asm/uaccess.h>
|
| 51 | +#include <asm-generic/sections.h> |
51 | 52 |
|
52 | 53 | #define CREATE_TRACE_POINTS
|
53 | 54 | #include <trace/events/printk.h>
|
@@ -2658,13 +2659,36 @@ int unregister_console(struct console *console)
|
2658 | 2659 | }
|
2659 | 2660 | EXPORT_SYMBOL(unregister_console);
|
2660 | 2661 |
|
| 2662 | +/* |
| 2663 | + * Some boot consoles access data that is in the init section and which will |
| 2664 | + * be discarded after the initcalls have been run. To make sure that no code |
| 2665 | + * will access this data, unregister the boot consoles in a late initcall. |
| 2666 | + * |
| 2667 | + * If for some reason, such as deferred probe or the driver being a loadable |
| 2668 | + * module, the real console hasn't registered yet at this point, there will |
| 2669 | + * be a brief interval in which no messages are logged to the console, which |
| 2670 | + * makes it difficult to diagnose problems that occur during this time. |
| 2671 | + * |
| 2672 | + * To mitigate this problem somewhat, only unregister consoles whose memory |
| 2673 | + * intersects with the init section. Note that code exists elsewhere to get |
| 2674 | + * rid of the boot console as soon as the proper console shows up, so there |
| 2675 | + * won't be side-effects from postponing the removal. |
| 2676 | + */ |
2661 | 2677 | static int __init printk_late_init(void)
|
2662 | 2678 | {
|
2663 | 2679 | struct console *con;
|
2664 | 2680 |
|
2665 | 2681 | for_each_console(con) {
|
2666 | 2682 | if (!keep_bootcon && con->flags & CON_BOOT) {
|
2667 |
| - unregister_console(con); |
| 2683 | + /* |
| 2684 | + * Make sure to unregister boot consoles whose data |
| 2685 | + * resides in the init section before the init section |
| 2686 | + * is discarded. Boot consoles whose data will stick |
| 2687 | + * around will automatically be unregistered when the |
| 2688 | + * proper console replaces them. |
| 2689 | + */ |
| 2690 | + if (init_section_intersects(con, sizeof(*con))) |
| 2691 | + unregister_console(con); |
2668 | 2692 | }
|
2669 | 2693 | }
|
2670 | 2694 | hotcpu_notifier(console_cpu_notify, 0);
|
|
0 commit comments