ia64/xen-unstable

view xen/common/keyhandler.c @ 8609:85d693e6f61a

Arch-specific per-vcpu info should be initialised to zero
when allocating a new vcpu structure, not copied from
CPU0's idle VCPU. Especially now that the idle VCPU itself
is dynamically allocated.

This should fix assertions people have been seeing in
getdomain_info_ctxt() relation to IOPL in eflags.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jan 14 21:26:40 2006 +0100 (2006-01-14)
parents 468d2a6fc0af
children
line source
1 /******************************************************************************
2 * keyhandler.c
3 */
5 #include <asm/regs.h>
6 #include <xen/keyhandler.h>
7 #include <xen/reboot.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 <asm/debugger.h>
17 #define KEY_MAX 256
18 #define STR_MAX 64
20 static struct {
21 union {
22 keyhandler_t *handler;
23 irq_keyhandler_t *irq_handler;
24 } u;
25 unsigned int flags;
26 char desc[STR_MAX];
27 } key_table[KEY_MAX];
29 #define KEYHANDLER_IRQ_CALLBACK 0x1
31 static unsigned char keypress_key;
33 static void keypress_softirq(void)
34 {
35 keyhandler_t *h;
36 unsigned char key = keypress_key;
37 if ( (h = key_table[key].u.handler) != NULL )
38 (*h)(key);
39 }
41 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
42 {
43 irq_keyhandler_t *h;
45 if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
46 {
47 if ( (h = key_table[key].u.irq_handler) != NULL )
48 (*h)(key, regs);
49 }
50 else
51 {
52 keypress_key = key;
53 raise_softirq(KEYPRESS_SOFTIRQ);
54 }
55 }
57 void register_keyhandler(
58 unsigned char key, keyhandler_t *handler, char *desc)
59 {
60 ASSERT(key_table[key].u.handler == NULL);
61 key_table[key].u.handler = handler;
62 key_table[key].flags = 0;
63 strncpy(key_table[key].desc, desc, STR_MAX);
64 key_table[key].desc[STR_MAX-1] = '\0';
65 }
67 void register_irq_keyhandler(
68 unsigned char key, irq_keyhandler_t *handler, char *desc)
69 {
70 ASSERT(key_table[key].u.irq_handler == NULL);
71 key_table[key].u.irq_handler = handler;
72 key_table[key].flags = KEYHANDLER_IRQ_CALLBACK;
73 strncpy(key_table[key].desc, desc, STR_MAX);
74 key_table[key].desc[STR_MAX-1] = '\0';
75 }
77 static void show_handlers(unsigned char key)
78 {
79 int i;
80 printk("'%c' pressed -> showing installed handlers\n", key);
81 for ( i = 0; i < KEY_MAX; i++ )
82 if ( key_table[i].u.handler != NULL )
83 printk(" key '%c' (ascii '%02x') => %s\n",
84 (i<33 || i>126)?(' '):(i),i,
85 key_table[i].desc);
86 }
88 static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
89 {
90 printk("'%c' pressed -> dumping registers\n", key);
91 show_registers(regs);
92 }
94 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
95 {
96 printk("'%c' pressed -> rebooting machine\n", key);
97 machine_restart(NULL);
98 }
100 static void cpuset_print(char *set, int size, cpumask_t mask)
101 {
102 *set++ = '{';
103 set += cpulist_scnprintf(set, size-2, mask);
104 *set++ = '}';
105 *set++ = '\0';
106 }
108 static void dump_domains(unsigned char key)
109 {
110 struct domain *d;
111 struct vcpu *v;
112 s_time_t now = NOW();
113 char cpuset[100];
115 printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
116 (u32)(now>>32), (u32)now);
118 read_lock(&domlist_lock);
120 for_each_domain ( d )
121 {
122 printk("General information for domain %u:\n", d->domain_id);
123 cpuset_print(cpuset, sizeof(cpuset), d->domain_dirty_cpumask);
124 printk(" flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
125 "dirty_cpus=%s\n",
126 d->domain_flags, atomic_read(&d->refcnt),
127 d->tot_pages, d->xenheap_pages, cpuset);
128 printk(" handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
129 "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
130 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
131 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
132 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
133 d->handle[12], d->handle[13], d->handle[14], d->handle[15]);
135 rangeset_domain_printk(d);
137 dump_pageframe_info(d);
139 printk("VCPU information and callbacks for domain %u:\n",
140 d->domain_id);
141 for_each_vcpu ( d, v ) {
142 printk(" VCPU%d: CPU%d [has=%c] flags=%lx "
143 "upcall_pend = %02x, upcall_mask = %02x ",
144 v->vcpu_id, v->processor,
145 test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
146 v->vcpu_flags,
147 v->vcpu_info->evtchn_upcall_pending,
148 v->vcpu_info->evtchn_upcall_mask);
149 cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask);
150 printk("dirty_cpus=%s ", cpuset);
151 cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity);
152 printk("cpu_affinity=%s\n", cpuset);
153 printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
154 VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
155 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
156 &d->shared_info->evtchn_pending[0]),
157 test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
158 &d->shared_info->evtchn_mask[0]),
159 test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG,
160 &v->vcpu_info->evtchn_pending_sel));
161 send_guest_virq(v, VIRQ_DEBUG);
162 }
163 }
165 read_unlock(&domlist_lock);
166 }
168 extern void dump_runq(unsigned char key);
169 extern void print_sched_histo(unsigned char key);
170 extern void reset_sched_histo(unsigned char key);
171 #ifndef NDEBUG
172 extern void audit_domains_key(unsigned char key);
173 #endif
175 #ifdef PERF_COUNTERS
176 extern void perfc_printall(unsigned char key);
177 extern void perfc_reset(unsigned char key);
178 #endif
180 void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
181 {
182 (void)debugger_trap_fatal(0xf001, regs);
183 nop(); /* Prevent the compiler doing tail call
184 optimisation, as that confuses xendbg a
185 bit. */
186 }
188 #ifndef NDEBUG
189 void debugtrace_key(unsigned char key)
190 {
191 debugtrace_send_to_console = !debugtrace_send_to_console;
192 debugtrace_dump();
193 printk("debugtrace_printk now writing to %s.\n",
194 debugtrace_send_to_console ? "console" : "buffer");
195 }
196 #endif
198 void initialize_keytable(void)
199 {
200 open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
202 register_irq_keyhandler(
203 'd', dump_registers, "dump registers");
204 register_keyhandler(
205 'h', show_handlers, "show this message");
206 register_keyhandler(
207 'l', print_sched_histo, "print sched latency histogram");
208 register_keyhandler(
209 'L', reset_sched_histo, "reset sched latency histogram");
210 register_keyhandler(
211 'q', dump_domains, "dump domain (and guest debug) info");
212 register_keyhandler(
213 'r', dump_runq, "dump run queues");
214 register_irq_keyhandler(
215 'R', halt_machine, "reboot machine");
217 #ifndef NDEBUG
218 register_keyhandler(
219 'o', audit_domains_key, "audit domains >0 EXPERIMENTAL");
220 register_keyhandler(
221 'T', debugtrace_key, "toggle debugtrace to console/buffer");
222 #endif
224 #ifdef PERF_COUNTERS
225 register_keyhandler(
226 'p', perfc_printall, "print performance counters");
227 register_keyhandler(
228 'P', perfc_reset, "reset performance counters");
229 #endif
231 register_irq_keyhandler('%', do_debug_key, "Trap to xendbg");
232 }
234 /*
235 * Local variables:
236 * mode: C
237 * c-set-style: "BSD"
238 * c-basic-offset: 4
239 * tab-width: 4
240 * indent-tabs-mode: nil
241 * End:
242 */