aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c186
1 files changed, 98 insertions, 88 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index ab3ffc5b3b64..36231525e22f 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -39,16 +39,11 @@
39#include <linux/syslog.h> 39#include <linux/syslog.h>
40#include <linux/cpu.h> 40#include <linux/cpu.h>
41#include <linux/notifier.h> 41#include <linux/notifier.h>
42#include <linux/rculist.h>
42 43
43#include <asm/uaccess.h> 44#include <asm/uaccess.h>
44 45
45/* 46/*
46 * for_each_console() allows you to iterate on each console
47 */
48#define for_each_console(con) \
49 for (con = console_drivers; con != NULL; con = con->next)
50
51/*
52 * Architectures can override it: 47 * Architectures can override it:
53 */ 48 */
54void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) 49void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
@@ -102,7 +97,7 @@ static int console_locked, console_suspended;
102/* 97/*
103 * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars 98 * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
104 * It is also used in interesting ways to provide interlocking in 99 * It is also used in interesting ways to provide interlocking in
105 * release_console_sem(). 100 * console_unlock();.
106 */ 101 */
107static DEFINE_SPINLOCK(logbuf_lock); 102static DEFINE_SPINLOCK(logbuf_lock);
108 103
@@ -267,25 +262,47 @@ int dmesg_restrict = 1;
267int dmesg_restrict; 262int dmesg_restrict;
268#endif 263#endif
269 264
265static int syslog_action_restricted(int type)
266{
267 if (dmesg_restrict)
268 return 1;
269 /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
270 return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
271}
272
273static int check_syslog_permissions(int type, bool from_file)
274{
275 /*
276 * If this is from /proc/kmsg and we've already opened it, then we've
277 * already done the capabilities checks at open time.
278 */
279 if (from_file && type != SYSLOG_ACTION_OPEN)
280 return 0;
281
282 if (syslog_action_restricted(type)) {
283 if (capable(CAP_SYSLOG))
284 return 0;
285 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
286 if (capable(CAP_SYS_ADMIN)) {
287 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
288 "but no CAP_SYSLOG (deprecated).\n");
289 return 0;
290 }
291 return -EPERM;
292 }
293 return 0;
294}
295
270int do_syslog(int type, char __user *buf, int len, bool from_file) 296int do_syslog(int type, char __user *buf, int len, bool from_file)
271{ 297{
272 unsigned i, j, limit, count; 298 unsigned i, j, limit, count;
273 int do_clear = 0; 299 int do_clear = 0;
274 char c; 300 char c;
275 int error = 0; 301 int error;
276 302
277 /* 303 error = check_syslog_permissions(type, from_file);
278 * If this is from /proc/kmsg we only do the capabilities checks 304 if (error)
279 * at open time. 305 goto out;
280 */
281 if (type == SYSLOG_ACTION_OPEN || !from_file) {
282 if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
283 return -EPERM;
284 if ((type != SYSLOG_ACTION_READ_ALL &&
285 type != SYSLOG_ACTION_SIZE_BUFFER) &&
286 !capable(CAP_SYS_ADMIN))
287 return -EPERM;
288 }
289 306
290 error = security_syslog(type); 307 error = security_syslog(type);
291 if (error) 308 if (error)
@@ -500,7 +517,7 @@ static void _call_console_drivers(unsigned start,
500/* 517/*
501 * Call the console drivers, asking them to write out 518 * Call the console drivers, asking them to write out
502 * log_buf[start] to log_buf[end - 1]. 519 * log_buf[start] to log_buf[end - 1].
503 * The console_sem must be held. 520 * The console_lock must be held.
504 */ 521 */
505static void call_console_drivers(unsigned start, unsigned end) 522static void call_console_drivers(unsigned start, unsigned end)
506{ 523{
@@ -603,11 +620,11 @@ static int have_callable_console(void)
603 * 620 *
604 * This is printk(). It can be called from any context. We want it to work. 621 * This is printk(). It can be called from any context. We want it to work.
605 * 622 *
606 * We try to grab the console_sem. If we succeed, it's easy - we log the output and 623 * We try to grab the console_lock. If we succeed, it's easy - we log the output and
607 * call the console drivers. If we fail to get the semaphore we place the output 624 * call the console drivers. If we fail to get the semaphore we place the output
608 * into the log buffer and return. The current holder of the console_sem will 625 * into the log buffer and return. The current holder of the console_sem will
609 * notice the new output in release_console_sem() and will send it to the 626 * notice the new output in console_unlock(); and will send it to the
610 * consoles before releasing the semaphore. 627 * consoles before releasing the lock.
611 * 628 *
612 * One effect of this deferred printing is that code which calls printk() and 629 * One effect of this deferred printing is that code which calls printk() and
613 * then changes console_loglevel may break. This is because console_loglevel 630 * then changes console_loglevel may break. This is because console_loglevel
@@ -658,19 +675,19 @@ static inline int can_use_console(unsigned int cpu)
658/* 675/*
659 * Try to get console ownership to actually show the kernel 676 * Try to get console ownership to actually show the kernel
660 * messages from a 'printk'. Return true (and with the 677 * messages from a 'printk'. Return true (and with the
661 * console_semaphore held, and 'console_locked' set) if it 678 * console_lock held, and 'console_locked' set) if it
662 * is successful, false otherwise. 679 * is successful, false otherwise.
663 * 680 *
664 * This gets called with the 'logbuf_lock' spinlock held and 681 * This gets called with the 'logbuf_lock' spinlock held and
665 * interrupts disabled. It should return with 'lockbuf_lock' 682 * interrupts disabled. It should return with 'lockbuf_lock'
666 * released but interrupts still disabled. 683 * released but interrupts still disabled.
667 */ 684 */
668static int acquire_console_semaphore_for_printk(unsigned int cpu) 685static int console_trylock_for_printk(unsigned int cpu)
669 __releases(&logbuf_lock) 686 __releases(&logbuf_lock)
670{ 687{
671 int retval = 0; 688 int retval = 0;
672 689
673 if (!try_acquire_console_sem()) { 690 if (console_trylock()) {
674 retval = 1; 691 retval = 1;
675 692
676 /* 693 /*
@@ -826,12 +843,12 @@ asmlinkage int vprintk(const char *fmt, va_list args)
826 * actual magic (print out buffers, wake up klogd, 843 * actual magic (print out buffers, wake up klogd,
827 * etc). 844 * etc).
828 * 845 *
829 * The acquire_console_semaphore_for_printk() function 846 * The console_trylock_for_printk() function
830 * will release 'logbuf_lock' regardless of whether it 847 * will release 'logbuf_lock' regardless of whether it
831 * actually gets the semaphore or not. 848 * actually gets the semaphore or not.
832 */ 849 */
833 if (acquire_console_semaphore_for_printk(this_cpu)) 850 if (console_trylock_for_printk(this_cpu))
834 release_console_sem(); 851 console_unlock();
835 852
836 lockdep_on(); 853 lockdep_on();
837out_restore_irqs: 854out_restore_irqs:
@@ -992,7 +1009,7 @@ void suspend_console(void)
992 if (!console_suspend_enabled) 1009 if (!console_suspend_enabled)
993 return; 1010 return;
994 printk("Suspending console(s) (use no_console_suspend to debug)\n"); 1011 printk("Suspending console(s) (use no_console_suspend to debug)\n");
995 acquire_console_sem(); 1012 console_lock();
996 console_suspended = 1; 1013 console_suspended = 1;
997 up(&console_sem); 1014 up(&console_sem);
998} 1015}
@@ -1003,7 +1020,7 @@ void resume_console(void)
1003 return; 1020 return;
1004 down(&console_sem); 1021 down(&console_sem);
1005 console_suspended = 0; 1022 console_suspended = 0;
1006 release_console_sem(); 1023 console_unlock();
1007} 1024}
1008 1025
1009/** 1026/**
@@ -1026,21 +1043,21 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self,
1026 case CPU_DYING: 1043 case CPU_DYING:
1027 case CPU_DOWN_FAILED: 1044 case CPU_DOWN_FAILED:
1028 case CPU_UP_CANCELED: 1045 case CPU_UP_CANCELED:
1029 acquire_console_sem(); 1046 console_lock();
1030 release_console_sem(); 1047 console_unlock();
1031 } 1048 }
1032 return NOTIFY_OK; 1049 return NOTIFY_OK;
1033} 1050}
1034 1051
1035/** 1052/**
1036 * acquire_console_sem - lock the console system for exclusive use. 1053 * console_lock - lock the console system for exclusive use.
1037 * 1054 *
1038 * Acquires a semaphore which guarantees that the caller has 1055 * Acquires a lock which guarantees that the caller has
1039 * exclusive access to the console system and the console_drivers list. 1056 * exclusive access to the console system and the console_drivers list.
1040 * 1057 *
1041 * Can sleep, returns nothing. 1058 * Can sleep, returns nothing.
1042 */ 1059 */
1043void acquire_console_sem(void) 1060void console_lock(void)
1044{ 1061{
1045 BUG_ON(in_interrupt()); 1062 BUG_ON(in_interrupt());
1046 down(&console_sem); 1063 down(&console_sem);
@@ -1049,21 +1066,29 @@ void acquire_console_sem(void)
1049 console_locked = 1; 1066 console_locked = 1;
1050 console_may_schedule = 1; 1067 console_may_schedule = 1;
1051} 1068}
1052EXPORT_SYMBOL(acquire_console_sem); 1069EXPORT_SYMBOL(console_lock);
1053 1070
1054int try_acquire_console_sem(void) 1071/**
1072 * console_trylock - try to lock the console system for exclusive use.
1073 *
1074 * Tried to acquire a lock which guarantees that the caller has
1075 * exclusive access to the console system and the console_drivers list.
1076 *
1077 * returns 1 on success, and 0 on failure to acquire the lock.
1078 */
1079int console_trylock(void)
1055{ 1080{
1056 if (down_trylock(&console_sem)) 1081 if (down_trylock(&console_sem))
1057 return -1; 1082 return 0;
1058 if (console_suspended) { 1083 if (console_suspended) {
1059 up(&console_sem); 1084 up(&console_sem);
1060 return -1; 1085 return 0;
1061 } 1086 }
1062 console_locked = 1; 1087 console_locked = 1;
1063 console_may_schedule = 0; 1088 console_may_schedule = 0;
1064 return 0; 1089 return 1;
1065} 1090}
1066EXPORT_SYMBOL(try_acquire_console_sem); 1091EXPORT_SYMBOL(console_trylock);
1067 1092
1068int is_console_locked(void) 1093int is_console_locked(void)
1069{ 1094{
@@ -1094,20 +1119,20 @@ void wake_up_klogd(void)
1094} 1119}
1095 1120
1096/** 1121/**
1097 * release_console_sem - unlock the console system 1122 * console_unlock - unlock the console system
1098 * 1123 *
1099 * Releases the semaphore which the caller holds on the console system 1124 * Releases the console_lock which the caller holds on the console system
1100 * and the console driver list. 1125 * and the console driver list.
1101 * 1126 *
1102 * While the semaphore was held, console output may have been buffered 1127 * While the console_lock was held, console output may have been buffered
1103 * by printk(). If this is the case, release_console_sem() emits 1128 * by printk(). If this is the case, console_unlock(); emits
1104 * the output prior to releasing the semaphore. 1129 * the output prior to releasing the lock.
1105 * 1130 *
1106 * If there is output waiting for klogd, we wake it up. 1131 * If there is output waiting for klogd, we wake it up.
1107 * 1132 *
1108 * release_console_sem() may be called from any context. 1133 * console_unlock(); may be called from any context.
1109 */ 1134 */
1110void release_console_sem(void) 1135void console_unlock(void)
1111{ 1136{
1112 unsigned long flags; 1137 unsigned long flags;
1113 unsigned _con_start, _log_end; 1138 unsigned _con_start, _log_end;
@@ -1140,7 +1165,7 @@ void release_console_sem(void)
1140 if (wake_klogd) 1165 if (wake_klogd)
1141 wake_up_klogd(); 1166 wake_up_klogd();
1142} 1167}
1143EXPORT_SYMBOL(release_console_sem); 1168EXPORT_SYMBOL(console_unlock);
1144 1169
1145/** 1170/**
1146 * console_conditional_schedule - yield the CPU if required 1171 * console_conditional_schedule - yield the CPU if required
@@ -1149,7 +1174,7 @@ EXPORT_SYMBOL(release_console_sem);
1149 * if this CPU should yield the CPU to another task, do 1174 * if this CPU should yield the CPU to another task, do
1150 * so here. 1175 * so here.
1151 * 1176 *
1152 * Must be called within acquire_console_sem(). 1177 * Must be called within console_lock();.
1153 */ 1178 */
1154void __sched console_conditional_schedule(void) 1179void __sched console_conditional_schedule(void)
1155{ 1180{
@@ -1170,14 +1195,14 @@ void console_unblank(void)
1170 if (down_trylock(&console_sem) != 0) 1195 if (down_trylock(&console_sem) != 0)
1171 return; 1196 return;
1172 } else 1197 } else
1173 acquire_console_sem(); 1198 console_lock();
1174 1199
1175 console_locked = 1; 1200 console_locked = 1;
1176 console_may_schedule = 0; 1201 console_may_schedule = 0;
1177 for_each_console(c) 1202 for_each_console(c)
1178 if ((c->flags & CON_ENABLED) && c->unblank) 1203 if ((c->flags & CON_ENABLED) && c->unblank)
1179 c->unblank(); 1204 c->unblank();
1180 release_console_sem(); 1205 console_unlock();
1181} 1206}
1182 1207
1183/* 1208/*
@@ -1188,7 +1213,7 @@ struct tty_driver *console_device(int *index)
1188 struct console *c; 1213 struct console *c;
1189 struct tty_driver *driver = NULL; 1214 struct tty_driver *driver = NULL;
1190 1215
1191 acquire_console_sem(); 1216 console_lock();
1192 for_each_console(c) { 1217 for_each_console(c) {
1193 if (!c->device) 1218 if (!c->device)
1194 continue; 1219 continue;
@@ -1196,7 +1221,7 @@ struct tty_driver *console_device(int *index)
1196 if (driver) 1221 if (driver)
1197 break; 1222 break;
1198 } 1223 }
1199 release_console_sem(); 1224 console_unlock();
1200 return driver; 1225 return driver;
1201} 1226}
1202 1227
@@ -1207,17 +1232,17 @@ struct tty_driver *console_device(int *index)
1207 */ 1232 */
1208void console_stop(struct console *console) 1233void console_stop(struct console *console)
1209{ 1234{
1210 acquire_console_sem(); 1235 console_lock();
1211 console->flags &= ~CON_ENABLED; 1236 console->flags &= ~CON_ENABLED;
1212 release_console_sem(); 1237 console_unlock();
1213} 1238}
1214EXPORT_SYMBOL(console_stop); 1239EXPORT_SYMBOL(console_stop);
1215 1240
1216void console_start(struct console *console) 1241void console_start(struct console *console)
1217{ 1242{
1218 acquire_console_sem(); 1243 console_lock();
1219 console->flags |= CON_ENABLED; 1244 console->flags |= CON_ENABLED;
1220 release_console_sem(); 1245 console_unlock();
1221} 1246}
1222EXPORT_SYMBOL(console_start); 1247EXPORT_SYMBOL(console_start);
1223 1248
@@ -1339,7 +1364,7 @@ void register_console(struct console *newcon)
1339 * Put this console in the list - keep the 1364 * Put this console in the list - keep the
1340 * preferred driver at the head of the list. 1365 * preferred driver at the head of the list.
1341 */ 1366 */
1342 acquire_console_sem(); 1367 console_lock();
1343 if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) { 1368 if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
1344 newcon->next = console_drivers; 1369 newcon->next = console_drivers;
1345 console_drivers = newcon; 1370 console_drivers = newcon;
@@ -1351,14 +1376,15 @@ void register_console(struct console *newcon)
1351 } 1376 }
1352 if (newcon->flags & CON_PRINTBUFFER) { 1377 if (newcon->flags & CON_PRINTBUFFER) {
1353 /* 1378 /*
1354 * release_console_sem() will print out the buffered messages 1379 * console_unlock(); will print out the buffered messages
1355 * for us. 1380 * for us.
1356 */ 1381 */
1357 spin_lock_irqsave(&logbuf_lock, flags); 1382 spin_lock_irqsave(&logbuf_lock, flags);
1358 con_start = log_start; 1383 con_start = log_start;
1359 spin_unlock_irqrestore(&logbuf_lock, flags); 1384 spin_unlock_irqrestore(&logbuf_lock, flags);
1360 } 1385 }
1361 release_console_sem(); 1386 console_unlock();
1387 console_sysfs_notify();
1362 1388
1363 /* 1389 /*
1364 * By unregistering the bootconsoles after we enable the real console 1390 * By unregistering the bootconsoles after we enable the real console
@@ -1394,7 +1420,7 @@ int unregister_console(struct console *console)
1394 return braille_unregister_console(console); 1420 return braille_unregister_console(console);
1395#endif 1421#endif
1396 1422
1397 acquire_console_sem(); 1423 console_lock();
1398 if (console_drivers == console) { 1424 if (console_drivers == console) {
1399 console_drivers=console->next; 1425 console_drivers=console->next;
1400 res = 0; 1426 res = 0;
@@ -1416,7 +1442,8 @@ int unregister_console(struct console *console)
1416 if (console_drivers != NULL && console->flags & CON_CONSDEV) 1442 if (console_drivers != NULL && console->flags & CON_CONSDEV)
1417 console_drivers->flags |= CON_CONSDEV; 1443 console_drivers->flags |= CON_CONSDEV;
1418 1444
1419 release_console_sem(); 1445 console_unlock();
1446 console_sysfs_notify();
1420 return res; 1447 return res;
1421} 1448}
1422EXPORT_SYMBOL(unregister_console); 1449EXPORT_SYMBOL(unregister_console);
@@ -1500,7 +1527,7 @@ int kmsg_dump_register(struct kmsg_dumper *dumper)
1500 /* Don't allow registering multiple times */ 1527 /* Don't allow registering multiple times */
1501 if (!dumper->registered) { 1528 if (!dumper->registered) {
1502 dumper->registered = 1; 1529 dumper->registered = 1;
1503 list_add_tail(&dumper->list, &dump_list); 1530 list_add_tail_rcu(&dumper->list, &dump_list);
1504 err = 0; 1531 err = 0;
1505 } 1532 }
1506 spin_unlock_irqrestore(&dump_list_lock, flags); 1533 spin_unlock_irqrestore(&dump_list_lock, flags);
@@ -1524,29 +1551,16 @@ int kmsg_dump_unregister(struct kmsg_dumper *dumper)
1524 spin_lock_irqsave(&dump_list_lock, flags); 1551 spin_lock_irqsave(&dump_list_lock, flags);
1525 if (dumper->registered) { 1552 if (dumper->registered) {
1526 dumper->registered = 0; 1553 dumper->registered = 0;
1527 list_del(&dumper->list); 1554 list_del_rcu(&dumper->list);
1528 err = 0; 1555 err = 0;
1529 } 1556 }
1530 spin_unlock_irqrestore(&dump_list_lock, flags); 1557 spin_unlock_irqrestore(&dump_list_lock, flags);
1558 synchronize_rcu();
1531 1559
1532 return err; 1560 return err;
1533} 1561}
1534EXPORT_SYMBOL_GPL(kmsg_dump_unregister); 1562EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
1535 1563
1536static const char * const kmsg_reasons[] = {
1537 [KMSG_DUMP_OOPS] = "oops",
1538 [KMSG_DUMP_PANIC] = "panic",
1539 [KMSG_DUMP_KEXEC] = "kexec",
1540};
1541
1542static const char *kmsg_to_str(enum kmsg_dump_reason reason)
1543{
1544 if (reason >= ARRAY_SIZE(kmsg_reasons) || reason < 0)
1545 return "unknown";
1546
1547 return kmsg_reasons[reason];
1548}
1549
1550/** 1564/**
1551 * kmsg_dump - dump kernel log to kernel message dumpers. 1565 * kmsg_dump - dump kernel log to kernel message dumpers.
1552 * @reason: the reason (oops, panic etc) for dumping 1566 * @reason: the reason (oops, panic etc) for dumping
@@ -1585,13 +1599,9 @@ void kmsg_dump(enum kmsg_dump_reason reason)
1585 l2 = chars; 1599 l2 = chars;
1586 } 1600 }
1587 1601
1588 if (!spin_trylock_irqsave(&dump_list_lock, flags)) { 1602 rcu_read_lock();
1589 printk(KERN_ERR "dump_kmsg: dump list lock is held during %s, skipping dump\n", 1603 list_for_each_entry_rcu(dumper, &dump_list, list)
1590 kmsg_to_str(reason));
1591 return;
1592 }
1593 list_for_each_entry(dumper, &dump_list, list)
1594 dumper->dump(dumper, reason, s1, l1, s2, l2); 1604 dumper->dump(dumper, reason, s1, l1, s2, l2);
1595 spin_unlock_irqrestore(&dump_list_lock, flags); 1605 rcu_read_unlock();
1596} 1606}
1597#endif 1607#endif