diff --git a/0001-printk-Make-CONSOLE_LOGLEVEL_QUIET-configurable.patch b/0001-printk-Make-CONSOLE_LOGLEVEL_QUIET-configurable.patch new file mode 100644 index 0000000..548bd4b --- /dev/null +++ b/0001-printk-Make-CONSOLE_LOGLEVEL_QUIET-configurable.patch @@ -0,0 +1,79 @@ +From 79bfd044ed82290603093be1a3759672176f3e6f Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 19 Jun 2018 13:30:04 +0200 +Subject: [PATCH] printk: Make CONSOLE_LOGLEVEL_QUIET configurable + +The goal of passing the "quiet" option to the kernel is for the kernel +to be quiet unless something really is wrong. + +Sofar passing quiet has been (mostly) equivalent to passing +loglevel=4 on the kernel commandline. Which means to show any messages +with a level of KERN_ERR or higher severity on the console. + +In practice this often does not result in a quiet boot though, since +there are many false-positive or otherwise harmless error messages printed, +defeating the purpose of the quiet option. Esp. the ACPICA code is really +bad wrt this, but there are plenty of others too. + +This commit makes CONSOLE_LOGLEVEL_QUIET configurable. + +This for example will allow distros which want quiet to really mean quiet +to set CONSOLE_LOGLEVEL_QUIET so that only messages with a higher severity +then KERN_ERR (CRIT, ALERT, EMERG) get printed, avoiding an endless game +of whack-a-mole silencing harmless error messages. + +Acked-by: Steven Rostedt (VMware) +Signed-off-by: Hans de Goede +--- + include/linux/printk.h | 6 +++--- + lib/Kconfig.debug | 11 +++++++++++ + 2 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/include/linux/printk.h b/include/linux/printk.h +index 6d7e800affd8..18602bb3eca8 100644 +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -50,15 +50,15 @@ static inline const char *printk_skip_headers(const char *buffer) + /* We show everything that is MORE important than this.. */ + #define CONSOLE_LOGLEVEL_SILENT 0 /* Mum's the word */ + #define CONSOLE_LOGLEVEL_MIN 1 /* Minimum loglevel we let people use */ +-#define CONSOLE_LOGLEVEL_QUIET 4 /* Shhh ..., when booted with "quiet" */ + #define CONSOLE_LOGLEVEL_DEBUG 10 /* issue debug messages */ + #define CONSOLE_LOGLEVEL_MOTORMOUTH 15 /* You can't shut this one up */ + + /* +- * Default used to be hard-coded at 7, we're now allowing it to be set from +- * kernel config. ++ * Default used to be hard-coded at 7, quiet used to be hardcoded at 4, ++ * we're now allowing both to be set from kernel config. + */ + #define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT ++#define CONSOLE_LOGLEVEL_QUIET CONFIG_CONSOLE_LOGLEVEL_QUIET + + extern int console_printk[]; + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 8838d1158d19..0d1c48dd22a9 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -30,6 +30,17 @@ config CONSOLE_LOGLEVEL_DEFAULT + usage in the kernel. That is controlled by the MESSAGE_LOGLEVEL_DEFAULT + option. + ++config CONSOLE_LOGLEVEL_QUIET ++ int "quiet console loglevel (1-15)" ++ range 1 15 ++ default "4" ++ help ++ loglevel to use when "quiet" is passed on the kernel commandline. ++ ++ When "quiet" is passed on the kernel commandline this loglevel ++ will be used as the loglevel. IOW passing "quiet" will be the ++ equivalent of passing "loglevel=" ++ + config MESSAGE_LOGLEVEL_DEFAULT + int "Default message log level (1-7)" + range 1 7 +-- +2.18.0 + diff --git a/0002-printk-Export-is_console_locked.patch b/0002-printk-Export-is_console_locked.patch new file mode 100644 index 0000000..aad3730 --- /dev/null +++ b/0002-printk-Export-is_console_locked.patch @@ -0,0 +1,34 @@ +From d48de54a9dab5370edd2e991f78cc7996cf5483e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 28 Jun 2018 15:20:27 +0200 +Subject: [PATCH 2/7] printk: Export is_console_locked + +This is a preparation patch for adding a number of WARN_CONSOLE_UNLOCKED() +calls to the fbcon code, which may be built as a module (event though +usually it is not). + +Acked-by: Steven Rostedt (VMware) +Acked-by: Sergey Senozhatsky +Acked-by: Petr Mladek +Reviewed-by: Daniel Vetter +Signed-off-by: Hans de Goede +Signed-off-by: Bartlomiej Zolnierkiewicz +--- + kernel/printk/printk.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index 247808333ba4..3f041e7cbfc9 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -2243,6 +2243,7 @@ int is_console_locked(void) + { + return console_locked; + } ++EXPORT_SYMBOL(is_console_locked); + + /* + * Check if we have any console that is capable of printing while cpu is +-- +2.18.0 + diff --git a/0003-fbcon-Call-WARN_CONSOLE_UNLOCKED-where-applicable.patch b/0003-fbcon-Call-WARN_CONSOLE_UNLOCKED-where-applicable.patch new file mode 100644 index 0000000..fef33c1 --- /dev/null +++ b/0003-fbcon-Call-WARN_CONSOLE_UNLOCKED-where-applicable.patch @@ -0,0 +1,70 @@ +From 3bd3a0e330aae4fffa8028aba2407ef615ab040b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 28 Jun 2018 15:20:28 +0200 +Subject: [PATCH 3/7] fbcon: Call WARN_CONSOLE_UNLOCKED() where applicable + +Replace comments about places where the console lock should be held with +calls to WARN_CONSOLE_UNLOCKED() to assert that it is actually held. + +Acked-by: Steven Rostedt (VMware) +Reviewed-by: Daniel Vetter +Reviewed-by: Sergey Senozhatsky +Signed-off-by: Hans de Goede +Signed-off-by: Bartlomiej Zolnierkiewicz +--- + drivers/video/fbdev/core/fbcon.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index c910e74d46ff..cd8d52a967aa 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -828,6 +828,8 @@ static int set_con2fb_map(int unit, int newidx, int user) + struct fb_info *oldinfo = NULL; + int found, err = 0; + ++ WARN_CONSOLE_UNLOCKED(); ++ + if (oldidx == newidx) + return 0; + +@@ -3044,6 +3046,8 @@ static int fbcon_fb_unbind(int idx) + { + int i, new_idx = -1, ret = 0; + ++ WARN_CONSOLE_UNLOCKED(); ++ + if (!fbcon_has_console_bind) + return 0; + +@@ -3094,6 +3098,8 @@ static int fbcon_fb_unregistered(struct fb_info *info) + { + int i, idx; + ++ WARN_CONSOLE_UNLOCKED(); ++ + idx = info->node; + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == idx) +@@ -3131,6 +3137,9 @@ static int fbcon_fb_unregistered(struct fb_info *info) + static void fbcon_remap_all(int idx) + { + int i; ++ ++ WARN_CONSOLE_UNLOCKED(); ++ + for (i = first_fb_vc; i <= last_fb_vc; i++) + set_con2fb_map(i, idx, 0); + +@@ -3177,6 +3186,8 @@ static int fbcon_fb_registered(struct fb_info *info) + { + int ret = 0, i, idx; + ++ WARN_CONSOLE_UNLOCKED(); ++ + idx = info->node; + fbcon_select_primary(info); + +-- +2.18.0 + diff --git a/0004-console-fbcon-Add-support-for-deferred-console-takeo.patch b/0004-console-fbcon-Add-support-for-deferred-console-takeo.patch new file mode 100644 index 0000000..36d625e --- /dev/null +++ b/0004-console-fbcon-Add-support-for-deferred-console-takeo.patch @@ -0,0 +1,322 @@ +From 83d83bebf40132e2d55ec58af666713cc76f9764 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 28 Jun 2018 15:20:30 +0200 +Subject: [PATCH 4/7] console/fbcon: Add support for deferred console takeover + +Currently fbcon claims fbdevs as soon as they are registered and takes over +the console as soon as the first fbdev gets registered. + +This behavior is undesirable in cases where a smooth graphical bootup is +desired, in such cases we typically want the contents of the framebuffer +(typically a vendor logo) to stay in place as is. + +The current solution for this problem (on embedded systems) is to not +enable fbcon. + +This commit adds a new FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER config option, +which when enabled defers fbcon taking over the console from the dummy +console until the first text is displayed on the console. Together with the +"quiet" kernel commandline option, this allows fbcon to still be used +together with a smooth graphical bootup, having it take over the console as +soon as e.g. an error message is logged. + +Note the choice to detect the first console output in the dummycon driver, +rather then handling this entirely inside the fbcon code, was made after +2 failed attempts to handle this entirely inside the fbcon code. The fbcon +code is woven quite tightly into the console code, making this to only +feasible option. + +Reviewed-by: Daniel Vetter +Signed-off-by: Hans de Goede +Signed-off-by: Bartlomiej Zolnierkiewicz +--- + Documentation/fb/fbcon.txt | 7 ++++ + drivers/video/console/Kconfig | 11 +++++ + drivers/video/console/dummycon.c | 67 +++++++++++++++++++++++++---- + drivers/video/fbdev/core/fbcon.c | 72 ++++++++++++++++++++++++++++++++ + include/linux/console.h | 5 +++ + 5 files changed, 154 insertions(+), 8 deletions(-) + +diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt +index 79c22d096bbc..d4d642e1ce9c 100644 +--- a/Documentation/fb/fbcon.txt ++++ b/Documentation/fb/fbcon.txt +@@ -155,6 +155,13 @@ C. Boot options + used by text. By default, this area will be black. The 'color' value + is an integer number that depends on the framebuffer driver being used. + ++6. fbcon=nodefer ++ ++ If the kernel is compiled with deferred fbcon takeover support, normally ++ the framebuffer contents, left in place by the firmware/bootloader, will ++ be preserved until there actually is some text is output to the console. ++ This option causes fbcon to bind immediately to the fbdev device. ++ + C. Attaching, Detaching and Unloading + + Before going on how to attach, detach and unload the framebuffer console, an +diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig +index 4110ba7d7ca9..e91edef98633 100644 +--- a/drivers/video/console/Kconfig ++++ b/drivers/video/console/Kconfig +@@ -150,6 +150,17 @@ config FRAMEBUFFER_CONSOLE_ROTATION + such that other users of the framebuffer will remain normally + oriented. + ++config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++ bool "Framebuffer Console Deferred Takeover" ++ depends on FRAMEBUFFER_CONSOLE=y && DUMMY_CONSOLE=y ++ help ++ If enabled this defers the framebuffer console taking over the ++ console from the dummy console until the first text is displayed on ++ the console. This is useful in combination with the "quiet" kernel ++ commandline option to keep the framebuffer contents initially put up ++ by the firmware in place, rather then replacing the contents with a ++ black screen as soon as fbcon loads. ++ + config STI_CONSOLE + bool "STI text console" + depends on PARISC && HAS_IOMEM +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index f2eafe2ed980..45ad925ad5f8 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -26,6 +26,65 @@ + #define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS + #endif + ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++/* These are both protected by the console_lock */ ++static RAW_NOTIFIER_HEAD(dummycon_output_nh); ++static bool dummycon_putc_called; ++ ++void dummycon_register_output_notifier(struct notifier_block *nb) ++{ ++ raw_notifier_chain_register(&dummycon_output_nh, nb); ++ ++ if (dummycon_putc_called) ++ nb->notifier_call(nb, 0, NULL); ++} ++ ++void dummycon_unregister_output_notifier(struct notifier_block *nb) ++{ ++ raw_notifier_chain_unregister(&dummycon_output_nh, nb); ++} ++ ++static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) ++{ ++ dummycon_putc_called = true; ++ raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); ++} ++ ++static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, ++ int count, int ypos, int xpos) ++{ ++ int i; ++ ++ if (!dummycon_putc_called) { ++ /* Ignore erases */ ++ for (i = 0 ; i < count; i++) { ++ if (s[i] != vc->vc_video_erase_char) ++ break; ++ } ++ if (i == count) ++ return; ++ ++ dummycon_putc_called = true; ++ } ++ ++ raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); ++} ++ ++static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) ++{ ++ /* Redraw, so that we get putc(s) for output done while blanked */ ++ return 1; ++} ++#else ++static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } ++static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, ++ int count, int ypos, int xpos) { } ++static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) ++{ ++ return 0; ++} ++#endif ++ + static const char *dummycon_startup(void) + { + return "dummy device"; +@@ -44,9 +103,6 @@ static void dummycon_init(struct vc_data *vc, int init) + static void dummycon_deinit(struct vc_data *vc) { } + static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height, + int width) { } +-static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } +-static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, +- int count, int ypos, int xpos) { } + static void dummycon_cursor(struct vc_data *vc, int mode) { } + + static bool dummycon_scroll(struct vc_data *vc, unsigned int top, +@@ -61,11 +117,6 @@ static int dummycon_switch(struct vc_data *vc) + return 0; + } + +-static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) +-{ +- return 0; +-} +- + static int dummycon_font_set(struct vc_data *vc, struct console_font *font, + unsigned int flags) + { +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index cd8d52a967aa..5fb156bdcf4e 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -129,6 +129,12 @@ static inline void fbcon_map_override(void) + } + #endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */ + ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++static bool deferred_takeover = true; ++#else ++#define deferred_takeover false ++#endif ++ + /* font data */ + static char fontname[40]; + +@@ -499,6 +505,12 @@ static int __init fb_console_setup(char *this_opt) + margin_color = simple_strtoul(options, &options, 0); + continue; + } ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++ if (!strcmp(options, "nodefer")) { ++ deferred_takeover = false; ++ continue; ++ } ++#endif + } + return 1; + } +@@ -3100,6 +3112,9 @@ static int fbcon_fb_unregistered(struct fb_info *info) + + WARN_CONSOLE_UNLOCKED(); + ++ if (deferred_takeover) ++ return 0; ++ + idx = info->node; + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == idx) +@@ -3140,6 +3155,13 @@ static void fbcon_remap_all(int idx) + + WARN_CONSOLE_UNLOCKED(); + ++ if (deferred_takeover) { ++ for (i = first_fb_vc; i <= last_fb_vc; i++) ++ con2fb_map_boot[i] = idx; ++ fbcon_map_override(); ++ return; ++ } ++ + for (i = first_fb_vc; i <= last_fb_vc; i++) + set_con2fb_map(i, idx, 0); + +@@ -3191,6 +3213,11 @@ static int fbcon_fb_registered(struct fb_info *info) + idx = info->node; + fbcon_select_primary(info); + ++ if (deferred_takeover) { ++ pr_info("fbcon: Deferring console take-over\n"); ++ return 0; ++ } ++ + if (info_idx == -1) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map_boot[i] == idx) { +@@ -3566,8 +3593,46 @@ static int fbcon_init_device(void) + return 0; + } + ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++static struct notifier_block fbcon_output_nb; ++ ++static int fbcon_output_notifier(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ int i; ++ ++ WARN_CONSOLE_UNLOCKED(); ++ ++ pr_info("fbcon: Taking over console\n"); ++ ++ dummycon_unregister_output_notifier(&fbcon_output_nb); ++ deferred_takeover = false; ++ logo_shown = FBCON_LOGO_DONTSHOW; ++ ++ for (i = 0; i < FB_MAX; i++) { ++ if (registered_fb[i]) ++ fbcon_fb_registered(registered_fb[i]); ++ } ++ ++ return NOTIFY_OK; ++} ++ ++static void fbcon_register_output_notifier(void) ++{ ++ fbcon_output_nb.notifier_call = fbcon_output_notifier; ++ dummycon_register_output_notifier(&fbcon_output_nb); ++} ++#else ++static inline void fbcon_register_output_notifier(void) {} ++#endif ++ + static void fbcon_start(void) + { ++ if (deferred_takeover) { ++ fbcon_register_output_notifier(); ++ return; ++ } ++ + if (num_registered_fb) { + int i; + +@@ -3594,6 +3659,13 @@ static void fbcon_exit(void) + if (fbcon_has_exited) + return; + ++#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER ++ if (deferred_takeover) { ++ dummycon_unregister_output_notifier(&fbcon_output_nb); ++ deferred_takeover = false; ++ } ++#endif ++ + kfree((void *)softback_buf); + softback_buf = 0UL; + +diff --git a/include/linux/console.h b/include/linux/console.h +index dfd6b0e97855..f59f3dbca65c 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -21,6 +21,7 @@ struct console_font_op; + struct console_font; + struct module; + struct tty_struct; ++struct notifier_block; + + /* + * this is what the terminal answers to a ESC-Z or csi0c query. +@@ -220,4 +221,8 @@ static inline bool vgacon_text_force(void) { return false; } + + extern void console_init(void); + ++/* For deferred console takeover */ ++void dummycon_register_output_notifier(struct notifier_block *nb); ++void dummycon_unregister_output_notifier(struct notifier_block *nb); ++ + #endif /* _LINUX_CONSOLE_H */ +-- +2.18.0 + diff --git a/0005-efi-bgrt-Drop-__initdata-from-bgrt_image_size.patch b/0005-efi-bgrt-Drop-__initdata-from-bgrt_image_size.patch new file mode 100644 index 0000000..ec1ff7f --- /dev/null +++ b/0005-efi-bgrt-Drop-__initdata-from-bgrt_image_size.patch @@ -0,0 +1,33 @@ +From 421b8aef3902426c4c3ebd23218c0ad282786e1d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 3 Jul 2018 17:43:10 +0200 +Subject: [PATCH 5/7] efi/bgrt: Drop __initdata from bgrt_image_size + +bgrt_image_size is necessary to (optionally) show the boot graphics from +the efifb code. The efifb driver is a platform driver, using a normal +driver probe() driver callback. So even though it is always builtin it +cannot reference __initdata. + +Acked-by: Ard Biesheuvel +Signed-off-by: Hans de Goede +Signed-off-by: Bartlomiej Zolnierkiewicz +--- + drivers/firmware/efi/efi-bgrt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c +index 50793fda7819..b22ccfb0c991 100644 +--- a/drivers/firmware/efi/efi-bgrt.c ++++ b/drivers/firmware/efi/efi-bgrt.c +@@ -20,7 +20,7 @@ + #include + + struct acpi_table_bgrt bgrt_tab; +-size_t __initdata bgrt_image_size; ++size_t bgrt_image_size; + + struct bmp_header { + u16 id; +-- +2.18.0 + diff --git a/0006-efifb-Copy-the-ACPI-BGRT-boot-graphics-to-the-frameb.patch b/0006-efifb-Copy-the-ACPI-BGRT-boot-graphics-to-the-frameb.patch new file mode 100644 index 0000000..706c2f3 --- /dev/null +++ b/0006-efifb-Copy-the-ACPI-BGRT-boot-graphics-to-the-frameb.patch @@ -0,0 +1,201 @@ +From a5f742d7ba70c702bcf67dd1fd8d5dde3f5042fc Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 3 Jul 2018 17:43:10 +0200 +Subject: [PATCH 6/7] efifb: Copy the ACPI BGRT boot graphics to the + framebuffer + +On systems where fbcon is configured for deferred console takeover, the +intend is for the framebuffer to show the boot graphics (e.g a vendor +logo) until some message (e.g. an error) is printed or a graphical +session takes over. + +Some firmware relies on the OS to show the boot graphics. + +This patch adds support to efifb to show the boot graphics and +automatically enables this when fbcon is configured for deferred +console takeover. + +Signed-off-by: Hans de Goede +Signed-off-by: Bartlomiej Zolnierkiewicz +--- + drivers/video/fbdev/efifb.c | 140 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 140 insertions(+) + +diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c +index 46a4484e3da7..fa01eecc0a55 100644 +--- a/drivers/video/fbdev/efifb.c ++++ b/drivers/video/fbdev/efifb.c +@@ -9,16 +9,39 @@ + + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + #include