~ressu/+junk/xen-debian

« back to all changes in this revision

Viewing changes to xen/common/keyhandler.c

  • Committer: sami at haahtinen
  • Author(s): Bastian Blank
  • Date: 2011-03-17 14:12:45 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: sami@haahtinen.name-20110317141245-owgqox0l0p3g5857
Tags: 4.1.0~rc6-1
* New upstream release candidate.
* Build documentation using pdflatex.
* Use python 2.6. (closes: #596545)
* Fix lintian override.
* Install new tools: xl, xenpaging.
* Enable blktap2.
  - Use own md5 implementation.
  - Fix includes.
  - Fix linking of blktap2 binaries.
  - Remove optimization setting.
* Temporarily disable hvmloader, wants to download ipxe.
* Remove xenstored pid check from xl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
#include <xen/console.h>
10
10
#include <xen/serial.h>
11
11
#include <xen/sched.h>
12
 
#include <xen/softirq.h>
 
12
#include <xen/tasklet.h>
13
13
#include <xen/domain.h>
14
14
#include <xen/rangeset.h>
15
15
#include <xen/compat.h>
19
19
 
20
20
static struct keyhandler *key_table[256];
21
21
static unsigned char keypress_key;
 
22
static bool_t alt_key_handling;
22
23
 
23
24
char keyhandler_scratch[1024];
24
25
 
70
71
    .desc = "show this message"
71
72
};
72
73
 
73
 
static void __dump_execstate(void *unused)
 
74
static cpumask_t dump_execstate_mask;
 
75
 
 
76
void dump_execstate(struct cpu_user_regs *regs)
74
77
{
75
 
    dump_execution_state();
76
 
    printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
77
 
    if ( is_idle_vcpu(current) )
78
 
        printk("No guest context (CPU is idle).\n");
79
 
    else
 
78
    unsigned int cpu = smp_processor_id();
 
79
 
 
80
    if ( !guest_mode(regs) )
 
81
    {
 
82
        printk("*** Dumping CPU%u host state: ***\n", cpu);
 
83
        show_execution_state(regs);
 
84
    }
 
85
 
 
86
    if ( !is_idle_vcpu(current) )
 
87
    {
 
88
        printk("*** Dumping CPU%u guest state (d%d:v%d): ***\n",
 
89
               smp_processor_id(), current->domain->domain_id,
 
90
               current->vcpu_id);
80
91
        show_execution_state(guest_cpu_user_regs());
 
92
        printk("\n");
 
93
    }
 
94
 
 
95
    cpu_clear(cpu, dump_execstate_mask);
 
96
    if ( !alt_key_handling )
 
97
        return;
 
98
 
 
99
    cpu = cycle_cpu(cpu, dump_execstate_mask);
 
100
    if ( cpu < NR_CPUS )
 
101
    {
 
102
        smp_send_state_dump(cpu);
 
103
        return;
 
104
    }
 
105
 
 
106
    console_end_sync();
 
107
    watchdog_enable();
81
108
}
82
109
 
83
110
static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
88
115
    watchdog_disable();
89
116
    console_start_sync();
90
117
 
91
 
    printk("'%c' pressed -> dumping registers\n", key);
 
118
    printk("'%c' pressed -> dumping registers\n\n", key);
 
119
 
 
120
    dump_execstate_mask = cpu_online_map;
92
121
 
93
122
    /* Get local execution state out immediately, in case we get stuck. */
94
 
    printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
95
 
    __dump_execstate(NULL);
96
 
 
97
 
    for_each_online_cpu ( cpu )
 
123
    dump_execstate(regs);
 
124
 
 
125
    /* Alt. handling: remaining CPUs are dumped asynchronously one-by-one. */
 
126
    if ( alt_key_handling )
 
127
        return;
 
128
 
 
129
    /* Normal handling: synchronously dump the remaining CPUs' states. */
 
130
    for_each_cpu_mask ( cpu, dump_execstate_mask )
98
131
    {
99
 
        if ( cpu == smp_processor_id() )
100
 
            continue;
101
 
        printk("\n*** Dumping CPU%d host state: ***\n", cpu);
102
 
        on_selected_cpus(cpumask_of(cpu), __dump_execstate, NULL, 1);
 
132
        smp_send_state_dump(cpu);
 
133
        while ( cpu_isset(cpu, dump_execstate_mask) )
 
134
            cpu_relax();
103
135
    }
104
136
 
105
 
    printk("\n");
106
 
 
107
137
    console_end_sync();
108
138
    watchdog_enable();
