From b9d1950675c67f10870debe164a226eef64f65d5 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 18 Mar 2008 11:29:18 +0000 Subject: 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 --- extras/mini-os/netfront.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'extras/mini-os/netfront.c') 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); -- cgit v1.2.3