diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-03-18 11:29:18 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-03-18 11:29:18 +0000 |
commit | b9d1950675c67f10870debe164a226eef64f65d5 (patch) | |
tree | acd93ea007ed7289d7bacc728997d698e050c276 /extras | |
parent | 62341d01ee88ecc87d6995000383446e3bf43ec7 (diff) | |
download | xen-b9d1950675c67f10870debe164a226eef64f65d5.tar.gz xen-b9d1950675c67f10870debe164a226eef64f65d5.tar.bz2 xen-b9d1950675c67f10870debe164a226eef64f65d5.zip |
minios: Fix lost events
evtchn_bind_interdomain used to clear any already pending event before
binding a handler, because else the handler may be called before it is
ready. That however leads to missed events, which I had to workaround
for the HVM case.
This changes the semantics of bind_evtchn, and thus of all the
event channel binding functions (bind_virq, evtchn_alloc_unbound,
evtchn_bind_interdomain) into not unmasking the event itself, hence
letting the caller initialize properly before unmasking the port (e.g.
record the port number in an appropriate place).
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras')
-rw-r--r-- | extras/mini-os/arch/ia64/time.c | 9 | ||||
-rw-r--r-- | extras/mini-os/arch/x86/time.c | 4 | ||||
-rw-r--r-- | extras/mini-os/blkfront.c | 14 | ||||
-rw-r--r-- | extras/mini-os/console/xencons_ring.c | 1 | ||||
-rw-r--r-- | extras/mini-os/events.c | 6 | ||||
-rw-r--r-- | extras/mini-os/fbfront.c | 28 | ||||
-rw-r--r-- | extras/mini-os/fs-front.c | 1 | ||||
-rw-r--r-- | extras/mini-os/netfront.c | 20 | ||||
-rw-r--r-- | extras/mini-os/xenbus/xenbus.c | 1 |
9 files changed, 35 insertions, 49 deletions
diff --git a/extras/mini-os/arch/ia64/time.c b/extras/mini-os/arch/ia64/time.c index 9fb3157fb6..bbaa6b1864 100644 --- a/extras/mini-os/arch/ia64/time.c +++ b/extras/mini-os/arch/ia64/time.c @@ -246,7 +246,7 @@ init_time(void) { uint64_t new; efi_time_t tm; - int err = 0; + evtchn_port_t port = 0; printk("Initialising time\n"); calculate_frequencies(); @@ -267,11 +267,12 @@ init_time(void) } else printk("efi_get_time() failed\n"); - err = bind_virq(VIRQ_ITC, timer_interrupt, NULL); - if (err == -1) { - printk("XEN timer request chn bind failed %i\n", err); + port = bind_virq(VIRQ_ITC, timer_interrupt, NULL); + if (port == -1) { + printk("XEN timer request chn bind failed %i\n", port); return; } + unmask_evtchn(port); itc_alt = ia64_get_itc(); itc_at_boot = itc_alt; new = ia64_get_itc() + itm_val; diff --git a/extras/mini-os/arch/x86/time.c b/extras/mini-os/arch/x86/time.c index c8313705ae..a396dc279f 100644 --- a/extras/mini-os/arch/x86/time.c +++ b/extras/mini-os/arch/x86/time.c @@ -222,6 +222,8 @@ static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign) void init_time(void) { + evtchn_port_t port; printk("Initialising timer interface\n"); - bind_virq(VIRQ_TIMER, &timer_handler, NULL); + port = bind_virq(VIRQ_TIMER, &timer_handler, NULL); + unmask_evtchn(port); } diff --git a/extras/mini-os/blkfront.c b/extras/mini-os/blkfront.c index 3210396b7b..f5cf19cbe5 100644 --- a/extras/mini-os/blkfront.c +++ b/extras/mini-os/blkfront.c @@ -43,7 +43,7 @@ struct blkfront_dev { struct blkif_front_ring ring; grant_ref_t ring_ref; - evtchn_port_t evtchn, local_port; + evtchn_port_t evtchn; blkif_vdev_t handle; char *nodename; @@ -92,14 +92,9 @@ struct blkfront_dev *init_blkfront(char *nodename, uint64_t *sectors, unsigned * dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); - evtchn_alloc_unbound_t op; - op.dom = DOMID_SELF; snprintf(path, sizeof(path), "%s/backend-id", nodename); - dev->dom = op.remote_dom = xenbus_read_integer(path); - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); - clear_evtchn(op.port); /* Without, handler gets invoked now! */ - dev->local_port = bind_evtchn(op.port, blkfront_handler, dev); - dev->evtchn=op.port; + dev->dom = xenbus_read_integer(path); + evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn); s = (struct blkif_sring*) alloc_page(); memset(s,0,PAGE_SIZE); @@ -194,6 +189,7 @@ done: snprintf(path, sizeof(path), "%s/feature-flush-cache", dev->backend); dev->flush = xenbus_read_integer(path); } + unmask_evtchn(dev->evtchn); printk("%u sectors of %u bytes\n", dev->sectors, dev->sector_size); printk("**************************\n"); @@ -219,7 +215,7 @@ void shutdown_blkfront(struct blkfront_dev *dev) err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path,"6"); - unbind_evtchn(dev->local_port); + unbind_evtchn(dev->evtchn); free(nodename); free(dev->backend); diff --git a/extras/mini-os/console/xencons_ring.c b/extras/mini-os/console/xencons_ring.c index f0cf9203ae..583e4bcb92 100644 --- a/extras/mini-os/console/xencons_ring.c +++ b/extras/mini-os/console/xencons_ring.c @@ -86,6 +86,7 @@ int xencons_ring_init(void) printk("XEN console request chn bind failed %i\n", err); return err; } + unmask_evtchn(start_info.console.domU.evtchn); /* In case we have in-flight data after save/restore... */ notify_daemon(); diff --git a/extras/mini-os/events.c b/extras/mini-os/events.c index 9174f166ed..7c88807889 100644 --- a/extras/mini-os/events.c +++ b/extras/mini-os/events.c @@ -87,9 +87,6 @@ evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler, wmb(); ev_actions[port].handler = handler; - /* Finally unmask the port */ - unmask_evtchn(port); - return port; } @@ -191,8 +188,7 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, if (err) return err; set_bit(op.local_port,bound_ports); - evtchn_port_t port = op.local_port; - clear_evtchn(port); /* Without, handler gets invoked now! */ + evtchn_port_t port = op.local_port; *local_port = bind_evtchn(port, handler, data); return err; } diff --git a/extras/mini-os/fbfront.c b/extras/mini-os/fbfront.c index b7caf78f6a..d16576f728 100644 --- a/extras/mini-os/fbfront.c +++ b/extras/mini-os/fbfront.c @@ -26,7 +26,7 @@ struct kbdfront_dev { domid_t dom; struct xenkbd_page *page; - evtchn_port_t evtchn, local_port; + evtchn_port_t evtchn; char *nodename; char *backend; @@ -68,14 +68,9 @@ struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer) dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); - evtchn_alloc_unbound_t op; - op.dom = DOMID_SELF; snprintf(path, sizeof(path), "%s/backend-id", nodename); - dev->dom = op.remote_dom = xenbus_read_integer(path); - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); - clear_evtchn(op.port); /* Without, handler gets invoked now! */ - dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev); - dev->evtchn=op.port; + dev->dom = xenbus_read_integer(path); + evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn); dev->page = s = (struct xenkbd_page*) alloc_page(); memset(s,0,PAGE_SIZE); @@ -151,6 +146,7 @@ done: err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ } + unmask_evtchn(dev->evtchn); printk("************************** KBDFRONT\n"); @@ -208,7 +204,7 @@ void shutdown_kbdfront(struct kbdfront_dev *dev) err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path,"6"); - unbind_evtchn(dev->local_port); + unbind_evtchn(dev->evtchn); free_pages(dev->page,0); free(nodename); @@ -241,7 +237,7 @@ struct fbfront_dev { domid_t dom; struct xenfb_page *page; - evtchn_port_t evtchn, local_port; + evtchn_port_t evtchn; char *nodename; char *backend; @@ -281,14 +277,9 @@ struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int heig dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); - evtchn_alloc_unbound_t op; - op.dom = DOMID_SELF; snprintf(path, sizeof(path), "%s/backend-id", nodename); - dev->dom = op.remote_dom = xenbus_read_integer(path); - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); - clear_evtchn(op.port); /* Without, handler gets invoked now! */ - dev->local_port = bind_evtchn(op.port, fbfront_handler, dev); - dev->evtchn=op.port; + dev->dom = xenbus_read_integer(path); + evtchn_alloc_unbound(dev->dom, fbfront_handler, dev, &dev->evtchn); dev->page = s = (struct xenfb_page*) alloc_page(); memset(s,0,PAGE_SIZE); @@ -397,6 +388,7 @@ done: err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ } + unmask_evtchn(dev->evtchn); printk("************************** FBFRONT\n"); @@ -462,7 +454,7 @@ void shutdown_fbfront(struct fbfront_dev *dev) err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path,"6"); - unbind_evtchn(dev->local_port); + unbind_evtchn(dev->evtchn); free_pages(dev->page,0); free(nodename); diff --git a/extras/mini-os/fs-front.c b/extras/mini-os/fs-front.c index dd8623d71a..131f134763 100644 --- a/extras/mini-os/fs-front.c +++ b/extras/mini-os/fs-front.c @@ -943,6 +943,7 @@ static int init_fs_import(struct fs_import *import) //ANY_CPU, import, &import->local_port)); + unmask_evtchn(import->local_port); self_id = get_self_id(); diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c index 095f55ca15..9b709d9826 100644 --- a/extras/mini-os/netfront.c +++ b/extras/mini-os/netfront.c @@ -48,7 +48,7 @@ struct netfront_dev { struct netif_rx_front_ring rx; grant_ref_t tx_ring_ref; grant_ref_t rx_ring_ref; - evtchn_port_t evtchn, local_port; + evtchn_port_t evtchn; char *nodename; char *backend; @@ -301,19 +301,14 @@ struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned dev->rx_buffers[i].page = (char*)alloc_page(); } - evtchn_alloc_unbound_t op; - op.dom = DOMID_SELF; snprintf(path, sizeof(path), "%s/backend-id", nodename); - dev->dom = op.remote_dom = xenbus_read_integer(path); - HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); - clear_evtchn(op.port); /* Without, handler gets invoked now! */ + dev->dom = xenbus_read_integer(path); #ifdef HAVE_LIBC if (thenetif_rx == NETIF_SELECT_RX) - dev->local_port = bind_evtchn(op.port, netfront_select_handler, dev); + evtchn_alloc_unbound(dev->dom, netfront_select_handler, dev, &dev->evtchn); else #endif - dev->local_port = bind_evtchn(op.port, netfront_handler, dev); - dev->evtchn=op.port; + evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn); txs = (struct netif_tx_sring*) alloc_page(); rxs = (struct netif_rx_sring *) alloc_page(); @@ -388,9 +383,9 @@ done: msg = xenbus_read(XBT_NIL, path, &mac); if ((dev->backend == NULL) || (mac == NULL)) { - struct evtchn_close op = { dev->local_port }; + struct evtchn_close op = { dev->evtchn }; printk("%s: backend/mac failed\n", __func__); - unbind_evtchn(dev->local_port); + unbind_evtchn(dev->evtchn); HYPERVISOR_event_channel_op(EVTCHNOP_close, &op); return NULL; } @@ -412,6 +407,7 @@ done: printk("**************************\n"); init_rx_buffers(dev); + unmask_evtchn(dev->evtchn); /* Special conversion specifier 'hh' needed for __ia64__. Without this mini-os panics with 'Unaligned reference'. */ @@ -460,7 +456,7 @@ void shutdown_netfront(struct netfront_dev *dev) err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path,"6"); - unbind_evtchn(dev->local_port); + unbind_evtchn(dev->evtchn); free(nodename); free(dev->backend); diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c index 1a96ce2f24..147cef1331 100644 --- a/extras/mini-os/xenbus/xenbus.c +++ b/extras/mini-os/xenbus/xenbus.c @@ -257,6 +257,7 @@ void init_xenbus(void) err = bind_evtchn(start_info.store_evtchn, xenbus_evtchn_handler, NULL); + unmask_evtchn(start_info.store_evtchn); DEBUG("xenbus on irq %d\n", err); } |