ia64/xen-unstable

view xen/common/keyhandler.c @ 19835:edfdeb150f27

Fix buildsystem to detect udev > version 124

udev removed the udevinfo symlink from versions higher than 123 and
xen's build-system could not detect if udev is in place and has the
required version.

Signed-off-by: Marc-A. Dahlhaus <mad@wol.de>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 25 13:02:37 2009 +0100 (2009-06-25)
parents 2f9e1348aa98
children
line source
1 /******************************************************************************
2 * keyhandler.c
3 */
5 #include <asm/regs.h>
6 #include <xen/keyhandler.h>
7 #include <xen/shutdown.h>
8 #include <xen/event.h>
9 #include <xen/console.h>
10 #include <xen/serial.h>
11 #include <xen/sched.h>
12 #include <xen/softirq.h>
13 #include <xen/domain.h>
14 #include <xen/rangeset.h>
15 #include <xen/compat.h>
16 #include <asm/debugger.h>
17 #include <asm/div64.h>
19 #define KEY_MAX 256
20 #define STR_MAX 64
22 static struct {
23 union {
24 keyhandler_t *handler;
25 irq_keyhandler_t *irq_handler;
26 } u;
27 unsigned int flags;
28 char desc[STR_MAX];
29 } key_table[KEY_MAX];
31 #define KEYHANDLER_IRQ_CALLBACK 0x1
33 static unsigned char keypress_key;
35 static void keypress_action(unsigned long unused)
36 {
37 keyhandler_t *h;
38 unsigned char key = keypress_key;
39 console_start_log_everything();
40 if ( (h = key_table[key].u.handler) != NULL )
41 (*h)(key);
42 console_end_log_everything();
43 }
45 static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0);
47 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
48 {
49 irq_keyhandler_t *h;
51 if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
52 {
53 console_start_log_everything();
54 if ( (h = key_table[key].u.irq_handler) != NULL )
55 (*h)(key, regs);
56 console_end_log_everything();
57 }
58 else
59 {
60 keypress_key = key;
61 tasklet_schedule(&keypress_tasklet);
62 }
63 }
65 void register_keyhandler(
66 unsigned char key, keyhandler_t *handler, char *desc)
67 {
68 ASSERT(key_table[key].u.handler == NULL);
69 key_table[key].u.handler = handler;
70 key_table[key].flags = 0;
71 safe_strcpy(key_table[key].desc, desc);
72 }
74 void register_irq_keyhandler(
75 unsigned char key, irq_keyhandler_t *handler, char *desc)
76 {
77 ASSERT(key_table[key].u.irq_handler == NULL);
78 key_table[key].u.irq_handler = handler;
79 key_table[key].flags = KEYHANDLER_IRQ_CALLBACK;
80 safe_strcpy(key_table[key].desc, desc);
81 }
83 static void show_handlers(unsigned char key)
84 {
85 int i;
86 printk("'%c' pressed -> showing installed handlers\n", key);
87 for ( i = 0; i < KEY_MAX; i++ )
88 if ( key_table[i].u.handler != NULL )
89 printk(" key '%c' (ascii '%02x') => %s\n",
90 (i<33 || i>126)?(' '):(i),i,
91 key_table[i].desc);
92 }
94 static void __dump_execstate(void *unused)
95 {
96 dump_execution_state();
97 printk("*** Dumping CPU%d guest state: ***\n", smp_processor_id());
98 if ( is_idle_vcpu(current) )
99 printk("No guest context (CPU is idle).\n");
100 else
101 show_execution_state(guest_cpu_user_regs());
102 }
104 static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
105 {
106 unsigned int cpu;
108 /* We want to get everything out that we possibly can. */
109 console_start_sync();
111 printk("'%c' pressed -> dumping registers\n", key);
113 /* Get local execution state out immediately, in case we get stuck. */
114 printk("\n*** Dumping CPU%d host state: ***\n", smp_processor_id());
115 __dump_execstate(NULL);
117 for_each_online_cpu ( cpu )
118 {
119 if ( cpu == smp_processor_id() )
120 continue;
121 printk("\n*** Dumping CPU%d host state: ***\n", cpu);
122 on_selected_cpus(cpumask_of(cpu), __dump_execstate, NULL, 1);
123 }
125 printk("\n");
127 console_end_sync();
128 }
130 static void dump_dom0_registers(unsigned char key)
131 {
132 struct vcpu *v;
134 if ( dom0 == NULL )
135 return;
137 printk("'%c' pressed -> dumping Dom0's registers\n", key);
139 for_each_vcpu ( dom0, v )
140 vcpu_show_execution_state(v);
141 }
143 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
144 {
145 printk("'%c' pressed -> rebooting machine\n", key);
146 machine_restart(0);
147 }
149 static void cpuset_print(char *set, int size, cpumask_t mask)
150 {
151 *set++ = '{';
152 set += cpulist_scnprintf(set, size-2, mask);
153 *set++ = '}';
154 *set++ = '\0';
155 }
157 static void periodic_timer_print(char *str, int size, uint64_t period)
158 {
159 if ( period == 0 )
160 {
161 strlcpy(str, "No periodic timer", size);
162 return;
163 }
165 snprintf(str, size,
166 "%u Hz periodic timer (period %u ms)",
167 1000000000/(int)period, (int)period/1000000);
168 }
170 static void dump_domains(unsigned char key)
171 {
172 struct domain *d;
173 struct vcpu *v;
174 s_time_t now = NOW();
175 char tmpstr[100];
177 printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
178 (u32)(now>>32), (u32)now);
180 rcu_read_lock(&domlist_read_lock);
182 for_each_domain ( d )
183 {
184 printk("General information for domain %u:\n", d->domain_id);
185 cpuset_print(tmpstr, sizeof(tmpstr), d->domain_dirty_cpumask);
186 printk(" refcnt=%d dying=%d nr_pages=%d xenheap_pages=%d "
187 "dirty_cpus=%s max_pages=%u\n",
188 atomic_read(&d->refcnt), d->is_dying,
189 d->tot_pages, d->xenheap_pages, tmpstr, d->max_pages);
190 printk(" handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
191 "%02x%02x-%02x%02x%02x%02x%02x%02x vm_assist=%08lx\n",
192 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
193 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
194 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
195 d->handle[12], d->handle[13], d->handle[14], d->handle[15],
196 d->vm_assist);
198 arch_dump_domain_info(d);
200 rangeset_domain_printk(d);
202 dump_pageframe_info(d);
204 printk("VCPU information and callbacks for domain %u:\n",
205 d->domain_id);
206 for_each_vcpu ( d, v ) {
207 printk(" VCPU%d: CPU%d [has=%c] flags=%lx poll=%d "
208 "upcall_pend = %02x, upcall_mask = %02x ",
209 v->vcpu_id, v->processor,
210 v->is_running ? 'T':'F',
211 v->pause_flags, v->poll_evtchn,
212 v->vcpu_info ? vcpu_info(v, evtchn_upcall_pending) : 0,
213 v->vcpu_info ? vcpu_info(v, evtchn_upcall_mask) : 1);
214 cpuset_print(tmpstr, sizeof(tmpstr), v->vcpu_dirty_cpumask);
215 printk("dirty_cpus=%s ", tmpstr);
216 cpuset_print(tmpstr, sizeof(tmpstr), v->cpu_affinity);
217 printk("cpu_affinity=%s\n", tmpstr);
218 arch_dump_vcpu_info(v);
219 periodic_timer_print(tmpstr, sizeof(tmpstr), v->periodic_period);
220 printk(" %s\n", tmpstr);
221 if ( !v->vcpu_info )
222 continue;
223 printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
224 VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
225 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
226 &shared_info(d, evtchn_pending)),
227 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
228 &shared_info(d, evtchn_mask)),
229 test_bit(v->virq_to_evtchn[VIRQ_DEBUG] /
230 BITS_PER_EVTCHN_WORD(d),
231 &vcpu_info(v, evtchn_pending_sel)));
232 send_guest_vcpu_virq(v, VIRQ_DEBUG);
233 }
234 }
236 rcu_read_unlock(&domlist_read_lock);
237 }
239 static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
240 static s_time_t read_clocks_time[NR_CPUS];
241 static u64 read_cycles_time[NR_CPUS];
243 static void read_clocks_slave(void *unused)
244 {
245 unsigned int cpu = smp_processor_id();
246 local_irq_disable();
247 while ( !cpu_isset(cpu, read_clocks_cpumask) )
248 cpu_relax();
249 read_clocks_time[cpu] = NOW();
250 read_cycles_time[cpu] = get_cycles();
251 cpu_clear(cpu, read_clocks_cpumask);
252 local_irq_enable();
253 }
255 static void read_clocks(unsigned char key)
256 {
257 unsigned int cpu = smp_processor_id(), min_stime_cpu, max_stime_cpu;
258 unsigned int min_cycles_cpu, max_cycles_cpu;
259 u64 min_stime, max_stime, dif_stime;
260 u64 min_cycles, max_cycles, dif_cycles;
261 static u64 sumdif_stime = 0, maxdif_stime = 0;
262 static u64 sumdif_cycles = 0, maxdif_cycles = 0;
263 static u32 count = 0;
264 static DEFINE_SPINLOCK(lock);
266 spin_lock(&lock);
268 smp_call_function(read_clocks_slave, NULL, 0);
270 local_irq_disable();
271 read_clocks_cpumask = cpu_online_map;
272 read_clocks_time[cpu] = NOW();
273 read_cycles_time[cpu] = get_cycles();
274 cpu_clear(cpu, read_clocks_cpumask);
275 local_irq_enable();
277 while ( !cpus_empty(read_clocks_cpumask) )
278 cpu_relax();
280 min_stime_cpu = max_stime_cpu = min_cycles_cpu = max_cycles_cpu = cpu;
281 for_each_online_cpu ( cpu )
282 {
283 if ( read_clocks_time[cpu] < read_clocks_time[min_stime_cpu] )
284 min_stime_cpu = cpu;
285 if ( read_clocks_time[cpu] > read_clocks_time[max_stime_cpu] )
286 max_stime_cpu = cpu;
287 if ( read_cycles_time[cpu] < read_cycles_time[min_cycles_cpu] )
288 min_cycles_cpu = cpu;
289 if ( read_cycles_time[cpu] > read_cycles_time[max_cycles_cpu] )
290 max_cycles_cpu = cpu;
291 }
293 min_stime = read_clocks_time[min_stime_cpu];
294 max_stime = read_clocks_time[max_stime_cpu];
295 min_cycles = read_cycles_time[min_cycles_cpu];
296 max_cycles = read_cycles_time[max_cycles_cpu];
298 spin_unlock(&lock);
300 dif_stime = max_stime - min_stime;
301 if ( dif_stime > maxdif_stime )
302 maxdif_stime = dif_stime;
303 sumdif_stime += dif_stime;
304 dif_cycles = max_cycles - min_cycles;
305 if ( dif_cycles > maxdif_cycles )
306 maxdif_cycles = dif_cycles;
307 sumdif_cycles += dif_cycles;
308 count++;
309 printk("Synced stime skew: max=%"PRIu64"ns avg=%"PRIu64"ns "
310 "samples=%"PRIu32" current=%"PRIu64"ns\n",
311 maxdif_stime, sumdif_stime/count, count, dif_stime);
312 printk("Synced cycles skew: max=%"PRIu64" avg=%"PRIu64" "
313 "samples=%"PRIu32" current=%"PRIu64"\n",
314 maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
315 }
317 extern void dump_runq(unsigned char key);
319 #ifdef PERF_COUNTERS
320 extern void perfc_printall(unsigned char key);
321 extern void perfc_reset(unsigned char key);
322 #endif
324 static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
325 {
326 printk("'%c' pressed -> trapping into debugger\n", key);
327 (void)debugger_trap_fatal(0xf001, regs);
328 nop(); /* Prevent the compiler doing tail call
329 optimisation, as that confuses xendbg a
330 bit. */
331 }
333 void __init initialize_keytable(void)
334 {
335 register_irq_keyhandler(
336 'd', dump_registers, "dump registers");
337 register_keyhandler(
338 'h', show_handlers, "show this message");
339 register_keyhandler(
340 'q', dump_domains, "dump domain (and guest debug) info");
341 register_keyhandler(
342 'r', dump_runq, "dump run queues");
343 register_irq_keyhandler(
344 'R', halt_machine, "reboot machine");
346 register_keyhandler(
347 't', read_clocks, "display multi-cpu clock info");
349 #ifdef PERF_COUNTERS
350 register_keyhandler(
351 'p', perfc_printall, "print performance counters");
352 register_keyhandler(
353 'P', perfc_reset, "reset performance counters");
354 #endif
356 register_keyhandler(
357 '0', dump_dom0_registers, "dump Dom0 registers");
359 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
360 }
362 /*
363 * Local variables:
364 * mode: C
365 * c-set-style: "BSD"
366 * c-basic-offset: 4
367 * tab-width: 4
368 * indent-tabs-mode: nil
369 * End:
370 */