Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/drivers/char/console.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * console.c
3
 * 
4
 * Emergency console I/O for Xen and the domain-0 guest OS.
5
 * 
6
 * Copyright (c) 2002-2004, K A Fraser.
7
 *
8
 * Added printf_ratelimit
9
 *     Taken from Linux - Author: Andi Kleen (net_ratelimit)
10
 *     Ported to Xen - Steven Rostedt - Red Hat
11
 */
12
13
#include <xen/version.h>
14
#include <xen/lib.h>
15
#include <xen/init.h>
16
#include <xen/event.h>
17
#include <xen/console.h>
18
#include <xen/serial.h>
19
#include <xen/softirq.h>
20
#include <xen/keyhandler.h>
21
#include <xen/guest_access.h>
22
#include <xen/watchdog.h>
23
#include <xen/shutdown.h>
24
#include <xen/video.h>
25
#include <xen/kexec.h>
26
#include <xen/ctype.h>
27
#include <xen/warning.h>
28
#include <asm/debugger.h>
29
#include <asm/div64.h>
30
#include <xen/hypercall.h> /* for do_console_io */
31
#include <xen/early_printk.h>
32
#include <xen/warning.h>
33
34
/* console: comma-separated list of console outputs. */
35
static char __initdata opt_console[30] = OPT_CONSOLE_STR;
36
string_param("console", opt_console);
37
38
/* conswitch: a character pair controlling console switching. */
39
/* Char 1: CTRL+<char1> is used to switch console input between Xen and DOM0 */
40
/* Char 2: If this character is 'x', then do not auto-switch to DOM0 when it */
41
/*         boots. Any other value, or omitting the char, enables auto-switch */
42
static unsigned char __read_mostly opt_conswitch[3] = "a";
43
string_runtime_param("conswitch", opt_conswitch);
44
45
/* sync_console: force synchronous console output (useful for debugging). */
46
static bool_t __initdata opt_sync_console;
47
boolean_param("sync_console", opt_sync_console);
48
static const char __initconst warning_sync_console[] =
49
    "WARNING: CONSOLE OUTPUT IS SYNCHRONOUS\n"
50
    "This option is intended to aid debugging of Xen by ensuring\n"
51
    "that all output is synchronously delivered on the serial line.\n"
52
    "However it can introduce SIGNIFICANT latencies and affect\n"
53
    "timekeeping. It is NOT recommended for production use!\n";
54
55
/* console_to_ring: send guest (incl. dom 0) console data to console ring. */
56
static bool_t __read_mostly opt_console_to_ring;
57
boolean_param("console_to_ring", opt_console_to_ring);
58
59
/* console_timestamps: include a timestamp prefix on every Xen console line. */
60
enum con_timestamp_mode
61
{
62
    TSM_NONE,          /* No timestamps */
63
    TSM_DATE,          /* [YYYY-MM-DD HH:MM:SS] */
64
    TSM_DATE_MS,       /* [YYYY-MM-DD HH:MM:SS.mmm] */
65
    TSM_BOOT           /* [SSSSSS.uuuuuu] */
66
};
67
68
static enum con_timestamp_mode __read_mostly opt_con_timestamp_mode = TSM_NONE;
69
70
static int parse_console_timestamps(const char *s);
71
custom_runtime_param("console_timestamps", parse_console_timestamps);
72
73
/* conring_size: allows a large console ring than default (16kB). */
74
static uint32_t __initdata opt_conring_size;
75
size_param("conring_size", opt_conring_size);
76
77
#define _CONRING_SIZE 16384
78
15.5k
#define CONRING_IDX_MASK(i) ((i)&(conring_size-1))
79
static char __initdata _conring[_CONRING_SIZE];
80
static char *__read_mostly conring = _conring;
81
static uint32_t __read_mostly conring_size = _CONRING_SIZE;
82
static uint32_t conringc, conringp;
83
84
static int __read_mostly sercon_handle = -1;
85
86
static DEFINE_SPINLOCK(console_lock);
87
88
/*
89
 * To control the amount of printing, thresholds are added.
90
 * These thresholds correspond to the XENLOG logging levels.
91
 * There's an upper and lower threshold for non-guest messages and for
92
 * guest-provoked messages.  This works as follows, for a given log level L:
93
 *
94
 * L < lower_threshold                     : always logged
95
 * lower_threshold <= L < upper_threshold  : rate-limited logging
96
 * upper_threshold <= L                    : never logged
97
 *
98
 * Note, in the above algorithm, to disable rate limiting simply make
99
 * the lower threshold equal to the upper.
100
 */
101
#ifdef NDEBUG
102
#define XENLOG_UPPER_THRESHOLD       2 /* Do not print INFO and DEBUG  */
103
#define XENLOG_LOWER_THRESHOLD       2 /* Always print ERR and WARNING */
104
#define XENLOG_GUEST_UPPER_THRESHOLD 2 /* Do not print INFO and DEBUG  */
105
#define XENLOG_GUEST_LOWER_THRESHOLD 0 /* Rate-limit ERR and WARNING   */
106
#else
107
#define XENLOG_UPPER_THRESHOLD       4 /* Do not discard anything      */
108
#define XENLOG_LOWER_THRESHOLD       4 /* Print everything             */
109
#define XENLOG_GUEST_UPPER_THRESHOLD 4 /* Do not discard anything      */
110
#define XENLOG_GUEST_LOWER_THRESHOLD 4 /* Print everything             */
111
#endif
112
/*
113
 * The XENLOG_DEFAULT is the default given to printks that
114
 * do not have any print level associated with them.
115
 */
116
194
#define XENLOG_DEFAULT       1 /* XENLOG_WARNING */
117
41
#define XENLOG_GUEST_DEFAULT 1 /* XENLOG_WARNING */
118
119
static int __read_mostly xenlog_upper_thresh = XENLOG_UPPER_THRESHOLD;
120
static int __read_mostly xenlog_lower_thresh = XENLOG_LOWER_THRESHOLD;
121
static int __read_mostly xenlog_guest_upper_thresh =
122
    XENLOG_GUEST_UPPER_THRESHOLD;
