Re: [PATCH v5 3/9] x86/head: Move early exception panic code into early_fixup_exception

From: Borislav Petkov
Date: Mon Apr 04 2016 - 15:38:18 EST


On Mon, Apr 04, 2016 at 06:00:42PM +0200, Peter Zijlstra wrote:
> On Mon, Apr 04, 2016 at 08:32:21AM -0700, Andy Lutomirski wrote:
>
> > Adding locking would be easy enough, wouldn't it?
>
> See patch in this thread..
>
> > But do any platforms really boot a second CPU before switching to real
> > printk?
>
> I _only_ use early_printk() as printk() is a quagmire of fail :-)

And since I'm the king of minimalistic changes... this below
works. However, the problem is that we need to pull up all that
early_param parsing in order to enable the early console, i.e.
"earlyprintk=ttyS0,115200" cmdline parsing.

And we can do all that after having setup the IDT. So I'd need to do
some early dancing with cmdline_find_option_bool(boot_command_line, ...
in asm or so. Need to think about it more.

---
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 1f4422d5c8d0..ad534226653b 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -130,6 +130,13 @@ static void __init copy_bootdata(char *real_mode_data)
}
}

+static int _early_printk(const char *fmt, va_list args)
+{
+ early_printk(fmt, args);
+
+ return 0;
+}
+
asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
{
int i;
@@ -164,6 +171,10 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
load_idt((const struct desc_ptr *)&idt_descr);

copy_bootdata(__va(real_mode_data));
+ parse_early_param();
+ this_cpu_write(printk_func, _early_printk);
+
+ printk("This is a test!\n");

/*
* Load microcode early on BSP.
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 2367ae07eb76..998d6c675549 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -882,6 +882,7 @@ void __init setup_arch(char **cmdline_p)
*/
__flush_tlb_all();
#else
+ this_cpu_write(printk_func, vprintk_default);
printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9ccbdf2c1453..97df81c97b2f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -169,6 +169,7 @@ void __init setup_log_buf(int early);
__printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...);
void dump_stack_print_info(const char *log_lvl);
void show_regs_print_info(const char *log_lvl);
+int vprintk_default(const char *fmt, va_list args);
#else
static inline __printf(1, 0)
int vprintk(const char *s, va_list args)

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.