109
139
}
115
145
    .desc = "dump registers"
116
146
};
117
147
 
 
148
static DECLARE_TASKLET(dump_dom0_tasklet, NULL, 0);
 
149
 
 
150
static void dump_dom0_action(unsigned long arg)
 
151
{
 
152
    struct vcpu *v = (void *)arg;
 
153
 
 
154
    for ( ; ; )
 
155
    {
 
156
        vcpu_show_execution_state(v);
 
157
        if ( (v = v->next_in_list) == NULL )
 
158
            break;
 
159
        if ( softirq_pending(smp_processor_id()) )
 
160
        {
 
161
            dump_dom0_tasklet.data = (unsigned long)v;
 
162
            tasklet_schedule_on_cpu(&dump_dom0_tasklet, v->processor);
 
163
            break;
 
164
        }
 
165
    }
 
166
}
 
167
 
118
168
static void dump_dom0_registers(unsigned char key)
119
169
{
120
170
    struct vcpu *v;
125
175
    printk("'%c' pressed -> dumping Dom0's registers\n", key);
126
176
 
127
177
    for_each_vcpu ( dom0, v )
 
178
    {
 
179
        if ( alt_key_handling && softirq_pending(smp_processor_id()) )
 
180
        {
 
181
            tasklet_kill(&dump_dom0_tasklet);
 
182
            tasklet_init(&dump_dom0_tasklet, dump_dom0_action,
 
183
                         (unsigned long)v);
 
184
            tasklet_schedule_on_cpu(&dump_dom0_tasklet, v->processor);
 
185
            return;
 
186
        }
128
187
        vcpu_show_execution_state(v);
 
188
    }
129
189
}
130
190
 
131
191
static struct keyhandler dump_dom0_registers_keyhandler = {
181
241
 
182
242
    for_each_domain ( d )
183
243
    {
 
244
        unsigned int i;
184
245
        printk("General information for domain %u:\n", d->domain_id);
185
246
        cpuset_print(tmpstr, sizeof(tmpstr), d->domain_dirty_cpumask);
186
247
        printk("    refcnt=%d dying=%d nr_pages=%d xenheap_pages=%d "
194
255
               d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
195
256
               d->handle[12], d->handle[13], d->handle[14], d->handle[15],
196
257
               d->vm_assist);
 
258
        for ( i = 0 ; i < NR_DOMAIN_WATCHDOG_TIMERS; i++ )
 
259
            if ( test_bit(i, &d->watchdog_inuse_map) )
 
260
                printk("    watchdog %d expires in %d seconds\n",
 
261
                       i, (u32)((d->watchdog_timer[i].expires - NOW()) >> 30));
197
262
 
198
263
        arch_dump_domain_info(d);
199
264
 
251
316
};
252
317
 
253
318
static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
254
 
static s_time_t read_clocks_time[NR_CPUS];
255
 
static u64 read_cycles_time[NR_CPUS];
 
319
static DEFINE_PER_CPU(s_time_t, read_clocks_time);
 
320
static DEFINE_PER_CPU(u64, read_cycles_time);
256
321
 
257
322
static void read_clocks_slave(void *unused)
258
323
{
260
325
    local_irq_disable();
261
326
    while ( !cpu_isset(cpu, read_clocks_cpumask) )
262
327
        cpu_relax();
263
 
    read_clocks_time[cpu] = NOW();
264
 
    read_cycles_time[cpu] = get_cycles();
 
328
    per_cpu(read_clocks_time, cpu) = NOW();
 
329
    per_cpu(read_cycles_time, cpu) = get_cycles();
265
330
    cpu_clear(cpu, read_clocks_cpumask);
266
331
    local_irq_enable();
267
332
}
283
348
 
284
349
    local_irq_disable();
285
350
    read_clocks_cpumask = cpu_online_map;
286
 
    read_clocks_time[cpu] = NOW();
287
 