123
static int __read_mostly xenlog_guest_lower_thresh =
124
    XENLOG_GUEST_LOWER_THRESHOLD;
125
126
static int parse_loglvl(const char *s);
127
static int parse_guest_loglvl(const char *s);
128
129
/*
130
 * <lvl> := none|error|warning|info|debug|all
131
 * loglvl=<lvl_print_always>[/<lvl_print_ratelimit>]
132
 *  <lvl_print_always>: log level which is always printed
133
 *  <lvl_print_rlimit>: log level which is rate-limit printed
134
 * Similar definitions for guest_loglvl, but applies to guest tracing.
135
 * Defaults: loglvl=warning ; guest_loglvl=none/warning
136
 */
137
custom_runtime_param("loglvl", parse_loglvl);
138
custom_runtime_param("guest_loglvl", parse_guest_loglvl);
139
140
static atomic_t print_everything = ATOMIC_INIT(0);
141
142
#define ___parse_loglvl(s, ps, lvlstr, lvlnum)          \
143
12
    if ( !strncmp((s), (lvlstr), strlen(lvlstr)) ) {    \
144
2
        *(ps) = (s) + strlen(lvlstr);                   \
145
2
        return (lvlnum);                                \
146
2
    }
147
148
static int __parse_loglvl(const char *s, const char **ps)
149
2
{
150
2
    ___parse_loglvl(s, ps, "none",    0);
151
2
    ___parse_loglvl(s, ps, "error",   1);
152
2
    ___parse_loglvl(s, ps, "warning", 2);
153
2
    ___parse_loglvl(s, ps, "info",    3);
154
2
    ___parse_loglvl(s, ps, "debug",   4);
155
2
    ___parse_loglvl(s, ps, "all",     4);
156
0
    return 2; /* sane fallback */
157
2
}
158
159
static int _parse_loglvl(const char *s, int *lower, int *upper)
160
2
{
161
2
    *lower = *upper = __parse_loglvl(s, &s);
162
2
    if ( *s == '/' )
163
0
        *upper = __parse_loglvl(s+1, &s);
164
2
    if ( *upper < *lower )
165
0
        *upper = *lower;
166
2
167
2
    return *s ? -EINVAL : 0;
168
2
}
169
170
static int parse_loglvl(const char *s)
171
1
{
172
1
    return _parse_loglvl(s, &xenlog_lower_thresh, &xenlog_upper_thresh);
173
1
}
174
175
static int parse_guest_loglvl(const char *s)
176
1
{
177
1
    return _parse_loglvl(s, &xenlog_guest_lower_thresh,
178
1
                         &xenlog_guest_upper_thresh);
179
1
}
180
181
static char *loglvl_str(int lvl)
182
2
{
183
2
    switch ( lvl )
184
2
    {
185
0
    case 0: return "Nothing";
186
0
    case 1: return "Errors";
187
0
    case 2: return "Errors and warnings";
188
0
    case 3: return "Errors, warnings and info";
189
2
    case 4: return "All";
190
2
    }
191
0
    return "???";
192
2
}
193
194
static int *__read_mostly upper_thresh_adj = &xenlog_upper_thresh;
195
static int *__read_mostly lower_thresh_adj = &xenlog_lower_thresh;
196
static const char *__read_mostly thresh_adj = "standard";
197
198
static void do_toggle_guest(unsigned char key, struct cpu_user_regs *regs)
199
0
{
200
0
    if ( upper_thresh_adj == &xenlog_upper_thresh )
201
0
    {
202
0
        upper_thresh_adj = &xenlog_guest_upper_thresh;
203
0
        lower_thresh_adj = &xenlog_guest_lower_thresh;
204
0
        thresh_adj = "guest";
205
0
    }
206
0
    else
207
0
    {
208
0
        upper_thresh_adj = &xenlog_upper_thresh;
209
0
        lower_thresh_adj = &xenlog_lower_thresh;
210
0
        thresh_adj = "standard";
211
0
    }
212
0
    printk("'%c' pressed -> %s log level adjustments enabled\n",
213
0
           key, thresh_adj);
214
0
}
215
216
static void do_adj_thresh(unsigned char key)
217
0
{
218
0
    if ( *upper_thresh_adj < *lower_thresh_adj )
219
0
        *upper_thresh_adj = *lower_thresh_adj;
220
0
    printk("'%c' pressed -> %s log level: %s (rate limited %s)\n",
221
0
           key, thresh_adj, loglvl_str(*lower_thresh_adj),
222
0
           loglvl_str(*upper_thresh_adj));
223
0
}
224
225
static void do_inc_thresh(unsigned char key, struct cpu_user_regs *regs)
226
0
{
227
0
    ++*lower_thresh_adj;
228
0
    do_adj_thresh(key);
229
0
}
230
231
static void do_dec_thresh(unsigned char key, struct cpu_user_regs *regs)
232
0
{
233
0
    if ( *lower_thresh_adj )
234
0
        --*lower_thresh_adj;
235
0
    do_adj_thresh(key);
236
0
}
237
238
/*
239
 * ********************************************************
240
 * *************** ACCESS TO CONSOLE RING *****************
241
 * ********************************************************
242
 */
