2015-05-10 19:14:00

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 0/2] x86/earlyprintk: setup earlyprintk as early as possible

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'.

These patchset provides two patches where:

1. Move handling of the builtin command line to the separate function
from the setup_arch. Now we can call it from the arch/x86/kernel/head{32,64}.c,
and find 'earlyprintk' kernel command line paramter there.

2. Provide setup_serial_console function to setup serial earlyprintk in the
arch/x86/kernel/head{32,64}.c

Alexander Kuleshov (2):
x86/setup: update boot_command_line with builtin_cmdline in separate
function
x86/earlyprintk: setup earlyprintk as early as possible

arch/x86/include/asm/serial.h | 2 ++
arch/x86/include/asm/setup.h | 3 ++-
arch/x86/kernel/early_printk.c | 25 +++++++++++++++++++++++++
arch/x86/kernel/head32.c | 6 ++++++
arch/x86/kernel/head64.c | 7 +++++++
arch/x86/kernel/setup.c | 28 +++++++++++++++-------------
6 files changed, 57 insertions(+), 14 deletions(-)

--
2.4.0


2015-05-10 19:14:21

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 1/2 v2] x86/setup: update boot_command_line with builtin_cmdline in separate function

This patch introduces setup_builtin_cmdline function which appends/overrides
boot_command_line with the builtin_cmdline if CONFIG_CMDLINE_BOOL is set.
Previously this functional was in the setup_arch, but we need to move
it for getting actual command line as early as possible in the
arch/x86/kernel/head{32,64}.c for the earlyprintk.

Changes:

v1->v2: function renamed from setup_cmdline to setup_builtin_cmdline to
avoid conflict with the setup_cmdline from the arch/x86/kernel/kexec-bzimage64.c

Signed-off-by: Alexander Kuleshov <[email protected]>
---
arch/x86/include/asm/setup.h | 3 ++-
arch/x86/kernel/head32.c | 1 +
arch/x86/kernel/head64.c | 1 +
arch/x86/kernel/setup.c | 28 +++++++++++++++-------------
4 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index f69e06b..dde474a 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -24,6 +24,7 @@
#define OLD_CL_ADDRESS 0x020 /* Relative to real mode data */
#define NEW_CL_POINTER 0x228 /* Relative to real mode data */

+
#ifndef __ASSEMBLY__
#include <asm/bootparam.h>
#include <asm/x86_init.h>
@@ -117,8 +118,8 @@ asmlinkage void __init i386_start_kernel(void);
#else
asmlinkage void __init x86_64_start_kernel(char *real_mode);
asmlinkage void __init x86_64_start_reservations(char *real_mode_data);
-
#endif /* __i386__ */
+void __init setup_builtin_cmdline(void);
#endif /* _SETUP */
#else
#define RESERVE_BRK(name,sz) \
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 2911ef3..95eed21 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -31,6 +31,7 @@ static void __init i386_default_early_setup(void)

asmlinkage __visible void __init i386_start_kernel(void)
{
+ setup_builtin_cmdline();
cr4_init_shadow();
sanitize_boot_params(&boot_params);

diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 2b55ee6..df290d1 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -171,6 +171,7 @@ 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));
+ setup_builtin_cmdline();

/*
* Load microcode early on BSP.
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d74ac33..c9d1896 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -845,6 +845,21 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
return 0;
}

+void __init setup_builtin_cmdline(void) {
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+ if (builtin_cmdline[0]) {
+ /* append boot loader cmdline to builtin */
+ strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
+ strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+ }
+#endif
+#endif
+}
+
/*
* Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures
@@ -973,19 +988,6 @@ void __init setup_arch(char **cmdline_p)
bss_resource.start = __pa_symbol(__bss_start);
bss_resource.end = __pa_symbol(__bss_stop)-1;

-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
- if (builtin_cmdline[0]) {
- /* append boot loader cmdline to builtin */
- strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
- strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
- }
-#endif
-#endif
-
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;

--
2.4.0

2015-05-10 19:14:30

by Alexander Kuleshov

[permalink] [raw]
Subject: [PATCH 2/2 v4] x86/earlyprintk: setup earlyprintk as early as possible

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 introduces setup_early_serial_console function which will search the
'earlyprintk' parameter in the kernel command line and setup 'earlyprintk'
depends on result. It allows to make 'earlyprintk' 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 the
setup_builtin_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.

Changes v3->v4:

* Move setup_early_serial_console from the include/linux/printk.h
to the arch/x86/include/asm/serial.h, because this function is only
for x86 now.

Changes v4->v5:

* Call setup_builtin_cmdline instead of setup_cmdline

