aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c88
1 files changed, 81 insertions, 7 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index b799a2ee96e..cbebc142be1 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -53,6 +53,10 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
53 53
54#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) 54#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
55 55
56#ifdef CONFIG_DEBUG_LL
57extern void printascii(char *);
58#endif
59
56/* printk's without a loglevel use this.. */ 60/* printk's without a loglevel use this.. */
57#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL 61#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
58 62
@@ -297,6 +301,53 @@ static inline void boot_delay_msec(void)
297} 301}
298#endif 302#endif
299 303
304/*
305 * Return the number of unread characters in the log buffer.
306 */
307static int log_buf_get_len(void)
308{
309 return logged_chars;
310}
311
312/*
313 * Clears the ring-buffer
314 */
315void log_buf_clear(void)
316{
317 logged_chars = 0;
318}
319
320/*
321 * Copy a range of characters from the log buffer.
322 */
323int log_buf_copy(char *dest, int idx, int len)
324{
325 int ret, max;
326 bool took_lock = false;
327
328 if (!oops_in_progress) {
329 spin_lock_irq(&logbuf_lock);
330 took_lock = true;
331 }
332
333 max = log_buf_get_len();
334 if (idx < 0 || idx >= max) {
335 ret = -1;
336 } else {
337 if (len > max - idx)
338 len = max - idx;
339 ret = len;
340 idx += (log_end - max);
341 while (len-- > 0)
342 dest[len] = LOG_BUF(idx + len);
343 }
344
345 if (took_lock)
346 spin_unlock_irq(&logbuf_lock);
347
348 return ret;
349}
350
300#ifdef CONFIG_SECURITY_DMESG_RESTRICT 351#ifdef CONFIG_SECURITY_DMESG_RESTRICT
301int dmesg_restrict = 1; 352int dmesg_restrict = 1;
302#else 353#else
@@ -325,8 +376,10 @@ static int check_syslog_permissions(int type, bool from_file)
325 return 0; 376 return 0;
326 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ 377 /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
327 if (capable(CAP_SYS_ADMIN)) { 378 if (capable(CAP_SYS_ADMIN)) {
328 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " 379 printk_once(KERN_WARNING "%s (%d): "
329 "but no CAP_SYSLOG (deprecated).\n"); 380 "Attempt to access syslog with CAP_SYS_ADMIN "
381 "but no CAP_SYSLOG (deprecated).\n",
382 current->comm, task_pid_nr(current));
330 return 0; 383 return 0;
331 } 384 }
332 return -EPERM; 385 return -EPERM;
@@ -789,7 +842,7 @@ static inline int can_use_console(unsigned int cpu)
789static int console_trylock_for_printk(unsigned int cpu) 842static int console_trylock_for_printk(unsigned int cpu)
790 __releases(&logbuf_lock) 843 __releases(&logbuf_lock)
791{ 844{
792 int retval = 0; 845 int retval = 0, wake = 0;
793 846
794 if (console_trylock()) { 847 if (console_trylock()) {
795 retval = 1; 848 retval = 1;
@@ -802,12 +855,14 @@ static int console_trylock_for_printk(unsigned int cpu)
802 */ 855 */
803 if (!can_use_console(cpu)) { 856 if (!can_use_console(cpu)) {
804 console_locked = 0; 857 console_locked = 0;
805 up(&console_sem); 858 wake = 1;
806 retval = 0; 859 retval = 0;
807 } 860 }
808 } 861 }
809 printk_cpu = UINT_MAX; 862 printk_cpu = UINT_MAX;
810 spin_unlock(&logbuf_lock); 863 spin_unlock(&logbuf_lock);
864 if (wake)
865 up(&console_sem);
811 return retval; 866 return retval;
812} 867}
813static const char recursion_bug_msg [] = 868static const char recursion_bug_msg [] =
@@ -882,6 +937,10 @@ asmlinkage int vprintk(const char *fmt, va_list args)
882 if (trace_override && !trace_recurse) 937 if (trace_override && !trace_recurse)
883 TRACE("%s", printk_buf); 938 TRACE("%s", printk_buf);
884 939
940#ifdef CONFIG_DEBUG_LL
941 printascii(printk_buf);
942#endif
943
885 p = printk_buf; 944 p = printk_buf;
886 945
887 /* Read log level and handle special printk prefix */ 946 /* Read log level and handle special printk prefix */
@@ -1156,7 +1215,6 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self,
1156 switch (action) { 1215 switch (action) {
1157 case CPU_ONLINE: 1216 case CPU_ONLINE:
1158 case CPU_DEAD: 1217 case CPU_DEAD:
1159 case CPU_DYING:
1160 case CPU_DOWN_FAILED: 1218 case CPU_DOWN_FAILED:
1161 case CPU_UP_CANCELED: 1219 case CPU_UP_CANCELED:
1162 console_lock(); 1220 console_lock();
@@ -1252,7 +1310,7 @@ void console_unlock(void)
1252{ 1310{
1253 unsigned long flags; 1311 unsigned long flags;
1254 unsigned _con_start, _log_end; 1312 unsigned _con_start, _log_end;
1255 unsigned wake_klogd = 0; 1313 unsigned wake_klogd = 0, retry = 0;
1256 1314
1257 if (console_suspended) { 1315 if (console_suspended) {
1258 up(&console_sem); 1316 up(&console_sem);
@@ -1261,6 +1319,7 @@ void console_unlock(void)
1261 1319
1262 console_may_schedule = 0; 1320 console_may_schedule = 0;
1263 1321
1322again:
1264 for ( ; ; ) { 1323 for ( ; ; ) {
1265 spin_lock_irqsave(&logbuf_lock, flags); 1324 spin_lock_irqsave(&logbuf_lock, flags);
1266 wake_klogd |= log_start - log_end; 1325 wake_klogd |= log_start - log_end;
@@ -1281,8 +1340,23 @@ void console_unlock(void)
1281 if (unlikely(exclusive_console)) 1340 if (unlikely(exclusive_console))
1282 exclusive_console = NULL; 1341 exclusive_console = NULL;
1283 1342
1343 spin_unlock(&logbuf_lock);
1344
1284 up(&console_sem); 1345 up(&console_sem);
1346
1347 /*
1348 * Someone could have filled up the buffer again, so re-check if there's
1349 * something to flush. In case we cannot trylock the console_sem again,
1350 * there's a new owner and the console_unlock() from them will do the
1351 * flush, no worries.
1352 */
1353 spin_lock(&logbuf_lock);
1354 if (con_start != log_end)
1355 retry = 1;
1285 spin_unlock_irqrestore(&logbuf_lock, flags); 1356 spin_unlock_irqrestore(&logbuf_lock, flags);
1357 if (retry && console_trylock())
1358 goto again;
1359
1286 if (wake_klogd) 1360 if (wake_klogd)
1287 wake_up_klogd(); 1361 wake_up_klogd();
1288} 1362}
@@ -1594,7 +1668,7 @@ static int __init printk_late_init(void)
1594 struct console *con; 1668 struct console *con;
1595 1669
1596 for_each_console(con) { 1670 for_each_console(con) {
1597 if (con->flags & CON_BOOT) { 1671 if (!keep_bootcon && con->flags & CON_BOOT) {
1598 printk(KERN_INFO "turn off boot console %s%d\n", 1672 printk(KERN_INFO "turn off boot console %s%d\n",
1599 con->name, con->index); 1673 con->name, con->index);
1600 unregister_console(con); 1674 unregister_console(con);