243
244
static void conring_puts(const char *str)
245
1.02k
{
246
1.02k
    char c;
247
1.02k
248
1.02k
    ASSERT(spin_is_locked(&console_lock));
249
1.02k
250
16.5k
    while ( (c = *str++) != '\0' )
251
15.5k
        conring[CONRING_IDX_MASK(conringp++)] = c;
252
1.02k
253
1.02k
    if ( (uint32_t)(conringp - conringc) > conring_size )
254
0
        conringc = conringp - conring_size;
255
1.02k
}
256
257
long read_console_ring(struct xen_sysctl_readconsole *op)
258
0
{
259
0
    XEN_GUEST_HANDLE_PARAM(char) str;
260
0
    uint32_t idx, len, max, sofar, c, p;
261
0
262
0
    str   = guest_handle_cast(op->buffer, char),
263
0
    max   = op->count;
264
0
    sofar = 0;
265
0
266
0
    c = read_atomic(&conringc);
267
0
    p = read_atomic(&conringp);
268
0
    if ( op->incremental &&
269
0
         (c <= p ? c < op->index && op->index <= p
270
0
                 : c < op->index || op->index <= p) )
271
0
        c = op->index;
272
0
273
0
    while ( (c != p) && (sofar < max) )
274
0
    {
275
0
        idx = CONRING_IDX_MASK(c);
276
0
        len = p - c;
277
0
        if ( (idx + len) > conring_size )
278
0
            len = conring_size - idx;
279
0
        if ( (sofar + len) > max )
280
0
            len = max - sofar;
281
0
        if ( copy_to_guest_offset(str, sofar, &conring[idx], len) )
282
0
            return -EFAULT;
283
0
        sofar += len;
284
0
        c += len;
285
0
    }
286
0
287
0
    if ( op->clear )
288
0
    {
289
0
        spin_lock_irq(&console_lock);
290
0
        conringc = p - c > conring_size ? p - conring_size : c;
291
0
        spin_unlock_irq(&console_lock);
292
0
    }
293
0
294
0
    op->count = sofar;
295
0
    op->index = c;
296
0
297
0
    return 0;
298
0
}
299
300
301
/*
302
 * *******************************************************
303
 * *************** ACCESS TO SERIAL LINE *****************
304
 * *******************************************************
305
 */
306
307
/* Characters received over the serial line are buffered for domain 0. */
308
0
#define SERIAL_RX_SIZE 128
309
0
#define SERIAL_RX_MASK(_i) ((_i)&(SERIAL_RX_SIZE-1))
310
static char serial_rx_ring[SERIAL_RX_SIZE];
311
static unsigned int serial_rx_cons, serial_rx_prod;
312
313
static void (*serial_steal_fn)(const char *) = early_puts;
314
315
int console_steal(int handle, void (*fn)(const char *))
316
0
{
317
0
    if ( (handle == -1) || (handle != sercon_handle) )
318
0
        return 0;
319
0
320
0
    if ( serial_steal_fn != NULL )
321
0
        return -EBUSY;
322
0
323
0
    serial_steal_fn = fn;
324
0
    return 1;
325
0
}
326
327
void console_giveback(int id)
328
0
{
329
0
    if ( id == 1 )
330
0
        serial_steal_fn = NULL;
331
0
}
332
333
static void sercon_puts(const char *s)
334
119k
{
335
119k
    if ( serial_steal_fn != NULL )
336
0
        (*serial_steal_fn)(s);
337
119k
    else
338
119k
        serial_puts(sercon_handle, s);
339
119k
}
340
341
static void dump_console_ring_key(unsigned char key)
342
0
{
343
0
    uint32_t idx, len, sofar, c;
344
0
    unsigned int order;
345
0
    char *buf;
346
0
347
0
    printk("'%c' pressed -> dumping console ring buffer (dmesg)\n", key);
348
0
349
0
    /* create a buffer in which we'll copy the ring in the correct
350
0
       order and NUL terminate */
351
0
    order = get_order_from_bytes(conring_size + 1);
352
0
    buf = alloc_xenheap_pages(order, 0);
353
0
    if ( buf == NULL )
354
0
    {
355
0
        printk("unable to allocate memory!\n");
356
0
        return;
357
0
    }
358
0
359
0
    c = conringc;
360
0
    sofar = 0;
361
0
    while ( (c != conringp) )
362
0
    {
363
0
        idx = CONRING_IDX_MASK(c);
364
0
        len = conringp - c;
365
0
        if ( (idx + len) > conring_size )
366
0
            len = conring_size - idx;
367
0
        memcpy(buf + sofar, &conring[idx], len);
368
0
        sofar += len;
369
0
        c += len;
370
0
    }
371
0
    buf[sofar] = '\0';
372
0
373
0
    sercon_puts(buf);
374
0
    video_puts(buf);
375
0
376
0
    free_xenheap_pages(buf, order);
377
0
}
378
379
/* CTRL-<switch_char> switches input direction between Xen and DOM0. */
380
1
#define switch_code (opt_conswitch[0]-'a'+1)
381
static int __read_mostly xen_rx = 1; /* FALSE => input passed to domain 0. */
382
383
static void switch_serial_input(void)
384
1
{
385
1
    static char *input_str[2] = { "DOM0", "Xen" };
386
1
    xen_rx = !xen_rx;
387
1
    printk("*** Serial input -> %s", input_str[xen_rx]);
388
1
    if ( switch_code )
389
1
        printk(" (type 'CTRL-%c' three times to switch input to %s)",
390
1
               opt_conswitch[0], input_str[!xen_rx]);
391
1
    printk("\n");
392
1
}
393
394
static void __serial_rx(char c, struct cpu_user_regs *regs)
395
0
{
396
0
    if ( xen_rx )
397
0
        return handle_keypress(c, regs);
398
0
399
0
    /* Deliver input to guest buffer, unless it is already full. */
400
0
    if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE )
401
0
        serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
402
0
    /* Always notify the guest: prevents receive path from getting stuck. */
403
0
    send_global_virq(VIRQ_CONSOLE);
404
0
}
405
406
static void serial_rx(char c, struct cpu_user_regs *regs)
407
0
{
408
0
    static int switch_code_count = 0;
409
0
410
0
    if ( switch_code && (c == switch_code) )
411
0
    {
412
0
        /* We eat CTRL-<switch_char> in groups of 3 to switch console input. */
413
0
        if ( ++switch_code_count == 3 )
414
0
        {
415
0
            switch_serial_input();
416
0
            switch_code_count = 0;
417
0
        }
418
0
        return;
419
0
    }
420
0
421
0
    for ( ; switch_code_count != 0; switch_code_count-- )
422
0
        __serial_rx(switch_code, regs);
423
0
424
0
    /* Finally process the just-received character. */
425
0
    __serial_rx(c, regs);
426
0
}
427
428
static void notify_dom0_con_ring(unsigned long unused)
429
131
{
430
131
    send_global_virq(VIRQ_CON_RING);
431
131
}
432
static DECLARE_SOFTIRQ_TASKLET(notify_dom0_con_ring_tasklet,
433
                               notify_dom0_con_ring, 0);
