Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753924AbbDHJcL (ORCPT ); Wed, 8 Apr 2015 05:32:11 -0400 Received: from mail-lb0-f179.google.com ([209.85.217.179]:36060 "EHLO mail-lb0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753666AbbDHJcG (ORCPT ); Wed, 8 Apr 2015 05:32:06 -0400 From: Alexander Kuleshov To: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Greg Kroah-Hartman , Yinghai Lu Cc: linux-kernel@vger.kernel.org, Alexander Kuleshov Subject: [PATCH 2/2] x86/earlyprintk: setup earlyprintk as early as possible Date: Wed, 8 Apr 2015 15:31:59 +0600 Message-Id: <1428485519-25587-1-git-send-email-kuleshovmail@gmail.com> X-Mailer: git-send-email 2.3.3.611.g09038fc.dirty In-Reply-To: <1428485466-24326-1-git-send-email-kuleshovmail@gmail.com> References: <1428485466-24326-1-git-send-email-kuleshovmail@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5647 Lines: 167 As setup_early_printk passed to the early_param, it will be usable only after 'parse_early_param' function will be called from the 'setup_arch'. So we have earlyprintk during early boot and decompression. Next point after decompression of the kernel where we can use early_printk is after call of the 'parse_early_param'. This patch makes setup_early_printk visible for head{32,64}.c So 'early_printk' function will be usabable after decompression of the kernel and before parse_early_param will be called. It also must be safe if CONFIG_CMDLINE_BOOL and CONFIG_CMDLINE_OVERRIDE are set, because setup_cmdline function will be called before setup_early_printk. Tested it with qemu, so early_printk() is usable and prints to serial console right after setup_early_printk function called from arch/x86/kerne/head64.c Changes v1->v2: * Comment added before the setup_early_printk call; * Added information about testing to the commit message. Changes v2->v3: * Call setup_cmdline before setup_early_printk; * setup_early_printk call wrapped with the setup_early_serial_console which checks that 'serial' given to the earlyprintk command line option. This prevents call of the setup_early_printk with the given pciserial/dbgp/efi, because they are using early_ioremap. Signed-off-by: Alexander Kuleshov --- arch/x86/kernel/early_printk.c | 2 +- arch/x86/kernel/head.c | 14 ++++++++++++++ arch/x86/kernel/head32.c | 2 ++ arch/x86/kernel/head64.c | 7 ++++++- include/linux/printk.h | 4 ++++ kernel/printk/printk.c | 11 +++++++---- 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index a62536a..19a94e0 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -329,7 +329,7 @@ static inline void early_console_register(struct console *con, int keep_early) register_console(early_console); } -static int __init setup_early_printk(char *buf) +int __init setup_early_printk(char *buf) { int keep; diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c index 992f442..b6e72aa 100644 --- a/arch/x86/kernel/head.c +++ b/arch/x86/kernel/head.c @@ -69,3 +69,17 @@ void __init reserve_ebda_region(void) /* reserve all memory between lowmem and the 1MB mark */ memblock_reserve(lowmem, 0x100000 - lowmem); } + +void setup_early_serial_console() { +#ifdef CONFIG_EARLY_PRINTK + char *arg; + + arg = strstr(boot_command_line, "earlyprintk=serial"); + if (!arg) + arg = strstr(boot_command_line, "earlyprintk=ttyS"); + if (!arg) + return; + + setup_early_printk(boot_command_line); +#endif +} diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 7ad0ad0..64c7a80 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -32,6 +32,8 @@ static void __init i386_default_early_setup(void) asmlinkage __visible void __init i386_start_kernel(void) { setup_cmdline(); + /* setup serial console as early as possible */ + setup_early_serial_console(); cr4_init_shadow(); sanitize_boot_params(&boot_params); diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 6eea2de..f0c03bd 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -172,12 +172,15 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) copy_bootdata(__va(real_mode_data)); setup_cmdline(); + /* setup serial console as early as possible */ + setup_early_serial_console(); /* * Load microcode early on BSP. */ load_ucode_bsp(); + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG) early_printk("Kernel alive\n"); @@ -193,8 +196,10 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) void __init x86_64_start_reservations(char *real_mode_data) { /* version is always not zero if it is copied */ - if (!boot_params.hdr.version) + if (!boot_params.hdr.version) { copy_bootdata(__va(real_mode_data)); + setup_early_serial_console(); + } reserve_ebda_region(); diff --git a/include/linux/printk.h b/include/linux/printk.h index baa3f97..17358dd 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -115,9 +115,13 @@ int no_printk(const char *fmt, ...) #ifdef CONFIG_EARLY_PRINTK extern asmlinkage __printf(1, 2) void early_printk(const char *fmt, ...); +int setup_early_printk(char *buf); +void setup_early_serial_console(void); #else static inline __printf(1, 2) __cold void early_printk(const char *s, ...) { } +int setup_early_printk(char *buf) { } +static void setup_early_serial_console(void) { } #endif typedef int(*printk_func_t)(const char *fmt, va_list args); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index bb0635b..e56285c 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2409,11 +2409,14 @@ void register_console(struct console *newcon) struct console_cmdline *c; if (console_drivers) - for_each_console(bcon) - if (WARN(bcon == newcon, - "console '%s%d' already registered\n", - bcon->name, bcon->index)) + for_each_console(bcon) { + /* not again */ + if (bcon == newcon) { + printk(KERN_INFO "console '%s%d' already registered\n", + bcon->name, bcon->index); return; + } + } /* * before we register a new CON_BOOT console, make sure we don't -- 2.3.3.611.g09038fc.dirty -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/