Signed-off-by: Alexander Kuleshov <[email protected]>
---
arch/x86/include/asm/serial.h | 2 ++
arch/x86/kernel/early_printk.c | 25 +++++++++++++++++++++++++
arch/x86/kernel/head32.c | 5 +++++
arch/x86/kernel/head64.c | 8 +++++++-
4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h
index 8378b8c..be3b73a 100644
--- a/arch/x86/include/asm/serial.h
+++ b/arch/x86/include/asm/serial.h
@@ -26,4 +26,6 @@
{ .uart = 0, BASE_BAUD, 0x3E8, 4, STD_COMX_FLAGS }, /* ttyS2 */ \
{ .uart = 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */

+int __init setup_early_serial_console(void);
+
#endif /* _ASM_X86_SERIAL_H */
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 89427d8..d7cc0b1 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -385,4 +385,29 @@ static int __init setup_early_printk(char *buf)
return 0;
}

+int __init setup_early_serial_console(void)
+{
+#ifdef CONFIG_EARLY_PRINTK
+ char *arg;
+
+ /*
+ * make sure that we have:
+ * "serial,0x3f8,115200"
+ * "serial,ttyS0,115200"
+ * "ttyS0,115200"
+ */
+ arg = strstr(boot_command_line, "earlyprintk=serial");
+ if (!arg)
+ arg = strstr(boot_command_line, "earlyprintk=ttyS");
+ if (!arg)
+ return -1;
+
+ arg = strstr(boot_command_line, "earlyprintk=");
+ /* += strlen("earlyprintk"); */
+ arg += 12;
+
+ return setup_early_printk(arg);
+#endif
+}
+
early_param("earlyprintk", setup_early_printk);
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 95eed21..e863ecc 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -32,6 +32,11 @@ static void __init i386_default_early_setup(void)
asmlinkage __visible void __init i386_start_kernel(void)
{
setup_builtin_cmdline();
+ setup_early_serial_console();
+
+ if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG)
+ early_printk("Kernel alive\n");
+
cr4_init_shadow();
sanitize_boot_params(&boot_params);

diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index df290d1..905e602 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -28,6 +28,7 @@
#include <asm/bootparam_utils.h>
#include <asm/microcode.h>
#include <asm/kasan.h>
+#include <asm/serial.h>