434
435
static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer, int count)
436
118k
{
437
118k
    char kbuf[128];
438
118k
    int kcount = 0;
439
118k
    struct domain *cd = current->domain;
440
118k
441
237k
    while ( count > 0 )
442
118k
    {
443
118k
        if ( kcount && hypercall_preempt_check() )
444
0
            return hypercall_create_continuation(
445
0
                __HYPERVISOR_console_io, "iih",
446
0
                CONSOLEIO_write, count, buffer);
447
118k
448
118k
        kcount = min_t(int, count, sizeof(kbuf)-1);
449
118k
        if ( copy_from_guest(kbuf, buffer, kcount) )
450
0
            return -EFAULT;
451
118k
        kbuf[kcount] = '\0';
452
118k
453
118k
        if ( is_hardware_domain(cd) )
454
118k
        {
455
118k
            /* Use direct console output as it could be interactive */
456
118k
            spin_lock_irq(&console_lock);
457
118k
458
118k
            sercon_puts(kbuf);
459
118k
            video_puts(kbuf);
460
118k
461
118k
            if ( opt_console_to_ring )
462
0
            {
463
0
                conring_puts(kbuf);
464
0
                tasklet_schedule(&notify_dom0_con_ring_tasklet);
465
0
            }
466
118k
467
118k
            spin_unlock_irq(&console_lock);
468
118k
        }
469
118k
        else
470
0
        {
471
0
            char *kin = kbuf, *kout = kbuf, c;
472
0
473
0
            /* Strip non-printable characters */
474
0
            for ( ; ; )
475
0
            {
476
0
                c = *kin++;
477
0
                if ( c == '\0' || c == '\n' )
478
0
                    break;
479
0
                if ( isprint(c) || c == '\t' )
480
0
                    *kout++ = c;
481
0
            }
482
0
            *kout = '\0';
483
0
            spin_lock(&cd->pbuf_lock);
484
0
            if ( c == '\n' )
485
0
            {
486
0
                kcount = kin - kbuf;
487
0
                cd->pbuf[cd->pbuf_idx] = '\0';
488
0
                guest_printk(cd, XENLOG_G_DEBUG "%s%s\n", cd->pbuf, kbuf);
489
0
                cd->pbuf_idx = 0;
490
0
            }
491
0
            else if ( cd->pbuf_idx + kcount < (DOMAIN_PBUF_SIZE - 1) )
492
0
            {
493
0
                /* buffer the output until a newline */
494
0
                memcpy(cd->pbuf + cd->pbuf_idx, kbuf, kcount);
495
0
                cd->pbuf_idx += kcount;
496
0
            }
497
0
            else
498
0
            {
499
0
                cd->pbuf[cd->pbuf_idx] = '\0';
500
0
                guest_printk(cd, XENLOG_G_DEBUG "%s%s\n", cd->pbuf, kbuf);
501
0
                cd->pbuf_idx = 0;
502
0
            }
503
0
            spin_unlock(&cd->pbuf_lock);
504
0
        }
505
118k
506
118k
        guest_handle_add_offset(buffer, kcount);
507
118k
        count -= kcount;
508
118k
    }
509
118k
510
118k
    return 0;
511
118k
}
512
513
long do_console_io(int cmd, int count, XEN_GUEST_HANDLE_PARAM(char) buffer)
514
118k
{
515
118k
    long rc;
516
118k
    unsigned int idx, len;
517
118k
518
118k
    rc = xsm_console_io(XSM_OTHER, current->domain, cmd);
519
118k
    if ( rc )
520
0
        return rc;
521
118k
522
118k
    switch ( cmd )
523
118k
    {
524
118k
    case CONSOLEIO_write:
525
118k
        rc = guest_console_write(buffer, count);
526
118k
        break;
527
0
    case CONSOLEIO_read:
528
0
        rc = 0;
529
0
        while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
530
0
        {
531
0
            idx = SERIAL_RX_MASK(serial_rx_cons);
532
0
            len = serial_rx_prod - serial_rx_cons;
533
0
            if ( (idx + len) > SERIAL_RX_SIZE )
534
0
                len = SERIAL_RX_SIZE - idx;
535
0
            if ( (rc + len) > count )
536
0
                len = count - rc;
537
0
            if ( copy_to_guest_offset(buffer, rc, &serial_rx_ring[idx], len) )
538
0
            {
539
0
                rc = -EFAULT;
540
0
                break;
541
0
            }
542
0
            rc += len;
543
0
            serial_rx_cons += len;
544
0
        }
545
0
        break;
546
0
    default:
547
0
        rc = -ENOSYS;
548
0
        break;
549
118k
    }
550
118k
551
118k
    return rc;
552
118k
}
553
554
555
/*
556
 * *****************************************************
557
 * *************** GENERIC CONSOLE I/O *****************
558
 * *****************************************************
559
 */
