Skip to content

Commit 8b3a149

Browse files
committed
efi: earlycon: Reprobe after parsing config tables
Commit 732ea9d ("efi: libstub: Move screen_info handling to common code") reorganized the earlycon handling so that all architectures pass the screen_info data via a EFI config table instead of populating struct screen_info directly, as the latter is only possible when the EFI stub is baked into the kernel (and not into the decompressor). However, this means that struct screen_info may not have been populated yet by the time the earlycon probe takes place, and this results in a non-functional early console. So let's probe again right after parsing the config tables and populating struct screen_info. Note that this means that earlycon output starts a bit later than before, and so it may fail to capture issues that occur while doing the early EFI initialization. Fixes: 732ea9d ("efi: libstub: Move screen_info handling to common code") Reported-by: Shawn Guo <[email protected]> Tested-by: Shawn Guo <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 3c66bb1 commit 8b3a149

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

drivers/firmware/efi/earlycon.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,22 +215,32 @@ efi_earlycon_write(struct console *con, const char *str, unsigned int num)
215215
}
216216
}
217217

218+
static bool __initdata fb_probed;
219+
220+
void __init efi_earlycon_reprobe(void)
221+
{
222+
if (fb_probed)
223+
setup_earlycon("efifb");
224+
}
225+
218226
static int __init efi_earlycon_setup(struct earlycon_device *device,
219227
const char *opt)
220228
{
221229
struct screen_info *si;
222230
u16 xres, yres;
223231
u32 i;
224232

225-
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
233+
fb_wb = opt && !strcmp(opt, "ram");
234+
235+
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) {
236+
fb_probed = true;
226237
return -ENODEV;
238+
}
227239

228240
fb_base = screen_info.lfb_base;
229241
if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
230242
fb_base |= (u64)screen_info.ext_lfb_base << 32;
231243

232-
fb_wb = opt && !strcmp(opt, "ram");
233-
234244
si = &screen_info;
235245
xres = si->lfb_width;
236246
yres = si->lfb_height;

drivers/firmware/efi/efi-init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ static void __init init_screen_info(void)
7272
if (memblock_is_map_memory(screen_info.lfb_base))
7373
memblock_mark_nomap(screen_info.lfb_base,
7474
screen_info.lfb_size);
75+
76+
if (IS_ENABLED(CONFIG_EFI_EARLYCON))
77+
efi_earlycon_reprobe();
7578
}
7679
}
7780

include/linux/efi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ efi_guid_to_str(efi_guid_t *guid, char *out)
693693
}
694694

695695
extern void efi_init (void);
696+
extern void efi_earlycon_reprobe(void);
696697
#ifdef CONFIG_EFI
697698
extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */
698699
#else

0 commit comments

Comments
 (0)