    read_cycles_time[cpu] = get_cycles();
 
351
    per_cpu(read_clocks_time, cpu) = NOW();
 
352
    per_cpu(read_cycles_time, cpu) = get_cycles();
288
353
    cpu_clear(cpu, read_clocks_cpumask);
289
354
    local_irq_enable();
290
355
 
294
359
    min_stime_cpu = max_stime_cpu = min_cycles_cpu = max_cycles_cpu = cpu;
295
360
    for_each_online_cpu ( cpu )
296
361
    {
297
 
        if ( read_clocks_time[cpu] < read_clocks_time[min_stime_cpu] )
 
362
        if ( per_cpu(read_clocks_time, cpu) <
 
363
             per_cpu(read_clocks_time, min_stime_cpu) )
298
364
            min_stime_cpu = cpu;
299
 
        if ( read_clocks_time[cpu] > read_clocks_time[max_stime_cpu] )
 
365
        if ( per_cpu(read_clocks_time, cpu) >
 
366
             per_cpu(read_clocks_time, max_stime_cpu) )
300
367
            max_stime_cpu = cpu;
301
 
        if ( read_cycles_time[cpu] < read_cycles_time[min_cycles_cpu] )
 
368
        if ( per_cpu(read_cycles_time, cpu) <
 
369
             per_cpu(read_cycles_time, min_cycles_cpu) )
302
370
            min_cycles_cpu = cpu;
303
 
        if ( read_cycles_time[cpu] > read_cycles_time[max_cycles_cpu] )
 
371
        if ( per_cpu(read_cycles_time, cpu) >
 
372
             per_cpu(read_cycles_time, max_cycles_cpu) )
304
373
            max_cycles_cpu = cpu;
305
374
    }
306
375
 
307
 
    min_stime = read_clocks_time[min_stime_cpu];
308
 
    max_stime = read_clocks_time[max_stime_cpu];
309
 
    min_cycles = read_cycles_time[min_cycles_cpu];
310
 
    max_cycles = read_cycles_time[max_cycles_cpu];
 
376
    min_stime = per_cpu(read_clocks_time, min_stime_cpu);
 
377
    max_stime = per_cpu(read_clocks_time, max_stime_cpu);
 
378
    min_cycles = per_cpu(read_cycles_time, min_cycles_cpu);
 
379
    max_cycles = per_cpu(read_cycles_time, max_cycles_cpu);
311
380
 
312
381
    spin_unlock(&lock);
313
382
 
376
445
    int k;
377
446
 
378
447
    console_start_log_everything();
 
448
 
379
449
    for ( k = 0; k < ARRAY_SIZE(key_table); k++ )
380
450
    {
 
451
        process_pending_softirqs();
381
452
        h = key_table[k];
382
453
        if ( (h == NULL) || !h->diagnostic || h->irq_callback )
383
454
            continue;
384
455
        printk("[%c: %s]\n", k, h->desc);
385
456
        (*h->u.fn)(k);
386
457
    }
 
458
 
387
459
    console_end_log_everything();
388
460
}
389
461
 
395
467
    struct keyhandler *h;
396
468
    int k;
397
469
 
 
470
    watchdog_disable();
 
471
 
398
472
    printk("'%c' pressed -> firing all diagnostic keyhandlers\n", key);
399
473
 
400
474
    /* Fire all the IRQ-context diangostic keyhandlers now */
401
 
    console_start_log_everything();
402
475
    for ( k = 0; k < ARRAY_SIZE(key_table); k++ )
403
476
    {
404
477
        h = key_table[k];
407
480
        printk("[%c: %s]\n", k, h->desc);
408
481
        (*h->u.irq_fn)(k, regs);
409
482
    }
410
 
    console_end_log_everything();
 
483
 
 
484
    watchdog_enable();
411
485
 
412
486
    /* Trigger the others from a tasklet in non-IRQ context */
413
487
    tasklet_schedule(&run_all_keyhandlers_tasklet);
434
508
    .desc = "trap to xendbg"
435
509
};
436
510
 
 
511
static void do_toggle_alt_key(unsigned char key, struct cpu_user_regs *regs)
 
512
{
 
513
    alt_key_handling = !alt_key_handling;
 
514
    printk("'%c' pressed -> using %s key handling\n", key,
 
515
           alt_key_handling ? "alternative" : "normal");
 
516
}
 
517
 
 
518
static struct keyhandler toggle_alt_keyhandler = {
 
519
    .irq_callback = 1,
 
520
    .u.irq_fn = do_toggle_alt_key,
 
521
    .desc = "toggle alternative key handling"
 
522
};
 
523
 
437
524
void __init initialize_keytable(void)
438
525
{
 
526
    if ( num_present_cpus() > 16 )
 
527
    {
 
528
        alt_key_handling = 1;
 
529
        printk(XENLOG_INFO "Defaulting to alternative key handling; "
 
530
               "send 'A' to switch to normal mode.\n");
 
531
    }
 
532
    register_keyhandler('A', &toggle_alt_keyhandler);
439
533
    register_keyhandler('d', &dump_registers_keyhandler);
440
534
    register_keyhandler('h', &show_handlers_keyhandler);
441
535
    register_keyhandler('q', &dump_domains_keyhandler);