560
561
static bool_t console_locks_busted;
562
563
static void __putstr(const char *str)
564
1.02k
{
565
1.02k
    ASSERT(spin_is_locked(&console_lock));
566
1.02k
567
1.02k
    sercon_puts(str);
568
1.02k
    video_puts(str);
569
1.02k
570
1.02k
    conring_puts(str);
571
1.02k
572
1.02k
    if ( !console_locks_busted )
573
1.02k
        tasklet_schedule(&notify_dom0_con_ring_tasklet);
574
1.02k
}
575
576
static int printk_prefix_check(char *p, char **pp)
577
308
{
578
308
    int loglvl = -1;
579
308
    int upper_thresh = xenlog_upper_thresh;
580
308
    int lower_thresh = xenlog_lower_thresh;
581
308
582
463
    while ( (p[0] == '<') && (p[1] != '\0') && (p[2] == '>') )
583
155
    {
584
155
        switch ( p[1] )
585
155
        {
586
41
        case 'G':
587
41
            upper_thresh = xenlog_guest_upper_thresh;
588
41
            lower_thresh = xenlog_guest_lower_thresh;
589
41
            if ( loglvl == -1 )
590
41
                loglvl = XENLOG_GUEST_DEFAULT;
591
41
            break;
592
114
        case '0' ... '3':
593
114
            loglvl = p[1] - '0';
594
114
            break;
595
155
        }
596
155
        p += 3;
597
155
    }
598
308
599
308
    if ( loglvl == -1 )
600
194
        loglvl = XENLOG_DEFAULT;
601
308
602
308
    *pp = p;
603
308
604
308
    return ((atomic_read(&print_everything) != 0) ||
605
308
            (loglvl < lower_thresh) ||
606
0
            ((loglvl < upper_thresh) && printk_ratelimit()));
607
308
} 
608
609
static int parse_console_timestamps(const char *s)
610
0
{
611
0
    switch ( parse_bool(s, NULL) )
612
0
    {
613
0
    case 0:
614
0
        opt_con_timestamp_mode = TSM_NONE;
615
0
        return 0;
616
0
    case 1:
617
0
        opt_con_timestamp_mode = TSM_DATE;
618
0
        return 0;
619
0
    }
620
0
    if ( *s == '\0' || /* Compat for old booleanparam() */
621
0
         !strcmp(s, "date") )
622
0
        opt_con_timestamp_mode = TSM_DATE;
623
0
    else if ( !strcmp(s, "datems") )
624
0
        opt_con_timestamp_mode = TSM_DATE_MS;
625
0
    else if ( !strcmp(s, "boot") )
626
0
        opt_con_timestamp_mode = TSM_BOOT;
627
0
    else if ( !strcmp(s, "none") )
628
0
        opt_con_timestamp_mode = TSM_NONE;
629
0
    else
630
0
        return -EINVAL;
631
0
632
0
    return 0;
633
0
}
634
635
static void printk_start_of_line(const char *prefix)
636
308
{
637
308
    struct tm tm;
638
308
    char tstr[32];
639
308
    uint64_t sec, nsec;
640
308
641
308
    __putstr(prefix);
642
308
643
308
    switch ( opt_con_timestamp_mode )
644
308
    {
645
0
    case TSM_DATE:
646
0
    case TSM_DATE_MS:
647
0
        tm = wallclock_time(&nsec);
648
0
649
0
        if ( tm.tm_mday == 0 )
650
0
            return;
651
0
652
0
        if ( opt_con_timestamp_mode == TSM_DATE )
653
0
            snprintf(tstr, sizeof(tstr), "[%04u-%02u-%02u %02u:%02u:%02u] ",
654
0
                     1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
655
0
                     tm.tm_hour, tm.tm_min, tm.tm_sec);
656
0
        else
657
0
            snprintf(tstr, sizeof(tstr),
658
0
                     "[%04u-%02u-%02u %02u:%02u:%02u.%03"PRIu64"] ",
659
0
                     1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
660
0
                     tm.tm_hour, tm.tm_min, tm.tm_sec, nsec / 1000000);
661
0
        break;
662
0
663
0
    case TSM_BOOT:
664
0
        sec = NOW();
665
0
        nsec = do_div(sec, 1000000000);
666
0
667
0
        snprintf(tstr, sizeof(tstr), "[%5"PRIu64".%06"PRIu64"] ",
668
0
                 sec, nsec / 1000);
669
0
        break;
670
0
671
308
    case TSM_NONE:
672
308
    default:
673
308
        return;
674
308
    }
675
308
676
0
    __putstr(tstr);
677
0
}
678
679
static void vprintk_common(const char *prefix, const char *fmt, va_list args)
680
401
{
681
401
    struct vps {
682
401
        bool_t continued, do_print;
683
401
    }            *state;
684
401
    static DEFINE_PER_CPU(struct vps, state);
685
401
    static char   buf[1024];
686
401
    char         *p, *q;
687
401
    unsigned long flags;
688
401
689
401
    /* console_lock can be acquired recursively from __printk_ratelimit(). */
690
401
    local_irq_save(flags);
691
401
    spin_lock_recursive(&console_lock);
692
401
    state = &this_cpu(state);
693
401
694
401
    (void)vsnprintf(buf, sizeof(buf), fmt, args);
695
401
696
401
    p = buf;
697
401
698
709
    while ( (q = strchr(p, '\n')) != NULL )
699
308
    {
700
308
        *q = '\0';
701
308
        if ( !state->continued )
702
259
            state->do_print = printk_prefix_check(p, &p);
703
308
        if ( state->do_print )
704
308
        {
705
308
            if ( !state->continued )
706
259
                printk_start_of_line(prefix);
707
308
            __putstr(p);
708
308
            __putstr("\n");
709
308
        }
710
308
        state->continued = 0;
711
308
        p = q + 1;
712
308
    }
713
401
714
401
    if ( *p != '\0' )
715
98
    {
716
98
        if ( !state->continued )
717
49
            state->do_print = printk_prefix_check(p, &p);
718
98
        if ( state->do_print )
719
98
        {
720
98
            if ( !state->continued )
721
49
                printk_start_of_line(prefix);
722
98
            __putstr(p);
723
98
        }
724
98
        state->continued = 1;
725
98
    }
726
401
727
401
    spin_unlock_recursive(&console_lock);
728
401
    local_irq_restore(flags);
729
401
}
730
731
void printk(const char *fmt, ...)
732
401
{
733
401
    va_list args;
734
401
    va_start(args, fmt);
735
401
    vprintk_common("(XEN) ", fmt, args);
736
401
    va_end(args);
737
401
}
738
739
void guest_printk(const struct domain *d, const char *fmt, ...)
740
0
{
741
0
    va_list args;
742
0
    char prefix[16];
743
0
744
0
    snprintf(prefix, sizeof(prefix), "(d%d) ", d->domain_id);
745
0
746
0
    va_start(args, fmt);
747
0
    vprintk_common(prefix, fmt, args);
748
0
    va_end(args);
749
0
}
750
751
void __init console_init_preirq(void)
752
1
{
753
1
    char *p;
754
1
    int sh;
755
1
756
1
    serial_init_preirq();
757
1
758
1
    /* Where should console output go? */
759
3
    for ( p = opt_console; p != NULL; p = strchr(p, ',') )
760
2
    {
761
2
        if ( *p == ',' )
762
1
            p++;
763
2
        if ( !strncmp(p, "vga", 3) )
764
1
            video_init();
765
1
        else if ( !strncmp(p, "none", 4) )
766
0
            continue;
767
1
        else if ( (sh = serial_parse_handle(p)) >= 0 )
768
1
        {
769
1
            sercon_handle = sh;
770
1
            serial_steal_fn = NULL;
771
1
        }
772
1
        else
773
0
        {
774
0
            char *q = strchr(p, ',');
775
0
            if ( q != NULL )
776
0
                *q = '\0';
777
0
            printk("Bad console= option '%s'\n", p);
778
0
            if ( q != NULL )
779
0
                *q = ',';
780
0
        }
781
2
    }
782
1
783
1
    serial_set_rx_handler(sercon_handle, serial_rx);
784
1
785
1
    /* HELLO WORLD --- start-of-day banner text. */
786
1
    spin_lock(&console_lock);
787
1
    __putstr(xen_banner());
788
1
    spin_unlock(&console_lock);
789
1
    printk("Xen version %d.%d%s (%s@%s) (%s) debug=%c " gcov_string " %s\n",
790
1
           xen_major_version(), xen_minor_version(), xen_extra_version(),
791
1
           xen_compile_by(), xen_compile_domain(),
792
1
           xen_compiler(), debug_build() ? 'y' : 'n', xen_compile_date());
793
1
    printk("Latest ChangeSet: %s\n", xen_changeset());
794
1
795
1
    if ( opt_sync_console )
796
1
    {
797
1
        serial_start_sync(sercon_handle);
798
1
        add_taint(TAINT_SYNC_CONSOLE);
799
1
        printk("Console output is synchronous.\n");
800
1
        warning_add(warning_sync_console);
801
1
    }
802
1
}
803
804
void __init console_init_ring(void)
805
2
{
806
2
    char *ring;
807
2
    unsigned int i, order, memflags;
808
2
    unsigned long flags;
809
2
810
2
    if ( !opt_conring_size )
811
1
        return;
812
2
813
1
    order = get_order_from_bytes(max(opt_conring_size, conring_size));
814
1
    memflags = MEMF_bits(crashinfo_maxaddr_bits);
815
1
    while ( (ring = alloc_xenheap_pages(order, memflags)) == NULL )
816
0
    {
817
0
        BUG_ON(order == 0);
818
0
        order--;
819
0
    }
820
1
    opt_conring_size = PAGE_SIZE << order;
821
1
822
1
    spin_lock_irqsave(&console_lock, flags);
823
8.18k
    for ( i = conringc ; i != conringp; i++ )
824
8.18k
        ring[i & (opt_conring_size - 1)] = conring[i & (conring_size - 1)];
825
1
    conring = ring;
826
1
    smp_wmb(); /* Allow users of console_force_unlock() to see larger buffer. */
827
1
    conring_size = opt_conring_size;
828
1
    spin_unlock_irqrestore(&console_lock, flags);
829
1
830
1
    printk("Allocated console ring of %u KiB.\n", opt_conring_size >> 10);
831
1
}
832
833
void __init console_init_postirq(void)
834
1
{
835
1
    serial_init_postirq();
836
1
837
1
    if ( conring != _conring )
838
0
        return;
839
1
840
1
    if ( !opt_conring_size )
841
1
        opt_conring_size = num_present_cpus() << (9 + xenlog_lower_thresh);
842
1
843
1
    console_init_ring();
844
1
}
845
846
void __init console_endboot(void)
847
1
{
848
1
    printk("Std. Loglevel: %s", loglvl_str(xenlog_lower_thresh));
849
1
    if ( xenlog_upper_thresh != xenlog_lower_thresh )
850
0
        printk(" (Rate-limited: %s)", loglvl_str(xenlog_upper_thresh));
851
1
    printk("\nGuest Loglevel: %s", loglvl_str(xenlog_guest_lower_thresh));
852
1
    if ( xenlog_guest_upper_thresh != xenlog_guest_lower_thresh )
853
0
        printk(" (Rate-limited: %s)", loglvl_str(xenlog_guest_upper_thresh));
854
1
    printk("\n");
855
1
856
1
    warning_print();
857
1
858
1
    video_endboot();
859
1
860
1
    /*
861
1
     * If user specifies so, we fool the switch routine to redirect input
862
1
     * straight back to Xen. I use this convoluted method so we still print
863
1
     * a useful 'how to switch' message.
864
1
     */
865
1
    if ( opt_conswitch[1] == 'x' )
866
0
        xen_rx = !xen_rx;
867
1
868
1
    register_keyhandler('w', dump_console_ring_key,
869
1
                        "synchronously dump console ring buffer (dmesg)", 0);
870
1
    register_irq_keyhandler('+', &do_inc_thresh,
871
1
                            "increase log level threshold", 0);
872
1
    register_irq_keyhandler('-', &do_dec_thresh,
873
1
                            "decrease log level threshold", 0);
874
1
    register_irq_keyhandler('G', &do_toggle_guest,
875
1
                            "toggle host/guest log level adjustment", 0);
876
1
877
1
    /* Serial input is directed to DOM0 by default. */
878
1
    switch_serial_input();
879
1
}
880
881
int __init console_has(const char *device)
882
2
{
883
2
    char *p;
884
2
885
4
    for ( p = opt_console; p != NULL; p = strchr(p, ',') )
886
3
    {
887
3
        if ( *p == ',' )
888
1
            p++;
889
3
        if ( strncmp(p, device, strlen(device)) == 0 )
890
1
            return 1;
891
3
    }
892
2
893
1
    return 0;
894
2
}
895
896
void console_start_log_everything(void)
897
0
{
898
0
    serial_start_log_everything(sercon_handle);
899
0
    atomic_inc(&print_everything);
900
0
}
901
902
void console_end_log_everything(void)
903
0
{
904
0
    serial_end_log_everything(sercon_handle);
905
0
    atomic_dec(&print_everything);
906
0
}
907
908
unsigned long console_lock_recursive_irqsave(void)
909
0
{
910
0
    unsigned long flags;
911
0
912
0
    local_irq_save(flags);
913
0
    spin_lock_recursive(&console_lock);
914
0
915
0
    return flags;
916
0
}
917
918
void console_unlock_recursive_irqrestore(unsigned long flags)
919
0
{
920
0
    spin_unlock_recursive(&console_lock);
921
0
    local_irq_restore(flags);
922
0
}
923
924
void console_force_unlock(void)
925
0
{
926
0
    watchdog_disable();
927
0
    spin_lock_init(&console_lock);
928
0
    serial_force_unlock(sercon_handle);
929
0
    console_locks_busted = 1;
930
0
    console_start_sync();
931
0
}
932
933
void console_start_sync(void)
934
0
{
935
0
    atomic_inc(&print_everything);
936
0
    serial_start_sync(sercon_handle);
937
0
}
938
939
void console_end_sync(void)
940
0
{
941
0
    serial_end_sync(sercon_handle);
942
0
    atomic_dec(&print_everything);
943
0
}
944
945
/*
946
 * printk rate limiting, lifted from Linux.
947
 *
948
 * This enforces a rate limit: not more than one kernel message
949
 * every printk_ratelimit_ms (millisecs).
950
 */
