printk: Give error on attempt to set log buffer length to over 2G
authorHe Zhe <zhe.he@windriver.com>
Sat, 29 Sep 2018 16:45:53 +0000 (00:45 +0800)
committerPetr Mladek <pmladek@suse.com>
Tue, 9 Oct 2018 12:02:05 +0000 (14:02 +0200)
The current printk() is ready to handle log buffer size up to 2G.
Give an explicit error for users who want to use larger log buffer.

Also fix printk formatting to show the 2G as a positive number.

Link: http://lkml.kernel.org/r/20181008135916.gg4kkmoki5bgtco5@pathway.suse.cz
Cc: rostedt@goodmis.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: He Zhe <zhe.he@windriver.com>
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
[pmladek: Fixed to the really safe limit 2GB.]
Signed-off-by: Petr Mladek <pmladek@suse.com>
kernel/printk/printk.c

index 15f3e70..fce696d 100644 (file)
@@ -440,6 +440,7 @@ static u32 clear_idx;
 /* record buffer */
 #define LOG_ALIGN __alignof__(struct printk_log)
 #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+#define LOG_BUF_LEN_MAX (u32)(1 << 31)
 static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
 static u32 log_buf_len = __LOG_BUF_LEN;
@@ -1040,18 +1041,23 @@ void log_buf_vmcoreinfo_setup(void)
 static unsigned long __initdata new_log_buf_len;
 
 /* we practice scaling the ring buffer by powers of 2 */
-static void __init log_buf_len_update(unsigned size)
+static void __init log_buf_len_update(u64 size)
 {
+       if (size > (u64)LOG_BUF_LEN_MAX) {
+               size = (u64)LOG_BUF_LEN_MAX;
+               pr_err("log_buf over 2G is not supported.\n");
+       }
+
        if (size)
                size = roundup_pow_of_two(size);
        if (size > log_buf_len)
-               new_log_buf_len = size;
+               new_log_buf_len = (unsigned long)size;
 }
 
 /* save requested log_buf_len since it's too early to process it */
 static int __init log_buf_len_setup(char *str)
 {
-       unsigned int size;
+       u64 size;
 
        if (!str)
                return -EINVAL;
@@ -1121,7 +1127,7 @@ void __init setup_log_buf(int early)
        }
 
        if (unlikely(!new_log_buf)) {
-               pr_err("log_buf_len: %ld bytes not available\n",
+               pr_err("log_buf_len: %lu bytes not available\n",
                        new_log_buf_len);
                return;
        }
@@ -1134,8 +1140,8 @@ void __init setup_log_buf(int early)
        memcpy(log_buf, __log_buf, __LOG_BUF_LEN);
        logbuf_unlock_irqrestore(flags);
 
-       pr_info("log_buf_len: %d bytes\n", log_buf_len);
-       pr_info("early log buf free: %d(%d%%)\n",
+       pr_info("log_buf_len: %u bytes\n", log_buf_len);
+       pr_info("early log buf free: %u(%u%%)\n",
                free, (free * 100) / __LOG_BUF_LEN);
 }