/*
* Manage page tables very early on.
@@ -171,7 +172,12 @@ 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));
- setup_builtin_cmdline();
+
+ setup_builtin_cmdline();
+ setup_early_serial_console();
+
+ if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG)
+ early_printk("Kernel alive\n");

/*
* Load microcode early on BSP.
--
2.4.0

2015-05-11 07:22:57

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 2/2 v4] x86/earlyprintk: setup earlyprintk as early as possible

On Mon, 2015-05-11 at 01:14 +0600, Alexander Kuleshov wrote:
> 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 introduces setup_early_serial_console function which will search the
> 'earlyprintk' parameter in the kernel command line and setup 'earlyprintk'
> depends on result. It allows to make 'earlyprintk' 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 the
> setup_builtin_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.
>
> Changes v3->v4:
>
> * Move setup_early_serial_console from the include/linux/printk.h
> to the arch/x86/include/asm/serial.h, because this function is only
> for x86 now.
>
> Changes v4->v5:
>
> * Call setup_builtin_cmdline instead of setup_cmdline

Please,
a) use back chronological order for changes,
b) put changelogs to coverletter,
c) use versioning for whole patch series (--subject-prefix is you friend
here).

>
> Signed-off-by: Alexander Kuleshov <[email protected]>
> ---
> arch/x86/include/asm/serial.h | 2 ++
> arch/x86/kernel/early_printk.c | 25 +++++++++++++++++++++++++
> arch/x86/kernel/head32.c | 5 +++++
> arch/x86/kernel/head64.c | 8 +++++++-
> 4 files changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h
> index 8378b8c..be3b73a 100644
> --- a/arch/x86/include/asm/serial.h
> +++ b/arch/x86/include/asm/serial.h
> @@ -26,4 +26,6 @@
> { .uart = 0, BASE_BAUD, 0x3E8, 4, STD_COMX_FLAGS }, /* ttyS2 */ \
> { .uart = 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
>
> +int __init setup_early_serial_console(void);
> +
> #endif /* _ASM_X86_SERIAL_H */
> diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
> index 89427d8..d7cc0b1 100644
> --- a/arch/x86/kernel/early_printk.c
> +++ b/arch/x86/kernel/early_printk.c
> @@ -385,4 +385,29 @@ static int __init setup_early_printk(char *buf)
> return 0;
> }
>
> +int __init setup_early_serial_console(void)
> +{
> +#ifdef CONFIG_EARLY_PRINTK
> + char *arg;
> +
> + /*
> + * make sure that we have:
> + * "serial,0x3f8,115200"
> + * "serial,ttyS0,115200"
> + * "ttyS0,115200"
> + */
> + arg = strstr(boot_command_line, "earlyprintk=serial");
> + if (!arg)
> + arg = strstr(boot_command_line, "earlyprintk=ttyS");
> + if (!arg)
> + return -1;
> +
> + arg = strstr(boot_command_line, "earlyprintk=");
> + /* += strlen("earlyprintk"); */
> + arg += 12;
> +
> + return setup_early_printk(arg);
> +#endif
> +}
> +
> early_param("earlyprintk", setup_early_printk);
> diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
> index 95eed21..e863ecc 100644
> --- a/arch/x86/kernel/head32.c
> +++ b/arch/x86/kernel/head32.c
> @@ -32,6 +32,11 @@ static void __init i386_default_early_setup(void)
> asmlinkage __visible void __init i386_start_kernel(void)
> {
> setup_builtin_cmdline();
> + setup_early_serial_console();
> +
> + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG)
> + early_printk("Kernel alive\n");
> +
> cr4_init_shadow();
> sanitize_boot_params(&boot_params);
>
> diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
> index df290d1..905e602 100644
> --- a/arch/x86/kernel/head64.c
> +++ b/arch/x86/kernel/head64.c
> @@ -28,6 +28,7 @@
> #include <asm/bootparam_utils.h>
> #include <asm/microcode.h>
> #include <asm/kasan.h>
> +#include <asm/serial.h>
>
> /*
> * Manage page tables very early on.
> @@ -171,7 +172,12 @@ 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));
> - setup_builtin_cmdline();
> +
> + setup_builtin_cmdline();
> + setup_early_serial_console();
> +
> + if (console_loglevel >= CONSOLE_LOGLEVEL_DEBUG)
> + early_printk("Kernel alive\n");
>
> /*
> * Load microcode early on BSP.


--
Andy Shevchenko <[email protected]>
Intel Finland Oy

2015-05-11 07:27:41

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH 0/2] x86/earlyprintk: setup earlyprintk as early as possible

On Mon, 2015-05-11 at 01:13 +0600, Alexander Kuleshov wrote:
> 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'.

>From this description is hard to understand what is rationale of the
proposed changes. Can you rephrase it?

>
> These patchset provides two patches where:
>
> 1. Move handling of the builtin command line to the separate function
> from the setup_arch. Now we can call it from the arch/x86/kernel/head{32,64}.c,
> and find 'earlyprintk' kernel command line paramter there.
>
> 2. Provide setup_serial_console function to setup serial earlyprintk in the
> arch/x86/kernel/head{32,64}.c
>
> Alexander Kuleshov (2):
> x86/setup: update boot_command_line with builtin_cmdline in separate
> function
> x86/earlyprintk: setup earlyprintk as early as possible
>
> arch/x86/include/asm/serial.h | 2 ++
> arch/x86/include/asm/setup.h | 3 ++-
> arch/x86/kernel/early_printk.c | 25 +++++++++++++++++++++++++
> arch/x86/kernel/head32.c | 6 ++++++
> arch/x86/kernel/head64.c | 7 +++++++
> arch/x86/kernel/setup.c | 28 +++++++++++++++-------------
> 6 files changed, 57 insertions(+), 14 deletions(-)
>


--
Andy Shevchenko <[email protected]>
Intel Finland Oy

2015-05-11 09:56:11

by Alexander Kuleshov

[permalink] [raw]
Subject: Re: [PATCH 0/2] x86/earlyprintk: setup earlyprintk as early as possible

Hello Andy,

Thank you for feedback. Will fix and resend.

2015-05-11 13:27 GMT+06:00 Andy Shevchenko <[email protected]>:
> On Mon, 2015-05-11 at 01:13 +0600, Alexander Kuleshov wrote:
>> 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'.
>
> From this description is hard to understand what is rationale of the
> proposed changes. Can you rephrase it?
>
>>
>> These patchset provides two patches where:
>>
>> 1. Move handling of the builtin command line to the separate function
>> from the setup_arch. Now we can call it from the arch/x86/kernel/head{32,64}.c,
>> and find 'earlyprintk' kernel command line paramter there.
>>
>> 2. Provide setup_serial_console function to setup serial earlyprintk in the
>> arch/x86/kernel/head{32,64}.c
>>
>> Alexander Kuleshov (2):
>> x86/setup: update boot_command_line with builtin_cmdline in separate
>> function
>> x86/earlyprintk: setup earlyprintk as early as possible
>>
>> arch/x86/include/asm/serial.h | 2 ++
>> arch/x86/include/asm/setup.h | 3 ++-
>> arch/x86/kernel/early_printk.c | 25 +++++++++++++++++++++++++
>> arch/x86/kernel/head32.c | 6 ++++++
>> arch/x86/kernel/head64.c | 7 +++++++
>> arch/x86/kernel/setup.c | 28 +++++++++++++++-------------
>> 6 files changed, 57 insertions(+), 14 deletions(-)
>>
>
>
> --
> Andy Shevchenko <[email protected]>
> Intel Finland Oy
>



--
_________________________
0xAX