951
int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst)
952
0
{
953
0
    static DEFINE_SPINLOCK(ratelimit_lock);
954
0
    static unsigned long toks = 10 * 5 * 1000;
955
0
    static unsigned long last_msg;
956
0
    static int missed;
957
0
    unsigned long flags;
958
0
    unsigned long long now = NOW(); /* ns */
959
0
    unsigned long ms;
960
0
961
0
    do_div(now, 1000000);
962
0
    ms = (unsigned long)now;
963
0
964
0
    spin_lock_irqsave(&ratelimit_lock, flags);
965
0
    toks += ms - last_msg;
966
0
    last_msg = ms;
967
0
    if ( toks > (ratelimit_burst * ratelimit_ms))
968
0
        toks = ratelimit_burst * ratelimit_ms;
969
0
    if ( toks >= ratelimit_ms )
970
0
    {
971
0
        int lost = missed;
972
0
        missed = 0;
973
0
        toks -= ratelimit_ms;
974
0
        spin_unlock(&ratelimit_lock);
975
0
        if ( lost )
976
0
        {
977
0
            char lost_str[8];
978
0
            snprintf(lost_str, sizeof(lost_str), "%d", lost);
979
0
            /* console_lock may already be acquired by printk(). */
980
0
            spin_lock_recursive(&console_lock);
981
0
            printk_start_of_line("(XEN) ");
982
0
            __putstr("printk: ");
983
0
            __putstr(lost_str);
984
0
            __putstr(" messages suppressed.\n");
985
0
            spin_unlock_recursive(&console_lock);
986
0
        }
987
0
        local_irq_restore(flags);
988
0
        return 1;
989
0
    }
990
0
    missed++;
991
0
    spin_unlock_irqrestore(&ratelimit_lock, flags);
992
0
    return 0;
993
0
}
994
995
/* minimum time in ms between messages */
996
static int __read_mostly printk_ratelimit_ms = 5 * 1000;
997
998
/* number of messages we send before ratelimiting */
999
static int __read_mostly printk_ratelimit_burst = 10;
1000
1001
int printk_ratelimit(void)
1002
0
{
1003
0
    return __printk_ratelimit(printk_ratelimit_ms, printk_ratelimit_burst);
1004
0
}
1005
1006
/*
1007
 * **************************************************************
1008
 * *************** Serial console ring buffer *******************
1009
 * **************************************************************
1010
 */
