aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/events.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-06-09 13:26:30 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-06-09 13:26:30 +0100
commitc68ffdc4fa75f9ed29ccdea16c9a910442e2fc20 (patch)
treeec2dc82b665f6046a46a4c90b5397fe51f17fac4 /extras/mini-os/events.c
parent0ba222a6fd5c72bda66eb3678c44fe3e43bbc6c0 (diff)
downloadxen-c68ffdc4fa75f9ed29ccdea16c9a910442e2fc20.tar.gz
xen-c68ffdc4fa75f9ed29ccdea16c9a910442e2fc20.tar.bz2
xen-c68ffdc4fa75f9ed29ccdea16c9a910442e2fc20.zip
minios: add proper shutdown facilities
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/events.c')
-rw-r--r--extras/mini-os/events.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/extras/mini-os/events.c b/extras/mini-os/events.c
index f47fc38822..87f54ef5eb 100644
--- a/extras/mini-os/events.c
+++ b/extras/mini-os/events.c
@@ -39,19 +39,29 @@ static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
void unbind_all_ports(void)
{
int i;
+ int cpu = 0;
+ shared_info_t *s = HYPERVISOR_shared_info;
+ vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
for (i = 0; i < NR_EVS; i++)
{
+ if (i == start_info.console.domU.evtchn ||
+ i == start_info.store_evtchn)
+ continue;
if (test_and_clear_bit(i, bound_ports))
{
struct evtchn_close close;
+ printk("port %d still bound!\n", i);
mask_evtchn(i);
close.port = i;
HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ clear_evtchn(i);
}
}
+ vcpu_info->evtchn_upcall_pending = 0;
+ vcpu_info->evtchn_pending_sel = 0;
}
-
+
/*
* Demux events to different handlers.
*/
@@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
ev_actions[port].data = data;
wmb();
ev_actions[port].handler = handler;
+ set_bit(port, bound_ports);
return port;
}
void unbind_evtchn(evtchn_port_t port )
{
+ struct evtchn_close close;
+
if (ev_actions[port].handler == default_handler)
printk("WARN: No handler for port %d when unbinding\n", port);
+ mask_evtchn(port);
+ clear_evtchn(port);
+
ev_actions[port].handler = default_handler;
wmb();
ev_actions[port].data = NULL;
+ clear_bit(port, bound_ports);
+
+ close.port = port;
+ HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
}
evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
@@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
printk("Failed to bind virtual IRQ %d\n", virq);
return -1;
}
- set_bit(op.port,bound_ports);
bind_evtchn(op.port, handler, data);
return op.port;
}
@@ -147,6 +166,15 @@ void init_events(void)
}
}
+void fini_events(void)
+{
+ /* Dealloc all events */
+ unbind_all_ports();
+#if defined(__x86_64__)
+ wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
+}
+
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
{
printk("[Port %d] - event received\n", port);
@@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
if (err)
return err;
- set_bit(op.local_port,bound_ports);
evtchn_port_t port = op.local_port;
*local_port = bind_evtchn(port, handler, data);
return err;