xref: /dragonfly/sys/kern/subr_prf.c (revision 2b3f93ea6d1f70880f3e87f3c2cbe0dc0bfc9332)
1 /*-
2  * Copyright (c) 1986, 1988, 1991, 1993
3  *        The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *        @(#)subr_prf.c      8.3 (Berkeley) 1/21/94
35  * $FreeBSD: src/sys/kern/subr_prf.c,v 1.61.2.5 2002/08/31 18:22:08 dwmalone Exp $
36  */
37 
38 #include "opt_ddb.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/msgbuf.h>
44 #include <sys/malloc.h>
45 #include <sys/proc.h>
46 #include <sys/caps.h>
47 #include <sys/tty.h>
48 #include <sys/tprintf.h>
49 #include <sys/stdint.h>
50 #include <sys/syslog.h>
51 #include <sys/cons.h>
52 #include <sys/uio.h>
53 #include <sys/sysctl.h>
54 #include <sys/lock.h>
55 #include <sys/ctype.h>
56 #include <sys/eventhandler.h>
57 #include <sys/kthread.h>
58 #include <sys/cpu_topology.h>
59 
60 #include <sys/thread2.h>
61 #include <sys/spinlock2.h>
62 
63 #ifdef DDB
64 #include <ddb/ddb.h>
65 #endif
66 
67 /*
68  * Note that stdarg.h and the ANSI style va_start macro is used for both
69  * ANSI and traditional C compilers.  We use the __ machine version to stay
70  * within the kernel header file set.
71  */
72 #include <machine/stdarg.h>
73 
74 #define TOCONS                0x01
75 #define TOTTY                 0x02
76 #define TOLOG                 0x04
77 #define TOWAKEUP    0x08
78 #define TONOSPIN    0x10      /* avoid serialization */
79 
80 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
81 #define MAXNBUF     (sizeof(intmax_t) * NBBY + 1)
82 
83 struct putchar_arg {
84           int       flags;
85           int       pri;
86           struct    tty *tty;
87 };
88 
89 struct snprintf_arg {
90           char      *str;
91           size_t    remain;
92 };
93 
94 extern    int log_open;
95 
96 struct    tty *constty;                           /* pointer to console "window" tty */
97 
98 static void  msglogchar(int c, int pri);
99 static void  msgaddchar(int c, void *dummy);
100 static void  kputchar (int ch, void *arg);
101 static char *ksprintn (char *nbuf, uintmax_t num, int base, int *lenp,
102                            int upper);
103 static void  snprintf_func (int ch, void *arg);
104 
105 static int consintr = 1;                /* Ok to handle console interrupts? */
106 static int msgbufmapped;                /* Set when safe to use msgbuf */
107 static struct spinlock cons_spin = SPINLOCK_INITIALIZER(cons_spin, "cons_spin");
108 static thread_t constty_td = NULL;
109 
110 int msgbuftrigger;
111 
112 static int      log_console_output = 1;
113 TUNABLE_INT("kern.log_console_output", &log_console_output);
114 SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,
115     &log_console_output, 0, "Duplicate console output to the syslog");
116 static int          kprintf_logging = TOLOG | TOCONS;
117 TUNABLE_INT("kern.kprintf_logging", &kprintf_logging);
118 SYSCTL_INT(_kern, OID_AUTO, kprintf_logging, CTLFLAG_RW,
119     &kprintf_logging, 0, "kprintf() target bitmask: 0x1=console 0x4=dmesg");
120 
121 static int ptr_restrict = 0;
122 TUNABLE_INT("security.ptr_restrict", &ptr_restrict);
123 SYSCTL_INT(_security, OID_AUTO, ptr_restrict, CTLFLAG_RW, &ptr_restrict, 0,
124     "Prevent leaking the kernel pointers back to userland");
125 
126 static int unprivileged_read_msgbuf = 1;
127 TUNABLE_INT("security.unprivileged_read_msgbuf", &unprivileged_read_msgbuf);
128 SYSCTL_INT(_security, OID_AUTO, unprivileged_read_msgbuf, CTLFLAG_RW,
129     &unprivileged_read_msgbuf, 0,
130     "Unprivileged processes may read the kernel message buffer");
131 
132 /*
133  * Warn that a system table is full.
134  */
135 void
tablefull(const char * tab)136 tablefull(const char *tab)
137 {
138 
139           log(LOG_ERR, "%s: table is full\n", tab);
140 }
141 
142 /*
143  * Uprintf prints to the controlling terminal for the current process.
144  */
145 int
uprintf(const char * fmt,...)146 uprintf(const char *fmt, ...)
147 {
148           struct proc *p = curproc;
149           __va_list ap;
150           struct putchar_arg pca;
151           int retval = 0;
152 
153           if (p && (p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
154                     __va_start(ap, fmt);
155                     pca.tty = p->p_session->s_ttyp;
156                     pca.flags = TOTTY;
157 
158                     retval = kvcprintf(fmt, kputchar, &pca, ap);
159                     __va_end(ap);
160           }
161           return (retval);
162 }
163 
164 tpr_t
tprintf_open(struct proc * p)165 tprintf_open(struct proc *p)
166 {
167           if ((p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
168                     sess_hold(p->p_session);
169                     return ((tpr_t) p->p_session);
170           }
171           return (NULL);
172 }
173 
174 void
tprintf_close(tpr_t sess)175 tprintf_close(tpr_t sess)
176 {
177           if (sess)
178                     sess_rele((struct session *) sess);
179 }
180 
181 /*
182  * tprintf prints on the controlling terminal associated
183  * with the given session.
184  */
185 int
tprintf(tpr_t tpr,const char * fmt,...)186 tprintf(tpr_t tpr, const char *fmt, ...)
187 {
188           struct session *sess = (struct session *)tpr;
189           struct tty *tp = NULL;
190           int flags = TOLOG;
191           __va_list ap;
192           struct putchar_arg pca;
193           int retval;
194 
195           if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
196                     flags |= TOTTY;
197                     tp = sess->s_ttyp;
198           }
199           __va_start(ap, fmt);
200           pca.tty = tp;
201           pca.flags = flags;
202           pca.pri = LOG_INFO;
203           retval = kvcprintf(fmt, kputchar, &pca, ap);
204           __va_end(ap);
205           msgbuftrigger = 1;
206           return (retval);
207 }
208 
209 /*
210  * Ttyprintf displays a message on a tty; it should be used only by
211  * the tty driver, or anything that knows the underlying tty will not
212  * be revoke(2)'d away.  Other callers should use tprintf.
213  */
214 int
ttyprintf(struct tty * tp,const char * fmt,...)215 ttyprintf(struct tty *tp, const char *fmt, ...)
216 {
217           __va_list ap;
218           struct putchar_arg pca;
219           int retval;
220 
221           __va_start(ap, fmt);
222           pca.tty = tp;
223           pca.flags = TOTTY;
224           retval = kvcprintf(fmt, kputchar, &pca, ap);
225           __va_end(ap);
226           return (retval);
227 }
228 
229 /*
230  * Log writes to the log buffer, and guarantees not to sleep (so can be
231  * called by interrupt routines).  If there is no process reading the
232  * log yet, it writes to the console also.
233  */
234 int
log(int level,const char * fmt,...)235 log(int level, const char *fmt, ...)
236 {
237           __va_list ap;
238           int retval;
239           struct putchar_arg pca;
240 
241           pca.tty = NULL;
242           pca.pri = level;
243           if ((kprintf_logging & TOCONS) == 0 || log_open)
244                     pca.flags = TOLOG;
245           else
246                     pca.flags = TOCONS;
247 
248           __va_start(ap, fmt);
249           retval = kvcprintf(fmt, kputchar, &pca, ap);
250           __va_end(ap);
251 
252           msgbuftrigger = 1;
253           return (retval);
254 }
255 
256 #define CONSCHUNK 128
257 
258 void
log_console(struct uio * uio)259 log_console(struct uio *uio)
260 {
261           int c, i, error, iovlen, nl;
262           struct uio muio;
263           struct iovec *miov = NULL;
264           char *consbuffer;
265           int pri;
266 
267           if (!log_console_output)
268                     return;
269 
270           pri = LOG_INFO | LOG_CONSOLE;
271           muio = *uio;
272           iovlen = uio->uio_iovcnt * sizeof (struct iovec);
273           miov = kmalloc(iovlen, M_TEMP, M_WAITOK);
274           consbuffer = kmalloc(CONSCHUNK, M_TEMP, M_WAITOK);
275           bcopy((caddr_t)muio.uio_iov, (caddr_t)miov, iovlen);
276           muio.uio_iov = miov;
277           uio = &muio;
278 
279           nl = 0;
280           while (uio->uio_resid > 0) {
281                     c = (int)szmin(uio->uio_resid, CONSCHUNK);
282                     error = uiomove(consbuffer, (size_t)c, uio);
283                     if (error != 0)
284                               break;
285                     for (i = 0; i < c; i++) {
286                               msglogchar(consbuffer[i], pri);
287                               if (consbuffer[i] == '\n')
288                                         nl = 1;
289                               else
290                                         nl = 0;
291                     }
292           }
293           if (!nl)
294                     msglogchar('\n', pri);
295           msgbuftrigger = 1;
296           kfree(miov, M_TEMP);
297           kfree(consbuffer, M_TEMP);
298           return;
299 }
300 
301 /*
302  * Output to the console.
303  */
304 int
kprintf(const char * fmt,...)305 kprintf(const char *fmt, ...)
306 {
307           __va_list ap;
308           int savintr;
309           struct putchar_arg pca;
310           int retval;
311 
312           savintr = consintr;           /* disable interrupts */
313           consintr = 0;
314           __va_start(ap, fmt);
315           pca.tty = NULL;
316           pca.flags = kprintf_logging & ~TOTTY;
317           pca.pri = -1;
318           retval = kvcprintf(fmt, kputchar, &pca, ap);
319           __va_end(ap);
320           if (!panicstr)
321                     msgbuftrigger = 1;
322           consintr = savintr;           /* reenable interrupts */
323           return (retval);
324 }
325 
326 int
kvprintf(const char * fmt,__va_list ap)327 kvprintf(const char *fmt, __va_list ap)
328 {
329           int savintr;
330           struct putchar_arg pca;
331           int retval;
332 
333           savintr = consintr;           /* disable interrupts */
334           consintr = 0;
335           pca.tty = NULL;
336           pca.flags = kprintf_logging & ~TOTTY;
337           pca.pri = -1;
338           retval = kvcprintf(fmt, kputchar, &pca, ap);
339           if (!panicstr)
340                     msgbuftrigger = 1;
341           consintr = savintr;           /* reenable interrupts */
342           return (retval);
343 }
344 
345 /*
346  * Limited rate kprintf.  The passed rate structure must be initialized
347  * with the desired reporting frequency.  A frequency of 0 will result in
348  * no output.
349  *
350  * count may be initialized to a negative number to allow an initial
351  * burst.
352  *
353  * Returns 0 if it did not issue the printf, non-zero if it did.
354  */
355 int
krateprintf(struct krate * rate,const char * fmt,...)356 krateprintf(struct krate *rate, const char *fmt, ...)
357 {
358           __va_list ap;
359           int res;
360 
361           if (rate->ticks != (int)time_uptime) {
362                     rate->ticks = (int)time_uptime;
363                     if (rate->count > 0)
364                               rate->count = 0;
365           }
366           if (rate->count < rate->freq) {
367                     ++rate->count;
368                     __va_start(ap, fmt);
369                     kvprintf(fmt, ap);
370                     __va_end(ap);
371                     res = 1;
372           } else {
373                     res = 0;
374           }
375           return res;
376 }
377 
378 /*
379  * Print a character to the dmesg log, the console, and/or the user's
380  * terminal.
381  *
382  * NOTE: TOTTY does not require nonblocking operation, but TOCONS
383  *         and TOLOG do.  When we have a constty we still output to
384  *         the real console but we have a monitoring thread which
385  *         we wakeup which tracks the log.
386  */
387 static void
kputchar(int c,void * arg)388 kputchar(int c, void *arg)
389 {
390           struct putchar_arg *ap = (struct putchar_arg*) arg;
391           int flags = ap->flags;
392           struct tty *tp = ap->tty;
393 
394           if (panicstr)
395                     constty = NULL;
396           if ((flags & TOCONS) && tp == NULL && constty)
397                     flags |= TOLOG | TOWAKEUP;
398           if ((flags & TOTTY) && tputchar(c, tp) < 0)
399                     ap->flags &= ~TOTTY;
400           if ((flags & TOLOG))
401                     msglogchar(c, ap->pri);
402           if ((flags & TOCONS) && c)
403                     cnputc(c);
404           if ((flags & TOWAKEUP) && mycpu->gd_intr_nesting_level == 0)
405                     wakeup(constty_td);
406 }
407 
408 /*
409  * Scaled down version of sprintf(3).
410  */
411 int
ksprintf(char * buf,const char * cfmt,...)412 ksprintf(char *buf, const char *cfmt, ...)
413 {
414           int retval;
415           __va_list ap;
416 
417           __va_start(ap, cfmt);
418           retval = kvcprintf(cfmt, NULL, buf, ap);
419           buf[retval] = '\0';
420           __va_end(ap);
421           return (retval);
422 }
423 
424 /*
425  * Scaled down version of vsprintf(3).
426  */
427 int
kvsprintf(char * buf,const char * cfmt,__va_list ap)428 kvsprintf(char *buf, const char *cfmt, __va_list ap)
429 {
430           int retval;
431 
432           retval = kvcprintf(cfmt, NULL, buf, ap);
433           buf[retval] = '\0';
434           return (retval);
435 }
436 
437 /*
438  * Scaled down version of snprintf(3).
439  */
440 int
ksnprintf(char * str,size_t size,const char * format,...)441 ksnprintf(char *str, size_t size, const char *format, ...)
442 {
443           int retval;
444           __va_list ap;
445 
446           __va_start(ap, format);
447           retval = kvsnprintf(str, size, format, ap);
448           __va_end(ap);
449           return(retval);
450 }
451 
452 /*
453  * Scaled down version of vsnprintf(3).
454  */
455 int
kvsnprintf(char * str,size_t size,const char * format,__va_list ap)456 kvsnprintf(char *str, size_t size, const char *format, __va_list ap)
457 {
458           struct snprintf_arg info;
459           int retval;
460 
461           info.str = str;
462           info.remain = size;
463           retval = kvcprintf(format, snprintf_func, &info, ap);
464           if (info.remain >= 1)
465                     *info.str++ = '\0';
466           return (retval);
467 }
468 
469 int
kvasnprintf(char ** strp,size_t size,const char * format,__va_list ap)470 kvasnprintf(char **strp, size_t size, const char *format, __va_list ap)
471 {
472           struct snprintf_arg info;
473           int retval;
474 
475           *strp = kmalloc(size, M_TEMP, M_WAITOK);
476           info.str = *strp;
477           info.remain = size;
478           retval = kvcprintf(format, snprintf_func, &info, ap);
479           if (info.remain >= 1)
480                     *info.str++ = '\0';
481           return (retval);
482 }
483 
484 void
kvasfree(char ** strp)485 kvasfree(char **strp)
486 {
487           if (*strp) {
488                     kfree(*strp, M_TEMP);
489                     *strp = NULL;
490           }
491 }
492 
493 static void
snprintf_func(int ch,void * arg)494 snprintf_func(int ch, void *arg)
495 {
496           struct snprintf_arg *const info = arg;
497 
498           if (info->remain >= 2) {
499                     *info->str++ = ch;
500                     info->remain--;
501           }
502 }
503 
504 /*
505  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
506  * order; return an optional length and a pointer to the last character
507  * written in the buffer (i.e., the first character of the string).
508  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
509  */
510 static char *
ksprintn(char * nbuf,uintmax_t num,int base,int * lenp,int upper)511 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
512 {
513           char *p, c;
514 
515           p = nbuf;
516           *p = '\0';
517           do {
518                     c = hex2ascii(num % base);
519                     *++p = upper ? toupper(c) : c;
520           } while (num /= base);
521           if (lenp)
522                     *lenp = p - nbuf;
523           return (p);
524 }
525 
526 /*
527  * Scaled down version of printf(3).
528  *
529  * Two additional formats:
530  *
531  * The format %pb%i is supported to decode error registers.
532  * Its usage is:
533  *
534  *        kprintf("reg=%pb%i\n", "<base><arg>*", regval);
535  *
536  * where <base> is the output base expressed as a control character, e.g.
537  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
538  * the first of which gives the bit number to be inspected (origin 1), and
539  * the next characters (up to a control character, i.e. a character <= 32),
540  * give the name of the register.  Thus:
541  *
542  *        kvcprintf("reg=%pb%i\n", "\10\2BITTWO\1BITONE\n", 3);
543  *
544  * would produce output:
545  *
546  *        reg=3<BITTWO,BITONE>
547  */
548 
549 #define PCHAR(c) {int cc=(c); if(func) (*func)(cc,arg); else *d++=cc; retval++;}
550 
551 int
kvcprintf(char const * fmt,void (* func)(int,void *),void * arg,__va_list ap)552 kvcprintf(char const *fmt, void (*func)(int, void*), void *arg, __va_list ap)
553 {
554           char nbuf[MAXNBUF];
555           char *d;
556           const char *p, *percent, *q;
557           int ch, n;
558           uintmax_t num;
559           int base, tmp, width, ladjust, sharpflag, spaceflag, neg, sign, dot;
560           int cflag, hflag, jflag, lflag, qflag, tflag, zflag;
561           int dwidth, upper;
562           char padc;
563           int retval = 0, stop = 0;
564           int usespin;
565           int ddb_active;
566 
567 #ifdef DDB
568           ddb_active = db_active;
569 #else
570           ddb_active = 0;
571 #endif
572 
573           num = 0;
574           if (!func)
575                     d = (char *) arg;
576           else
577                     d = NULL;
578 
579           if (fmt == NULL)
580                     fmt = "(fmt null)\n";
581 
582           /*
583            * For kputchar just straight-out don't spin, even if it means losing
584            * output from several cpu's posting at the same time.  This allows
585            * us to call debugging / warning kprintf()s from the likes of
586            * the Xinvltlb hard interrupt which ignore critical sections.
587            *
588            * This also avoids deadlocking on nested kprintf()s.
589            */
590           usespin = (func == kputchar &&
591                        (kprintf_logging & TONOSPIN) == 0 &&
592                        panic_cpu_gd != mycpu &&
593                        (((struct putchar_arg *)arg)->flags & TOTTY) == 0);
594           if (usespin) {
595                     crit_enter_hard();
596                     if (spin_trylock(&cons_spin) == 0) {
597                               goto headoncrash;   /* failed */
598                     }
599           }
600 
601           for (;;) {
602                     padc = ' ';
603                     width = 0;
604                     while ((ch = (u_char)*fmt++) != '%' || stop) {
605                               if (ch == '\0')
606                                         goto done;
607                               PCHAR(ch);
608                     }
609                     percent = fmt - 1;
610                     dot = dwidth = ladjust = neg = sharpflag = sign = upper = 0;
611                     spaceflag = 0;
612                     cflag = hflag = jflag = lflag = qflag = tflag = zflag = 0;
613 
614 reswitch:
615                     switch (ch = (u_char)*fmt++) {
616                     case ' ':
617                               spaceflag = 1;
618                               goto reswitch;
619                     case '.':
620                               dot = 1;
621                               goto reswitch;
622                     case '#':
623                               sharpflag = 1;
624                               goto reswitch;
625                     case '+':
626                               sign = 1;
627                               goto reswitch;
628                     case '-':
629                               ladjust = 1;
630                               goto reswitch;
631                     case '%':
632                               PCHAR(ch);
633                               break;
634                     case '*':
635                               if (!dot) {
636                                         width = __va_arg(ap, int);
637                                         if (width < 0) {
638                                                   ladjust = !ladjust;
639                                                   width = -width;
640                                         }
641                               } else {
642                                         dwidth = __va_arg(ap, int);
643                               }
644                               goto reswitch;
645                     case '0':
646                               if (!dot) {
647                                         padc = '0';
648                                         goto reswitch;
649                               }
650                     case '1': case '2': case '3': case '4':
651                     case '5': case '6': case '7': case '8': case '9':
652                                         for (n = 0;; ++fmt) {
653                                                   n = n * 10 + ch - '0';
654                                                   ch = *fmt;
655                                                   if (ch < '0' || ch > '9')
656                                                             break;
657                                         }
658                               if (dot)
659                                         dwidth = n;
660                               else
661                                         width = n;
662                               goto reswitch;
663                     case 'c':
664                               PCHAR(__va_arg(ap, int));
665                               break;
666                     case 'd':
667                     case 'i':
668                               base = 10;
669                               sign = 1;
670                               goto handle_sign;
671                     case 'h':
672                               if (hflag) {
673                                         hflag = 0;
674                                         cflag = 1;
675                               } else
676                                         hflag = 1;
677                               goto reswitch;
678                     case 'j':
679                               jflag = 1;
680                               goto reswitch;
681                     case 'l':
682                               if (lflag) {
683                                         lflag = 0;
684                                         qflag = 1;
685                               } else
686                                         lflag = 1;
687                               goto reswitch;
688                     case 'n':
689                               if (cflag)
690                                         *(__va_arg(ap, char *)) = retval;
691                               else if (hflag)
692                                         *(__va_arg(ap, short *)) = retval;
693                               else if (jflag)
694                                         *(__va_arg(ap, intmax_t *)) = retval;
695                               else if (lflag)
696                                         *(__va_arg(ap, long *)) = retval;
697                               else if (qflag)
698                                         *(__va_arg(ap, quad_t *)) = retval;
699                               else
700                                         *(__va_arg(ap, int *)) = retval;
701                               break;
702                     case 'o':
703                               base = 8;
704                               goto handle_nosign;
705                     case 'p':
706                               /* peek if this is a /b/ hiding as /p/ or not */
707                               if (fmt[0] == 'b' && fmt[1] == '%' && fmt[2] == 'i') {
708                                         fmt += 3; /* consume "b%i" */
709                                         p = __va_arg(ap, char *);
710                                         num = (u_int)__va_arg(ap, int);
711                                         for (q = ksprintn(nbuf, num, *p++, NULL, 0);*q;)
712                                                   PCHAR(*q--);
713 
714                                         if (num == 0)
715                                                   break;
716 
717                                         for (tmp = 0; *p;) {
718                                                   n = *p++;
719                                                   if (num & (1 << (n - 1))) {
720                                                             PCHAR(tmp ? ',' : '<');
721                                                             for (; (n = *p) > ' '; ++p)
722                                                                       PCHAR(n);
723                                                             tmp = 1;
724                                                   } else {
725                                                             for (; *p > ' '; ++p)
726                                                                       continue;
727                                                   }
728                                         }
729                                         if (tmp)
730                                                   PCHAR('>');
731                                         break;
732                               }
733                               base = 16;
734                               sharpflag = (width == 0);
735                               sign = 0;
736                               num = (uintptr_t)__va_arg(ap, void *);
737                               if (ptr_restrict && fmt[0] != 'x' &&
738                                   !(panicstr || dumping || ddb_active)) {
739                                         if (ptr_restrict == 1) {
740                                                   /* zero out upper bits */
741                                                   num &= 0xffffffUL;
742                                         } else {
743                                                   num = 0xc0ffee;
744                                         }
745                               }
746                               goto number;
747                     case 'q':
748                               qflag = 1;
749                               goto reswitch;
750                     case 's':
751                               p = __va_arg(ap, char *);
752                               if (p == NULL)
753                                         p = "(null)";
754                               if (!dot)
755                                         n = strlen (p);
756                               else
757                                         for (n = 0; n < dwidth && p[n]; n++)
758                                                   continue;
759 
760                               width -= n;
761 
762                               if (!ladjust && width > 0)
763                                         while (width--)
764                                                   PCHAR(padc);
765                               while (n--)
766                                         PCHAR(*p++);
767                               if (ladjust && width > 0)
768                                         while (width--)
769                                                   PCHAR(padc);
770                               break;
771                     case 't':
772                               tflag = 1;
773                               goto reswitch;
774                     case 'u':
775                               base = 10;
776                               goto handle_nosign;
777                     case 'X':
778                               upper = 1;
779                               /* FALLTHROUGH */
780                     case 'x':
781                               base = 16;
782                               goto handle_nosign;
783                     case 'z':
784                               zflag = 1;
785                               goto reswitch;
786 handle_nosign:
787                               sign = 0;
788                               if (cflag)
789                                         num = (u_char)__va_arg(ap, int);
790                               else if (hflag)
791                                         num = (u_short)__va_arg(ap, int);
792                               else if (jflag)
793                                         num = __va_arg(ap, uintmax_t);
794                               else if (lflag)
795                                         num = __va_arg(ap, u_long);
796                               else if (qflag)
797                                         num = __va_arg(ap, u_quad_t);
798                               else if (tflag)
799                                         num = __va_arg(ap, ptrdiff_t);
800                               else if (zflag)
801                                         num = __va_arg(ap, size_t);
802                               else
803                                         num = __va_arg(ap, u_int);
804                               goto number;
805 handle_sign:
806                               if (cflag)
807                                         num = (char)__va_arg(ap, int);
808                               else if (hflag)
809                                         num = (short)__va_arg(ap, int);
810                               else if (jflag)
811                                         num = __va_arg(ap, intmax_t);
812                               else if (lflag)
813                                         num = __va_arg(ap, long);
814                               else if (qflag)
815                                         num = __va_arg(ap, quad_t);
816                               else if (tflag)
817                                         num = __va_arg(ap, ptrdiff_t);
818                               else if (zflag)
819                                         num = __va_arg(ap, ssize_t);
820                               else
821                                         num = __va_arg(ap, int);
822 number:
823                               if (sign && (intmax_t)num < 0) {
824                                         neg = 1;
825                                         num = -(intmax_t)num;
826                               }
827                               p = ksprintn(nbuf, num, base, &n, upper);
828                               tmp = 0;
829                               if (sharpflag && num != 0) {
830                                         if (base == 8)
831                                                   tmp++;
832                                         else if (base == 16)
833                                                   tmp += 2;
834                               }
835                               if (neg || (sign && spaceflag))
836                                         tmp++;
837 
838                               if (!ladjust && padc == '0')
839                                         dwidth = width - tmp;
840                               width -= tmp + imax(dwidth, n);
841                               dwidth -= n;
842                               if (!ladjust)
843                                         while (width-- > 0)
844                                                   PCHAR(' ');
845                               if (neg) {
846                                         PCHAR('-');
847                               } else if (sign && spaceflag) {
848                                         PCHAR(' ');
849                               }
850                               if (sharpflag && num != 0) {
851                                         if (base == 8) {
852                                                   PCHAR('0');
853                                         } else if (base == 16) {
854                                                   PCHAR('0');
855                                                   PCHAR('x');
856                                         }
857                               }
858                               while (dwidth-- > 0)
859                                         PCHAR('0');
860 
861                               while (*p)
862                                         PCHAR(*p--);
863 
864                               if (ladjust)
865                                         while (width-- > 0)
866                                                   PCHAR(' ');
867 
868                               break;
869                     default:
870                               while (percent < fmt)
871                                         PCHAR(*percent++);
872                               /*
873                                * Since we ignore an formatting argument it is no
874                                * longer safe to obey the remaining formatting
875                                * arguments as the arguments will no longer match
876                                * the format specs.
877                                */
878                               stop = 1;
879                               break;
880                     }
881           }
882 done:
883           /*
884            * Cleanup reentrancy issues.
885            */
886           if (usespin) {
887                     spin_unlock(&cons_spin);
888 headoncrash:
889                     crit_exit_hard();
890           }
891           return (retval);
892 }
893 
894 #undef PCHAR
895 
896 /*
897  * Called from the panic code to try to get the console working
898  * again in case we paniced inside a kprintf().
899  */
900 void
kvcreinitspin(void)901 kvcreinitspin(void)
902 {
903           spin_init(&cons_spin, "kvcre");
904 }
905 
906 /*
907  * Console support thread for constty intercepts.  This is needed because
908  * console tty intercepts can block.  Instead of having kputchar() attempt
909  * to directly write to the console intercept we just force it to log
910  * and wakeup this baby to track and dump the log to constty.
911  */
912 static void
constty_daemon(void)913 constty_daemon(void)
914 {
915           u_int rindex;
916           u_int xindex;
917           u_int n;
918         struct msgbuf *mbp;
919           struct tty *tp;
920 
921         EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc,
922                               constty_td, SHUTDOWN_PRI_FIRST);
923         constty_td->td_flags |= TDF_SYSTHREAD;
924 
925           mbp = msgbufp;
926           rindex = mbp->msg_bufr;                 /* persistent loop variable */
927           xindex = mbp->msg_bufx - 1;   /* anything different than bufx */
928           cpu_ccfence();
929 
930         for (;;) {
931                 kproc_suspend_loop();
932 
933                     crit_enter();
934                     if (mbp != msgbufp)
935                               mbp = msgbufp;
936                     if (xindex == mbp->msg_bufx ||
937                         mbp == NULL ||
938                         msgbufmapped == 0) {
939                               tsleep(constty_td, 0, "waiting", hz);
940                               crit_exit();
941                               continue;
942                     }
943                     crit_exit();
944 
945                     /*
946                      * Get message buf FIFO indices.  rindex is tracking.
947                      */
948                     xindex = mbp->msg_bufx;
949                     cpu_ccfence();
950                     if ((tp = constty) == NULL) {
951                               rindex = xindex;
952                               continue;
953                     }
954 
955                     /*
956                      * Check if the calculated bytes has rolled the whole
957                      * message buffer.
958                      */
959                     n = xindex - rindex;
960                     if (n > mbp->msg_size - 1024) {
961                               rindex = xindex - mbp->msg_size + 2048;
962                               n = xindex - rindex;
963                     }
964 
965                     /*
966                      * And dump it.  If constty gets stuck will give up.
967                      */
968                     while (rindex != xindex) {
969                               u_int ri = rindex % mbp->msg_size;
970                               if (tputchar((uint8_t)mbp->msg_ptr[ri], tp) < 0) {
971                                         constty = NULL;
972                                         rindex = xindex;
973                                         break;
974                               }
975                         if (tp->t_outq.c_cc >= tp->t_ohiwat) {
976                                         tsleep(constty_daemon, 0, "blocked", hz / 10);
977                                         if (tp->t_outq.c_cc >= tp->t_ohiwat) {
978                                                   rindex = xindex;
979                                                   break;
980                                         }
981                               }
982                               ++rindex;
983                     }
984           }
985 }
986 
987 static struct kproc_desc constty_kp = {
988         "consttyd",
989           constty_daemon,
990         &constty_td
991 };
992 SYSINIT(bufdaemon, SI_SUB_KTHREAD_UPDATE, SI_ORDER_ANY,
993         kproc_start, &constty_kp);
994 
995 /*
996  * Put character in log buffer with a particular priority.
997  *
998  * MPSAFE, HARD INTERRUPT SAFE, NESTING SAFE
999  * CRITICAL SECTIONS MIGHT BE IGNORED!  MUST NOT USE NORMAL
1000  * SPIN_LOCK MECHANISMS.
1001  */
1002 static void
msglogchar(int c,int pri)1003 msglogchar(int c, int pri)
1004 {
1005           static int lastpri = -1;
1006           static int dangling;
1007           char nbuf[MAXNBUF];
1008           char *p;
1009 
1010           if (!msgbufmapped)
1011                     return;
1012           if (c == '\0' || c == '\r')
1013                     return;
1014           if (pri != -1 && pri != lastpri) {
1015                     if (dangling) {
1016                               msgaddchar('\n', NULL);
1017                               dangling = 0;
1018                     }
1019                     msgaddchar('<', NULL);
1020                     for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
1021                               msgaddchar(*p--, NULL);
1022                     msgaddchar('>', NULL);
1023                     lastpri = pri;
1024           }
1025           msgaddchar(c, NULL);
1026           if (c == '\n') {
1027                     dangling = 0;
1028                     lastpri = -1;
1029           } else {
1030                     dangling = 1;
1031           }
1032 }
1033 
1034 /*
1035  * Put char in log buffer.   Make sure nothing blows up beyond repair if
1036  * we have an MP race.
1037  *
1038  * MPSAFE, HARD INTERRUPT SAFE, NESTING SAFE
1039  * CRITICAL SECTIONS MIGHT BE IGNORED!  MUST NOT USE NORMAL
1040  * SPIN_LOCK MECHANISMS.
1041  */
1042 static void
msgaddchar(int c,void * dummy)1043 msgaddchar(int c, void *dummy)
1044 {
1045           struct msgbuf *mbp;
1046           u_int lindex;
1047           u_int rindex;
1048           u_int xindex;
1049           u_int n;
1050 
1051           if (!msgbufmapped)
1052                     return;
1053           mbp = msgbufp;
1054           lindex = mbp->msg_bufl;
1055           rindex = mbp->msg_bufr;
1056           xindex = mbp->msg_bufx++;     /* Allow SMP race */
1057           cpu_ccfence();
1058 
1059           mbp->msg_ptr[xindex % mbp->msg_size] = c;
1060           n = xindex - lindex;
1061           if (n > mbp->msg_size - 1024) {
1062                     lindex = xindex - mbp->msg_size + 2048;
1063                     cpu_ccfence();
1064                     mbp->msg_bufl = lindex;
1065           }
1066           n = xindex - rindex;
1067           if (n > mbp->msg_size - 1024) {
1068                     rindex = xindex - mbp->msg_size + 2048;
1069                     cpu_ccfence();
1070                     mbp->msg_bufr = rindex;
1071           }
1072 }
1073 
1074 static void
msgbufcopy(struct msgbuf * oldp)1075 msgbufcopy(struct msgbuf *oldp)
1076 {
1077           u_int rindex;
1078           u_int xindex;
1079           u_int n;
1080 
1081           rindex = oldp->msg_bufr;
1082           xindex = oldp->msg_bufx;
1083           cpu_ccfence();
1084 
1085           n = xindex - rindex;
1086           if (n > oldp->msg_size - 1024)
1087                     rindex = xindex - oldp->msg_size + 2048;
1088           while (rindex != xindex) {
1089                     msglogchar(oldp->msg_ptr[rindex % oldp->msg_size], -1);
1090                     ++rindex;
1091           }
1092 }
1093 
1094 void
msgbufinit(void * ptr,size_t size)1095 msgbufinit(void *ptr, size_t size)
1096 {
1097           char *cp;
1098           static struct msgbuf *oldp = NULL;
1099 
1100           size -= sizeof(*msgbufp);
1101           cp = (char *)ptr;
1102           msgbufp = (struct msgbuf *) (cp + size);
1103           if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_size != size) {
1104                     bzero(cp, size);
1105                     bzero(msgbufp, sizeof(*msgbufp));
1106                     msgbufp->msg_magic = MSG_MAGIC;
1107                     msgbufp->msg_size = (char *)msgbufp - cp;
1108           }
1109           msgbufp->msg_ptr = cp;
1110           if (msgbufmapped && oldp != msgbufp)
1111                     msgbufcopy(oldp);
1112           cpu_mfence();
1113           msgbufmapped = 1;
1114           oldp = msgbufp;
1115 }
1116 
1117 /* Sysctls for accessing/clearing the msgbuf */
1118 
1119 static int
sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)1120 sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
1121 {
1122         struct msgbuf *mbp;
1123           struct ucred *cred;
1124           int error;
1125           u_int rindex_modulo;
1126           u_int xindex_modulo;
1127           u_int rindex;
1128           u_int xindex;
1129           u_int n;
1130 
1131           /*
1132            * Only wheel or root can access the message log.
1133            */
1134           if (unprivileged_read_msgbuf == 0) {
1135                     KKASSERT(req->td->td_proc);
1136                     cred = req->td->td_proc->p_ucred;
1137 
1138                     if ((cred->cr_prison || groupmember(0, cred) == 0) &&
1139                         caps_priv_check_td(req->td, SYSCAP_RESTRICTEDROOT) != 0)
1140                     {
1141                               return (EPERM);
1142                     }
1143           }
1144 
1145           /*
1146            * Unwind the buffer, so that it's linear (possibly starting with
1147            * some initial nulls).
1148            *
1149            * We don't push the entire buffer like we did before because
1150            * bufr (and bufl) now advance in chunks when the fifo is full,
1151            * rather than one character.
1152            */
1153           mbp = msgbufp;
1154           rindex = mbp->msg_bufr;
1155           xindex = mbp->msg_bufx;
1156           n = xindex - rindex;
1157           if (n > mbp->msg_size - 1024) {
1158                     rindex = xindex - mbp->msg_size + 2048;
1159                     n = xindex - rindex;
1160           }
1161           rindex_modulo = rindex % mbp->msg_size;
1162           xindex_modulo = xindex % mbp->msg_size;
1163 
1164           if (rindex_modulo < xindex_modulo) {
1165                     /*
1166                      * Can handle in one linear section.
1167                      */
1168                     error = sysctl_handle_opaque(oidp,
1169                                                        mbp->msg_ptr + rindex_modulo,
1170                                                        xindex_modulo - rindex_modulo,
1171                                                        req);
1172           } else if (rindex_modulo == xindex_modulo) {
1173                     /*
1174                      * Empty buffer, just return a single newline
1175                      */
1176                     error = sysctl_handle_opaque(oidp, "\n", 1, req);
1177           } else if (n <= mbp->msg_size - rindex_modulo) {
1178                     /*
1179                      * Can handle in one linear section.
1180                      */
1181                     error = sysctl_handle_opaque(oidp,
1182                                                        mbp->msg_ptr + rindex_modulo,
1183                                                        n - rindex_modulo,
1184                                                        req);
1185           } else {
1186                     /*
1187                      * Glue together two linear sections into one contiguous
1188                      * output.
1189                      */
1190                     error = sysctl_handle_opaque(oidp,
1191                                                        mbp->msg_ptr + rindex_modulo,
1192                                                        mbp->msg_size - rindex_modulo,
1193                                                        req);
1194                     n -= mbp->msg_size - rindex_modulo;
1195                     if (error == 0)
1196                               error = sysctl_handle_opaque(oidp, mbp->msg_ptr,
1197                                                                  n, req);
1198           }
1199           return (error);
1200 }
1201 
1202 SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD,
1203     0, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
1204 
1205 static int msgbuf_clear;
1206 
1207 static int
sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)1208 sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
1209 {
1210           int error;
1211           error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
1212           if (!error && req->newptr) {
1213                     /* Clear the buffer and reset write pointer */
1214                     msgbufp->msg_bufr = msgbufp->msg_bufx;
1215                     msgbufp->msg_bufl = msgbufp->msg_bufx;
1216                     bzero(msgbufp->msg_ptr, msgbufp->msg_size);
1217                     msgbuf_clear = 0;
1218           }
1219           return (error);
1220 }
1221 
1222 SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
1223     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0,
1224     sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer");
1225 
1226 #ifdef DDB
1227 
DB_SHOW_COMMAND(msgbuf,db_show_msgbuf)1228 DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
1229 {
1230           u_int rindex;
1231           u_int i;
1232           u_int j;
1233 
1234           if (!msgbufmapped) {
1235                     db_printf("msgbuf not mapped yet\n");
1236                     return;
1237           }
1238           db_printf("msgbufp = %p\n", msgbufp);
1239           db_printf("magic = %x, size = %d, r= %d, w = %d, ptr = %p\n",
1240                       msgbufp->msg_magic, msgbufp->msg_size,
1241                       msgbufp->msg_bufr % msgbufp->msg_size,
1242                       msgbufp->msg_bufx % msgbufp->msg_size,
1243                       msgbufp->msg_ptr);
1244 
1245           rindex = msgbufp->msg_bufr;
1246           for (i = 0; i < msgbufp->msg_size; i++) {
1247                     j = (i + rindex) % msgbufp->msg_size;
1248                     db_printf("%c", msgbufp->msg_ptr[j]);
1249           }
1250           db_printf("\n");
1251 }
1252 
1253 #endif /* DDB */
1254 
1255 
1256 void
hexdump(const void * ptr,int length,const char * hdr,int flags)1257 hexdump(const void *ptr, int length, const char *hdr, int flags)
1258 {
1259           int i, j, k;
1260           int cols;
1261           const unsigned char *cp;
1262           char delim;
1263 
1264           if ((flags & HD_DELIM_MASK) != 0)
1265                     delim = (flags & HD_DELIM_MASK) >> 8;
1266           else
1267                     delim = ' ';
1268 
1269           if ((flags & HD_COLUMN_MASK) != 0)
1270                     cols = flags & HD_COLUMN_MASK;
1271           else
1272                     cols = 16;
1273 
1274           cp = ptr;
1275           for (i = 0; i < length; i+= cols) {
1276                     if (hdr != NULL)
1277                               kprintf("%s", hdr);
1278 
1279                     if ((flags & HD_OMIT_COUNT) == 0)
1280                               kprintf("%04x  ", i);
1281 
1282                     if ((flags & HD_OMIT_HEX) == 0) {
1283                               for (j = 0; j < cols; j++) {
1284                                         k = i + j;
1285                                         if (k < length)
1286                                                   kprintf("%c%02x", delim, cp[k]);
1287                                         else
1288                                                   kprintf("   ");
1289                               }
1290                     }
1291 
1292                     if ((flags & HD_OMIT_CHARS) == 0) {
1293                               kprintf("  |");
1294                               for (j = 0; j < cols; j++) {
1295                                         k = i + j;
1296                                         if (k >= length)
1297                                                   kprintf(" ");
1298                                         else if (cp[k] >= ' ' && cp[k] <= '~')
1299                                                   kprintf("%c", cp[k]);
1300                                         else
1301                                                   kprintf(".");
1302                               }
1303                               kprintf("|");
1304                     }
1305                     kprintf("\n");
1306           }
1307 }
1308 
1309 void
kprint_cpuset(cpumask_t * mask)1310 kprint_cpuset(cpumask_t *mask)
1311 {
1312           int i;
1313           int b = -1;
1314           int e = -1;
1315           int more = 0;
1316 
1317           kprintf("cpus(");
1318           CPUSET_FOREACH(i, *mask) {
1319                     if (b < 0) {
1320                               b = i;
1321                               e = b + 1;
1322                               continue;
1323                     }
1324                     if (e == i) {
1325                               ++e;
1326                               continue;
1327                     }
1328                     if (more)
1329                               kprintf(", ");
1330                     if (b == e - 1) {
1331                               kprintf("%d", b);
1332                     } else {
1333                               kprintf("%d-%d", b, e - 1);
1334                     }
1335                     more = 1;
1336                     b = i;
1337                     e = b + 1;
1338           }
1339           if (more)
1340                     kprintf(", ");
1341           if (b >= 0) {
1342                     if (b == e - 1) {
1343                               kprintf("%d", b);
1344                     } else {
1345                               kprintf("%d-%d", b, e - 1);
1346                     }
1347           }
1348           kprintf(") ");
1349 }
1350