1011
1012
#ifdef DEBUG_TRACE_DUMP
1013
1014
/* Send output direct to console, or buffer it? */
1015
static volatile int debugtrace_send_to_console;
1016
1017
static char        *debugtrace_buf; /* Debug-trace buffer */
1018
static unsigned int debugtrace_prd; /* Producer index     */
1019
static unsigned int debugtrace_kilobytes = 128, debugtrace_bytes;
1020
static unsigned int debugtrace_used;
1021
static DEFINE_SPINLOCK(debugtrace_lock);
1022
integer_param("debugtrace", debugtrace_kilobytes);
1023
1024
static void debugtrace_dump_worker(void)
1025
{
1026
    if ( (debugtrace_bytes == 0) || !debugtrace_used )
1027
        return;
1028
1029
    printk("debugtrace_dump() starting\n");
1030
1031
    /* Print oldest portion of the ring. */
1032
    ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);
1033
    sercon_puts(&debugtrace_buf[debugtrace_prd]);
1034
1035
    /* Print youngest portion of the ring. */
1036
    debugtrace_buf[debugtrace_prd] = '\0';
1037
    sercon_puts(&debugtrace_buf[0]);
1038
1039
    memset(debugtrace_buf, '\0', debugtrace_bytes);
1040
1041
    printk("debugtrace_dump() finished\n");
