aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c315
1 files changed, 231 insertions, 84 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 2ddbdc73aade..35185392173f 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -31,6 +31,7 @@
31#include <linux/smp.h> 31#include <linux/smp.h>
32#include <linux/security.h> 32#include <linux/security.h>
33#include <linux/bootmem.h> 33#include <linux/bootmem.h>
34#include <linux/memblock.h>
34#include <linux/syscalls.h> 35#include <linux/syscalls.h>
35#include <linux/kexec.h> 36#include <linux/kexec.h>
36#include <linux/kdb.h> 37#include <linux/kdb.h>
@@ -53,7 +54,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
53#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) 54#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
54 55
55/* printk's without a loglevel use this.. */ 56/* printk's without a loglevel use this.. */
56#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ 57#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
57 58
58/* We show everything that is MORE important than this.. */ 59/* We show everything that is MORE important than this.. */
59#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ 60#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
@@ -113,6 +114,11 @@ static unsigned con_start; /* Index into log_buf: next char to be sent to consol
113static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ 114static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */
114 115
115/* 116/*
117 * If exclusive_console is non-NULL then only this console is to be printed to.
118 */
119static struct console *exclusive_console;
120
121/*
116 * Array of consoles built from command line options (console=) 122 * Array of consoles built from command line options (console=)
117 */ 123 */
118struct console_cmdline 124struct console_cmdline
@@ -162,46 +168,74 @@ void log_buf_kexec_setup(void)
162} 168}
163#endif 169#endif
164 170
171/* requested log_buf_len from kernel cmdline */
172static unsigned long __initdata new_log_buf_len;
173
174/* save requested log_buf_len since it's too early to process it */
165static int __init log_buf_len_setup(char *str) 175static int __init log_buf_len_setup(char *str)
166{ 176{
167 unsigned size = memparse(str, &str); 177 unsigned size = memparse(str, &str);
168 unsigned long flags;
169 178
170 if (size) 179 if (size)
171 size = roundup_pow_of_two(size); 180 size = roundup_pow_of_two(size);
172 if (size > log_buf_len) { 181 if (size > log_buf_len)
173 unsigned start, dest_idx, offset; 182 new_log_buf_len = size;
174 char *new_log_buf;
175 183
176 new_log_buf = alloc_bootmem(size); 184 return 0;
177 if (!new_log_buf) { 185}
178 printk(KERN_WARNING "log_buf_len: allocation failed\n"); 186early_param("log_buf_len", log_buf_len_setup);
179 goto out;
180 }
181 187
182 spin_lock_irqsave(&logbuf_lock, flags); 188void __init setup_log_buf(int early)
183 log_buf_len = size; 189{
184 log_buf = new_log_buf; 190 unsigned long flags;
185 191 unsigned start, dest_idx, offset;
186 offset = start = min(con_start, log_start); 192 char *new_log_buf;
187 dest_idx = 0; 193 int free;
188 while (start != log_end) { 194
189 log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)]; 195 if (!new_log_buf_len)
190 start++; 196 return;
191 dest_idx++; 197
192 } 198 if (early) {
193 log_start -= offset; 199 unsigned long mem;
194 con_start -= offset;
195 log_end -= offset;
196 spin_unlock_irqrestore(&logbuf_lock, flags);
197 200
198 printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len); 201 mem = memblock_alloc(new_log_buf_len, PAGE_SIZE);
202 if (mem == MEMBLOCK_ERROR)
203 return;
204 new_log_buf = __va(mem);
205 } else {
206 new_log_buf = alloc_bootmem_nopanic(new_log_buf_len);
199 } 207 }
200out:
201 return 1;
202}
203 208
204__setup("log_buf_len=", log_buf_len_setup); 209 if (unlikely(!new_log_buf)) {
210 pr_err("log_buf_len: %ld bytes not available\n",
211 new_log_buf_len);
212 return;
213 }
214
215 spin_lock_irqsave(&logbuf_lock, flags);
216 log_buf_len = new_log_buf_len;
217 log_buf = new_log_buf;
218 new_log_buf_len = 0;
219 free = __LOG_BUF_LEN - log_end;
220
221 offset = start = min(con_start, log_start);
222 dest_idx = 0;
223 while (start != log_end) {
224 unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1);
225
226 log_buf[dest_idx] = __log_buf[log_idx_mask];
227 start++;
228 dest_idx++;
229 }
230 log_start -= offset;
231 con_start -= offset;
232 log_end -= offset;
233 spin_unlock_irqrestore(&logbuf_lock, flags);
234
235 pr_info("log_buf_len: %d\n", log_buf_len);
236 pr_info("early log buf free: %d(%d%%)\n",
237 free, (free * 100) / __LOG_BUF_LEN);
238}
205 239
206#ifdef CONFIG_BOOT_PRINTK_DELAY 240#ifdef CONFIG_BOOT_PRINTK_DELAY
207 241
@@ -262,25 +296,47 @@ int dmesg_restrict = 1;
262int dmesg_restrict; 296int dmesg_restrict;
263#endif 297#endif
264 298
299static int syslog_action_restricted(int type)
300{
301 if (dmesg_restrict)
302 return 1;
303 /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
304 return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
305}
306
307static int check_syslog_permissions(int type, bool from_file)
308{
309 /*
310 * If this is from /proc/kmsg and we've already opened it, then we've
311 * already done the capabilities checks at open time.
312 */
313 if (from_file && type != SYSLOG_ACTION_OPEN)
314 return 0;
315
316 if (syslog_action_restricted(type)) {
317 if (capable(CAP_SYSLOG))
318 return 0;
319 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
320 if (capable(CAP_SYS_ADMIN)) {
321 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
322 "but no CAP_SYSLOG (deprecated).\n");
323 return 0;
324 }
325 return -EPERM;
326 }
327 return 0;
328}
329
265int do_syslog(int type, char __user *buf, int len, bool from_file) 330int do_syslog(int type, char __user *buf, int len, bool from_file)
266{ 331{
267 unsigned i, j, limit, count; 332 unsigned i, j, limit, count;
268 int do_clear = 0; 333 int do_clear = 0;
269 char c; 334 char c;
270 int error = 0; 335 int error;
271 336
272 /* 337 error = check_syslog_permissions(type, from_file);
273 * If this is from /proc/kmsg we only do the capabilities checks 338 if (error)
274 * at open time. 339 goto out;
275 */
276 if (type == SYSLOG_ACTION_OPEN || !from_file) {
277 if (dmesg_restrict && !capable(CAP_SYSLOG))
278 goto warn; /* switch to return -EPERM after 2.6.39 */
279 if ((type != SYSLOG_ACTION_READ_ALL &&
280 type != SYSLOG_ACTION_SIZE_BUFFER) &&
281 !capable(CAP_SYSLOG))
282 goto warn; /* switch to return -EPERM after 2.6.39 */
283 }
284 340
285 error = security_syslog(type); 341 error = security_syslog(type);
286 if (error) 342 if (error)
@@ -423,12 +479,6 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
423 } 479 }
424out: 480out:
425 return error; 481 return error;
426warn:
427 /* remove after 2.6.39 */
428 if (capable(CAP_SYS_ADMIN))
429 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
430 "but no CAP_SYSLOG (deprecated and denied).\n");
431 return -EPERM;
432} 482}
433 483
434SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) 484SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
@@ -460,6 +510,8 @@ static void __call_console_drivers(unsigned start, unsigned end)
460 struct console *con; 510 struct console *con;
461 511
462 for_each_console(con) { 512 for_each_console(con) {
513 if (exclusive_console && con != exclusive_console)
514 continue;
463 if ((con->flags & CON_ENABLED) && con->write && 515 if ((con->flags & CON_ENABLED) && con->write &&
464 (cpu_online(smp_processor_id()) || 516 (cpu_online(smp_processor_id()) ||
465 (con->flags & CON_ANYTIME))) 517 (con->flags & CON_ANYTIME)))
@@ -499,6 +551,71 @@ static void _call_console_drivers(unsigned start,
499} 551}
500 552
501/* 553/*
554 * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the
555 * lower 3 bit are the log level, the rest are the log facility. In case
556 * userspace passes usual userspace syslog messages to /dev/kmsg or
557 * /dev/ttyprintk, the log prefix might contain the facility. Printk needs
558 * to extract the correct log level for in-kernel processing, and not mangle
559 * the original value.
560 *
561 * If a prefix is found, the length of the prefix is returned. If 'level' is
562 * passed, it will be filled in with the log level without a possible facility
563 * value. If 'special' is passed, the special printk prefix chars are accepted
564 * and returned. If no valid header is found, 0 is returned and the passed
565 * variables are not touched.
566 */
567static size_t log_prefix(const char *p, unsigned int *level, char *special)
568{
569 unsigned int lev = 0;
570 char sp = '\0';
571 size_t len;
572
573 if (p[0] != '<' || !p[1])
574 return 0;
575 if (p[2] == '>') {
576 /* usual single digit level number or special char */
577 switch (p[1]) {
578 case '0' ... '7':
579 lev = p[1] - '0';
580 break;
581 case 'c': /* KERN_CONT */
582 case 'd': /* KERN_DEFAULT */
583 sp = p[1];
584 break;
585 default:
586 return 0;
587 }
588 len = 3;
589 } else {
590 /* multi digit including the level and facility number */
591 char *endp = NULL;
592
593 if (p[1] < '0' && p[1] > '9')
594 return 0;
595
596 lev = (simple_strtoul(&p[1], &endp, 10) & 7);
597 if (endp == NULL || endp[0] != '>')
598 return 0;
599 len = (endp + 1) - p;
600 }
601
602 /* do not accept special char if not asked for */
603 if (sp && !special)
604 return 0;
605
606 if (special) {
607 *special = sp;
608 /* return special char, do not touch level */
609 if (sp)
610 return len;
611 }
612
613 if (level)
614 *level = lev;
615 return len;
616}
617
618/*
502 * Call the console drivers, asking them to write out 619 * Call the console drivers, asking them to write out
503 * log_buf[start] to log_buf[end - 1]. 620 * log_buf[start] to log_buf[end - 1].
504 * The console_lock must be held. 621 * The console_lock must be held.
@@ -513,13 +630,9 @@ static void call_console_drivers(unsigned start, unsigned end)
513 cur_index = start; 630 cur_index = start;
514 start_print = start; 631 start_print = start;
515 while (cur_index != end) { 632 while (cur_index != end) {
516 if (msg_level < 0 && ((end - cur_index) > 2) && 633 if (msg_level < 0 && ((end - cur_index) > 2)) {
517 LOG_BUF(cur_index + 0) == '<' && 634 /* strip log prefix */
518 LOG_BUF(cur_index + 1) >= '0' && 635 cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL);
519 LOG_BUF(cur_index + 1) <= '7' &&
520 LOG_BUF(cur_index + 2) == '>') {
521 msg_level = LOG_BUF(cur_index + 1) - '0';
522 cur_index += 3;
523 start_print = cur_index; 636 start_print = cur_index;
524 } 637 }
525 while (cur_index != end) { 638 while (cur_index != end) {
@@ -717,6 +830,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
717 unsigned long flags; 830 unsigned long flags;
718 int this_cpu; 831 int this_cpu;
719 char *p; 832 char *p;
833 size_t plen;
834 char special;
720 835
721 boot_delay_msec(); 836 boot_delay_msec();
722 printk_delay(); 837 printk_delay();
@@ -757,45 +872,52 @@ asmlinkage int vprintk(const char *fmt, va_list args)
757 printed_len += vscnprintf(printk_buf + printed_len, 872 printed_len += vscnprintf(printk_buf + printed_len,
758 sizeof(printk_buf) - printed_len, fmt, args); 873 sizeof(printk_buf) - printed_len, fmt, args);
759 874
760
761 p = printk_buf; 875 p = printk_buf;
762 876
763 /* Do we have a loglevel in the string? */ 877 /* Read log level and handle special printk prefix */
764 if (p[0] == '<') { 878 plen = log_prefix(p, &current_log_level, &special);
765 unsigned char c = p[1]; 879 if (plen) {
766 if (c && p[2] == '>') { 880 p += plen;
767 switch (c) { 881
768 case '0' ... '7': /* loglevel */ 882 switch (special) {
769 current_log_level = c - '0'; 883 case 'c': /* Strip <c> KERN_CONT, continue line */
770 /* Fallthrough - make sure we're on a new line */ 884 plen = 0;
771 case 'd': /* KERN_DEFAULT */ 885 break;
772 if (!new_text_line) { 886 case 'd': /* Strip <d> KERN_DEFAULT, start new line */
773 emit_log_char('\n'); 887 plen = 0;
774 new_text_line = 1; 888 default:
775 } 889 if (!new_text_line) {
776 /* Fallthrough - skip the loglevel */ 890 emit_log_char('\n');
777 case 'c': /* KERN_CONT */ 891 new_text_line = 1;
778 p += 3;
779 break;
780 } 892 }
781 } 893 }
782 } 894 }
783 895
784 /* 896 /*
785 * Copy the output into log_buf. If the caller didn't provide 897 * Copy the output into log_buf. If the caller didn't provide
786 * appropriate log level tags, we insert them here 898 * the appropriate log prefix, we insert them here
787 */ 899 */
788 for ( ; *p; p++) { 900 for (; *p; p++) {
789 if (new_text_line) { 901 if (new_text_line) {
790 /* Always output the token */
791 emit_log_char('<');
792 emit_log_char(current_log_level + '0');
793 emit_log_char('>');
794 printed_len += 3;
795 new_text_line = 0; 902 new_text_line = 0;
796 903
904 if (plen) {
905 /* Copy original log prefix */
906 int i;
907
908 for (i = 0; i < plen; i++)
909 emit_log_char(printk_buf[i]);
910 printed_len += plen;
911 } else {
912 /* Add log prefix */
913 emit_log_char('<');
914 emit_log_char(current_log_level + '0');
915 emit_log_char('>');
916 printed_len += 3;
917 }
918
797 if (printk_time) { 919 if (printk_time) {
798 /* Follow the token with the time */ 920 /* Add the current time stamp */
799 char tbuf[50], *tp; 921 char tbuf[50], *tp;
800 unsigned tlen; 922 unsigned tlen;
801 unsigned long long t; 923 unsigned long long t;
@@ -1144,6 +1266,11 @@ void console_unlock(void)
1144 local_irq_restore(flags); 1266 local_irq_restore(flags);
1145 } 1267 }
1146 console_locked = 0; 1268 console_locked = 0;
1269
1270 /* Release the exclusive_console once it is used */
1271 if (unlikely(exclusive_console))
1272 exclusive_console = NULL;
1273
1147 up(&console_sem); 1274 up(&console_sem);
1148 spin_unlock_irqrestore(&logbuf_lock, flags); 1275 spin_unlock_irqrestore(&logbuf_lock, flags);
1149 if (wake_klogd) 1276 if (wake_klogd)
@@ -1230,6 +1357,18 @@ void console_start(struct console *console)
1230} 1357}
1231EXPORT_SYMBOL(console_start); 1358EXPORT_SYMBOL(console_start);
1232 1359
1360static int __read_mostly keep_bootcon;
1361
1362static int __init keep_bootcon_setup(char *str)
1363{
1364 keep_bootcon = 1;
1365 printk(KERN_INFO "debug: skip boot console de-registration.\n");
1366
1367 return 0;
1368}
1369
1370early_param("keep_bootcon", keep_bootcon_setup);
1371
1233/* 1372/*
1234 * The console driver calls this routine during kernel initialization 1373 * The console driver calls this routine during kernel initialization
1235 * to register the console printing procedure with printk() and to 1374 * to register the console printing procedure with printk() and to
@@ -1366,6 +1505,12 @@ void register_console(struct console *newcon)
1366 spin_lock_irqsave(&logbuf_lock, flags); 1505 spin_lock_irqsave(&logbuf_lock, flags);
1367 con_start = log_start; 1506 con_start = log_start;
1368 spin_unlock_irqrestore(&logbuf_lock, flags); 1507 spin_unlock_irqrestore(&logbuf_lock, flags);
1508 /*
1509 * We're about to replay the log buffer. Only do this to the
1510 * just-registered console to avoid excessive message spam to
1511 * the already-registered consoles.
1512 */
1513 exclusive_console = newcon;
1369 } 1514 }
1370 console_unlock(); 1515 console_unlock();
1371 console_sysfs_notify(); 1516 console_sysfs_notify();
@@ -1377,7 +1522,9 @@ void register_console(struct console *newcon)
1377 * users know there might be something in the kernel's log buffer that 1522 * users know there might be something in the kernel's log buffer that
1378 * went to the bootconsole (that they do not see on the real console) 1523 * went to the bootconsole (that they do not see on the real console)
1379 */ 1524 */
1380 if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) { 1525 if (bcon &&
1526 ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
1527 !keep_bootcon) {
1381 /* we need to iterate through twice, to make sure we print 1528 /* we need to iterate through twice, to make sure we print
1382 * everything out, before we unregister the console(s) 1529 * everything out, before we unregister the console(s)
1383 */ 1530 */