1042
}
1043
1044
static void debugtrace_toggle(void)
1045
{
1046
    unsigned long flags;
1047
1048
    watchdog_disable();
1049
    spin_lock_irqsave(&debugtrace_lock, flags);
1050
1051
    /*
1052
     * Dump the buffer *before* toggling, in case the act of dumping the
1053
     * buffer itself causes more printk() invocations.
1054
     */
1055
    printk("debugtrace_printk now writing to %s.\n",
1056
           !debugtrace_send_to_console ? "console": "buffer");
1057
    if ( !debugtrace_send_to_console )
1058
        debugtrace_dump_worker();
1059
1060
    debugtrace_send_to_console = !debugtrace_send_to_console;
1061
1062
    spin_unlock_irqrestore(&debugtrace_lock, flags);
1063
    watchdog_enable();
1064
1065
}
1066
1067
void debugtrace_dump(void)
1068
{
1069
    unsigned long flags;
1070
1071
    watchdog_disable();
1072
    spin_lock_irqsave(&debugtrace_lock, flags);
1073
1074
    debugtrace_dump_worker();
1075
1076
    spin_unlock_irqrestore(&debugtrace_lock, flags);
1077
    watchdog_enable();
1078
}
1079
1080
void debugtrace_printk(const char *fmt, ...)
1081
{
1082
    static char    buf[1024];
1083
    static u32 count;
1084
1085
    va_list       args;
1086
    char         *p;
1087
    unsigned long flags;
1088
1089
    if ( debugtrace_bytes == 0 )
1090
        return;
1091
1092
    debugtrace_used = 1;
1093
1094
    spin_lock_irqsave(&debugtrace_lock, flags);
1095
1096
    ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);
1097
1098
    snprintf(buf, sizeof(buf), "%u ", ++count);
1099
1100
    va_start(args, fmt);
1101
    (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, args);
1102
    va_end(args);
1103
1104
    if ( debugtrace_send_to_console )
1105
    {
1106
        serial_puts(sercon_handle, buf);
1107
    }
1108
    else
1109
    {
1110
        for ( p = buf; *p != '\0'; p++ )
1111
        {
1112
            debugtrace_buf[debugtrace_prd++] = *p;            
1113
            /* Always leave a nul byte at the end of the buffer. */
1114
            if ( debugtrace_prd == (debugtrace_bytes - 1) )
1115
                debugtrace_prd = 0;
1116
        }
1117
    }
1118
1119
    spin_unlock_irqrestore(&debugtrace_lock, flags);
1120
}
1121
1122
static void debugtrace_key(unsigned char key)
1123
{
1124
    debugtrace_toggle();
1125
}
1126
1127
static int __init debugtrace_init(void)
1128
{
1129
    int order;
1130
    unsigned int kbytes, bytes;
1131
1132
    /* Round size down to next power of two. */
1133
    while ( (kbytes = (debugtrace_kilobytes & (debugtrace_kilobytes-1))) != 0 )
1134
        debugtrace_kilobytes = kbytes;
1135
1136
    bytes = debugtrace_kilobytes << 10;
1137
    if ( bytes == 0 )
1138
        return 0;
1139
1140
    order = get_order_from_bytes(bytes);
1141
    debugtrace_buf = alloc_xenheap_pages(order, 0);
1142
    ASSERT(debugtrace_buf != NULL);
1143
1144
    memset(debugtrace_buf, '\0', bytes);
1145
1146
    debugtrace_bytes = bytes;
1147
1148
    register_keyhandler('T', debugtrace_key,
1149
                        "toggle debugtrace to console/buffer", 0);
1150
1151
    return 0;
1152
}
1153
__initcall(debugtrace_init);
1154
1155
#endif /* !NDEBUG */
1156
1157
1158
/*
1159
 * **************************************************************
1160
 * *************** Debugging/tracing/error-report ***************
1161
 * **************************************************************
1162
 */
1163
1164
void panic(const char *fmt, ...)
1165
0
{
1166
0
    va_list args;
1167
0
    unsigned long flags;
1168
0
    static DEFINE_SPINLOCK(lock);
1169
0
    static char buf[128];
1170
0
    
1171
0
    debugtrace_dump();
1172
0
1173
0
    /* Protects buf[] and ensure multi-line message prints atomically. */
1174
0
    spin_lock_irqsave(&lock, flags);
1175
0
1176
0
    va_start(args, fmt);
1177
0
    (void)vsnprintf(buf, sizeof(buf), fmt, args);
1178
0
    va_end(args);
1179
0
1180
0
    console_start_sync();
1181
0
    printk("\n****************************************\n");
1182
0
    printk("Panic on CPU %d:\n", smp_processor_id());
1183
0
    printk("%s\n", buf);
1184
0
    printk("****************************************\n\n");
1185
0
    if ( opt_noreboot )
1186
0
        printk("Manual reset required ('noreboot' specified)\n");
1187
0
    else
1188
0
        printk("Reboot in five seconds...\n");
1189
0
1190
0
    spin_unlock_irqrestore(&lock, flags);
1191
0
1192
0
    debugger_trap_immediate();
1193
0
1194
0
#ifdef CONFIG_KEXEC
1195
0
    kexec_crash();
1196
0
#endif
1197
0
1198
0
    if ( opt_noreboot )
1199
0
        machine_halt();
1200
0
    else
1201
0
        machine_restart(5000);
1202
0
}
1203
1204
/*
1205
 * **************************************************************
1206
 * ****************** Console suspend/resume ********************
1207
 * **************************************************************
1208
 */
1209
1210
0
static void suspend_steal_fn(const char *str) { }
1211
static int suspend_steal_id;
1212
1213
int console_suspend(void)
1214
0
{
1215
0
    suspend_steal_id = console_steal(sercon_handle, suspend_steal_fn);
1216
0
    serial_suspend();
1217
0
    return 0;
1218
0
}
1219
1220
int console_resume(void)
1221
0
{
1222
0
    serial_resume();
1223
0
    console_giveback(suspend_steal_id);
1224
0
    return 0;
1225
0
}
1226
1227
/*
1228
 * Local variables:
1229
 * mode: C
1230
 * c-file-style: "BSD"
1231
 * c-basic-offset: 4
1232
 * tab-width: 4
1233
 * indent-tabs-mode: nil
1234
 * End:
1235
 */
1236