From 0f742e92ea9ea37b9883310e3d9f0ac04704813c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Oct 2005 19:14:13 +0100 Subject: [PATCH 1/6] EVTCHNOP_alloc_unbound can allocate a port in an arbitrary domain (only if the caller is sufficiently privileged). Signed-off-by: Keir Fraser --- .../drivers/xen/blkfront/blkfront.c | 8 ++++++-- .../drivers/xen/netfront/netfront.c | 8 ++++++-- .../drivers/xen/tpmfront/tpmfront.c | 9 ++++++--- tools/libxc/xc_evtchn.c | 2 ++ tools/libxc/xenctrl.h | 4 +++- tools/python/xen/lowlevel/xc/xc.c | 10 +++++----- xen/common/event_channel.c | 18 +++++++++++++++--- xen/include/public/event_channel.h | 10 ++++++---- 8 files changed, 49 insertions(+), 20 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 78222c92f5..00caac5d95 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -485,7 +485,7 @@ static void watch_for_status(struct xenbus_watch *watch, const char *node) static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info) { blkif_sring_t *sring; - evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; + evtchn_op_t op; int err; info->ring_ref = GRANT_INVALID_REF; @@ -508,7 +508,9 @@ static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info) } info->ring_ref = err; - op.u.alloc_unbound.dom = info->backend_id; + op.cmd = EVTCHNOP_alloc_unbound; + op.u.alloc_unbound.dom = DOMID_SELF; + op.u.alloc_unbound.remote_dom = info->backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { gnttab_end_foreign_access(info->ring_ref, 0); @@ -518,7 +520,9 @@ static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info) xenbus_dev_error(dev, err, "allocating event channel"); return err; } + blkif_connect(info, op.u.alloc_unbound.port); + return 0; } diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 5a5dac453f..7bd156625b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -972,7 +972,7 @@ static void watch_for_status(struct xenbus_watch *watch, const char *node) static int setup_device(struct xenbus_device *dev, struct netfront_info *info) { - evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; + evtchn_op_t op; int err; info->tx_ring_ref = GRANT_INVALID_REF; @@ -1010,13 +1010,17 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) } info->rx_ring_ref = err; - op.u.alloc_unbound.dom = info->backend_id; + op.cmd = EVTCHNOP_alloc_unbound; + op.u.alloc_unbound.dom = DOMID_SELF; + op.u.alloc_unbound.remote_dom = info->backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { xenbus_dev_error(dev, err, "allocating event channel"); goto out; } + connect_device(info, op.u.alloc_unbound.port); + return 0; out: diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c index 8fc6a4b501..55c44f95aa 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c @@ -244,8 +244,7 @@ static int setup_tpmring(struct xenbus_device *dev, { tpmif_tx_interface_t *sring; struct tpm_private *tp = &my_private; - - evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; + evtchn_op_t op; int err; sring = (void *)__get_free_page(GFP_KERNEL); @@ -269,7 +268,9 @@ static int setup_tpmring(struct xenbus_device *dev, } info->ring_ref = err; - op.u.alloc_unbound.dom = backend_id; + op.cmd = EVTCHNOP_alloc_unbound; + op.u.alloc_unbound.dom = DOMID_SELF; + op.u.alloc_unbound.remote_dom = backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { gnttab_end_foreign_access(info->ring_ref, 0); @@ -278,7 +279,9 @@ static int setup_tpmring(struct xenbus_device *dev, xenbus_dev_error(dev, err, "allocating event channel"); return err; } + tpmif_connect(op.u.alloc_unbound.port, backend_id); + return 0; } diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c index f7698d3541..3bdacf36a3 100644 --- a/tools/libxc/xc_evtchn.c +++ b/tools/libxc/xc_evtchn.c @@ -33,6 +33,7 @@ static int do_evtchn_op(int xc_handle, evtchn_op_t *op) int xc_evtchn_alloc_unbound(int xc_handle, + u32 remote_dom, u32 dom, int *port) { @@ -40,6 +41,7 @@ int xc_evtchn_alloc_unbound(int xc_handle, int rc; op.cmd = EVTCHNOP_alloc_unbound; + op.u.alloc_unbound.remote_dom = (domid_t)remote_dom; op.u.alloc_unbound.dom = (domid_t)dom; op.u.alloc_unbound.port = (port != NULL) ? *port : 0; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 2fe9bee750..3e74c62fa0 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -306,13 +306,15 @@ typedef evtchn_status_t xc_evtchn_status_t; * well-known port within a domain to receive events on. * * @parm xc_handle a handle to an open hypervisor interface - * @parm dom the ID of the domain. This maybe DOMID_SELF + * @parm remote_dom the ID of the domain who will later bind + * @parm dom the ID of the local domain (the 'allocatee') * @parm port a pointer to a port. This is an in/out parameter. If *port is * 0, then a new port will be assigned, if port is > 0 then that * port is allocated if the port is unallocated. * @return 0 on success, -1 on failure */ int xc_evtchn_alloc_unbound(int xc_handle, + u32 remote_dom, u32 dom, int *port); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index d096b7bb96..7ff5b40ca9 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -432,16 +432,16 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + u32 dom = DOMID_SELF, remote_dom; int port = 0; - static char *kwd_list[] = { "dom", "port", NULL }; + static char *kwd_list[] = { "remote_dom", "dom", "port", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, - &dom, &port) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list, + &remote_dom, &dom, &port) ) return NULL; - if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 ) + if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 ) return PyErr_SetFromErrno(xc_error); return PyInt_FromLong(port); diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 8c413097ba..eea5ee1633 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -63,10 +63,19 @@ static int get_free_port(struct domain *d) static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) { struct evtchn *chn; - struct domain *d = current->domain; + struct domain *d; int port = alloc->port; + domid_t dom = alloc->dom; long rc = 0; + if ( dom == DOMID_SELF ) + dom = current->domain->domain_id; + else if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( (d = find_domain_by_id(dom)) == NULL ) + return -ESRCH; + spin_lock(&d->evtchn_lock); /* Obtain, or ensure that we already have, a valid . */ @@ -84,11 +93,11 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) { case ECS_FREE: chn->state = ECS_UNBOUND; - chn->u.unbound.remote_domid = alloc->dom; + chn->u.unbound.remote_domid = alloc->remote_dom; break; case ECS_UNBOUND: - if ( chn->u.unbound.remote_domid != alloc->dom ) + if ( chn->u.unbound.remote_domid != alloc->remote_dom ) ERROR_EXIT(-EINVAL); break; @@ -99,7 +108,10 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) out: spin_unlock(&d->evtchn_lock); + put_domain(d); + alloc->port = port; + return rc; } diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h index 443be607f8..37efd85af3 100644 --- a/xen/include/public/event_channel.h +++ b/xen/include/public/event_channel.h @@ -10,14 +10,16 @@ #define __XEN_PUBLIC_EVENT_CHANNEL_H__ /* - * EVTCHNOP_alloc_unbound: Prepare a local port for binding to . - * may be wildcarded by setting to zero, in which case a fresh port - * will be allocated, and the field filled in on return. + * EVTCHNOP_alloc_unbound: Allocate a port in for later binding to + * . may be wildcarded by setting to zero, in which case a + * fresh port will be allocated, and the field filled in on return. + * NOTES: + * 1. If the caller is unprivileged then must be DOMID_SELF. */ #define EVTCHNOP_alloc_unbound 6 typedef struct evtchn_alloc_unbound { /* IN parameters */ - domid_t dom; + domid_t dom, remote_dom; /* IN/OUT parameters */ u32 port; } evtchn_alloc_unbound_t; From 66041d1b9c3a82c43d3c8f10cfd4247a7a876684 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Oct 2005 19:15:56 +0100 Subject: [PATCH 2/6] Gentoo compatible stuff has to be done *before* the set -e. You could also do the which in the if with a combination of ! and || after the set -e but I think it's cleaner to just do it before the set -e. Signed-off-by: Anthony Liguori --- tools/examples/network-bridge | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge index f862db0c3f..f0e1e1648d 100755 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -39,6 +39,17 @@ # #============================================================================ +# Gentoo doesn't have ifup/ifdown: define appropriate alternatives +which ifup >& /dev/null +if [ "$?" != 0 -a -e /etc/conf.d/net ]; then + ifup() { + /etc/init.d/net.$1 start + } + ifdown() { + /etc/init.d/net.$1 stop + } +fi + # Exit if anything goes wrong. set -e @@ -55,17 +66,6 @@ antispoof=${antispoof:-no} echo "*network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof" >&2 -# Gentoo doesn't have ifup/ifdown: define appropriate alternatives -which ifup >& /dev/null -if [ "$?" != 0 -a -e /etc/conf.d/net ]; then - ifup() { - /etc/init.d/net.$1 start - } - ifdown() { - /etc/init.d/net.$1 stop - } -fi - # Usage: transfer_addrs src dst # Copy all IP addresses (including aliases) from device $src to device $dst. transfer_addrs () { From c436ce043df0eec436d8019a404a2ef51ac1ec93 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Oct 2005 23:15:00 +0100 Subject: [PATCH 3/6] Activate suspending/resuming of the TPM interface and add some missing code to tpmif.py. Signed-off-by: Stefan Berger --- .../drivers/xen/tpmfront/tpmfront.c | 64 +++++++++---------- tools/python/xen/xend/server/tpmif.py | 17 ++++- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c index 55c44f95aa..384f39ffcb 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c @@ -442,26 +442,32 @@ static int tpmfront_remove(struct xenbus_device *dev) return 0; } -static int tpmfront_suspend(struct xenbus_device *dev) +static int +tpmfront_suspend(struct xenbus_device *dev) { struct tpmfront_info *info = dev->data; struct tpm_private *tp = &my_private; + u32 ctr = 0; - /* lock so no app can send */ + /* lock, so no app can send */ down(&suspend_lock); - while (atomic_read(&tp->tx_busy)) { - printk("---- TPMIF: Outstanding request.\n"); -#if 0 + while (atomic_read(&tp->tx_busy) && ctr <= 25) { + if ((ctr % 10) == 0) + printk("INFO: Waiting for outstanding request.\n"); /* - * Would like to wait until the outstanding request - * has come back, but this does not work properly, yet. + * Wait for a request to be responded to. */ - interruptible_sleep_on_timeout(&tp->wait_q, - 100); -#else - break; -#endif + interruptible_sleep_on_timeout(&tp->wait_q, 100); + ctr++; + } + + if (atomic_read(&tp->tx_busy)) { + /* + * A temporary work-around. + */ + printk("WARNING: Resetting busy flag."); + atomic_set(&tp->tx_busy, 0); } unregister_xenbus_watch(&info->watch); @@ -469,44 +475,34 @@ static int tpmfront_suspend(struct xenbus_device *dev) kfree(info->backend); info->backend = NULL; - destroy_tpmring(info, tp); - return 0; } -static int tpmif_recover(void) -{ - return 0; -} - -static int tpmfront_resume(struct xenbus_device *dev) +static int +tpmfront_resume(struct xenbus_device *dev) { struct tpmfront_info *info = dev->data; - int err; + int err = talk_to_backend(dev, info); - err = talk_to_backend(dev, info); - if (!err) { - tpmif_recover(); - } - - /* unlock so apps can resume */ + /* unlock, so apps can resume sending */ up(&suspend_lock); return err; } -static void tpmif_connect(u16 evtchn, domid_t domid) +static void +tpmif_connect(u16 evtchn, domid_t domid) { int err = 0; struct tpm_private *tp = &my_private; tp->evtchn = evtchn; - tp->backend_id = domid; + tp->backend_id = domid; - err = bind_evtchn_to_irqhandler( - tp->evtchn, - tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp); - if ( err <= 0 ) { + err = bind_evtchn_to_irqhandler(tp->evtchn, + tpmif_int, SA_SAMPLE_RANDOM, "tpmif", + tp); + if (err <= 0) { WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err); return; } @@ -641,7 +637,7 @@ tpm_xmit(struct tpm_private *tp, if (NULL == txb) { DPRINTK("txb (i=%d) is NULL. buffers initilized?\n", i); - DPRINTK("Not transmittin anything!\n"); + DPRINTK("Not transmitting anything!\n"); spin_unlock_irq(&tp->tx_lock); return -EFAULT; } diff --git a/tools/python/xen/xend/server/tpmif.py b/tools/python/xen/xend/server/tpmif.py index 50e8f7f016..b5269a2cb0 100644 --- a/tools/python/xen/xend/server/tpmif.py +++ b/tools/python/xen/xend/server/tpmif.py @@ -39,9 +39,24 @@ class TPMifController(DevController): """@see DevController.getDeviceDetails""" devid = int(sxp.child_value(config, 'instance', '0')) - log.debug("The domain has a TPM with instance %d." % devid) + log.info("The domain has a TPM with instance %d." % devid) back = { 'instance' : "%i" % devid } front = { 'handle' : "%i" % devid } return (devid, back, front) + + def configuration(self, devid): + + log.info("The configuration method is called.") + + result = DevContoller.configuration(self, devid) + + (instance) = self.readBackend(devif, + 'instance') + + if instance: + result.append(['instance', instance]) + log.info("configuration: instance=%d." % instance) + + return result From ec7c322ccd8def4302df3862c9b4eb4afbdb19e2 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 5 Oct 2005 23:47:09 +0100 Subject: [PATCH 4/6] Reformat the pfn_info structure to ensure that lock cmpxchg8b instructions occur only on naturally aligned 8-byte memory values. This is needed for some NUMA x86 systems. Signed-off-by: Keir Fraser Signed-off-by: Aravindh Puthiyaparambil --- xen/arch/x86/x86_32/mm.c | 1 + xen/arch/x86/x86_64/mm.c | 6 ++++-- xen/include/asm-x86/mm.h | 14 +++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 25c2ea7a7d..64491f02d9 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -156,6 +156,7 @@ void subarch_init_memory(struct domain *dom_xen) */ if ( (offsetof(struct pfn_info, u.inuse._domain) != (offsetof(struct pfn_info, count_info) + sizeof(u32))) || + ((offsetof(struct pfn_info, count_info) & 7) != 0) || (sizeof(struct pfn_info) != 24) ) { printk("Weird pfn_info layout (%ld,%ld,%d)\n", diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 76b3518111..a20c900fb0 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -137,8 +137,10 @@ void subarch_init_memory(struct domain *dom_xen) * count_info and domain fields must be adjacent, as we perform atomic * 64-bit operations on them. */ - if ( (offsetof(struct pfn_info, u.inuse._domain) != - (offsetof(struct pfn_info, count_info) + sizeof(u32))) ) + if ( ((offsetof(struct pfn_info, u.inuse._domain) != + (offsetof(struct pfn_info, count_info) + sizeof(u32)))) || + ((offsetof(struct pfn_info, count_info) & 7) != 0) || + (sizeof(struct pfn_info) != 40) ) { printk("Weird pfn_info layout (%ld,%ld,%ld)\n", offsetof(struct pfn_info, count_info), diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index a68538c0a7..9b79f86d6f 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -22,9 +22,6 @@ struct pfn_info /* Each frame can be threaded onto a doubly-linked list. */ struct list_head list; - /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */ - u32 tlbflush_timestamp; - /* Reference count and various PGC_xxx flags and fields. */ u32 count_info; @@ -37,17 +34,20 @@ struct pfn_info u32 _domain; /* pickled format */ /* Type reference count and various PGT_xxx flags and fields. */ unsigned long type_info; - } inuse; + } __attribute__ ((packed)) inuse; /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */ struct { + /* Order-size of the free chunk this page is the head of. */ + u32 order; /* Mask of possibly-tainted TLBs. */ cpumask_t cpumask; - /* Order-size of the free chunk this page is the head of. */ - u8 order; - } free; + } __attribute__ ((packed)) free; } u; + + /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */ + u32 tlbflush_timestamp; }; /* The following page types are MUTUALLY EXCLUSIVE. */ From 993adabd0023db2efd8e9b980501a4fbf55e1e3f Mon Sep 17 00:00:00 2001 From: "vh249@kneesaa.uk.xensource.com" Date: Wed, 5 Oct 2005 19:16:29 -0400 Subject: [PATCH 5/6] mixup in vcpu-enable and vcpu-disable help string Signed-off-by: Vincent Hanquez --- tools/python/xen/xm/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 1ce9985a1c..df458c5d88 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -86,8 +86,8 @@ xm full list of subcommands: shutdown [-w|-a] shutdown a domain sysrq send a sysrq to a domain unpause unpause a paused domain - vcpu-enable disable VCPU in a domain - vcpu-disable enable VCPU in a domain + vcpu-enable enable VCPU in a domain + vcpu-disable disable VCPU in a domain vcpu-list get the list of VCPUs for a domain vcpu-pin set which cpus a VCPU can use. From e926a106968c31292ed850b60197fb9af112d69e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 6 Oct 2005 10:42:32 +0100 Subject: [PATCH 6/6] Ensure that all fields of evtchn_op_t are initialised when making an event_channel_op hypercall. Stefan Berger gets the credit for diagnosing nasty domU driver problems that were a result of garbage fields. Signed-off-by: Stefan Berger Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c | 26 ++++----- .../drivers/xen/blkback/interface.c | 11 ++-- .../drivers/xen/blkfront/blkfront.c | 8 +-- .../drivers/xen/blktap/interface.c | 11 ++-- .../drivers/xen/netback/interface.c | 11 ++-- .../drivers/xen/netfront/netfront.c | 8 +-- .../drivers/xen/tpmback/interface.c | 11 ++-- .../drivers/xen/tpmfront/tpmfront.c | 8 +-- linux-2.6-xen-sparse/include/asm-xen/evtchn.h | 6 +- tools/libxc/xc_evtchn.c | 57 +++++++++---------- 10 files changed, 75 insertions(+), 82 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index 647f1f240b..c9555d5e70 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -180,14 +180,13 @@ static int find_unbound_irq(void) int bind_virq_to_irq(int virq) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq }; int evtchn, irq; int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) { - op.cmd = EVTCHNOP_bind_virq; op.u.bind_virq.virq = virq; op.u.bind_virq.vcpu = cpu; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); @@ -212,7 +211,7 @@ EXPORT_SYMBOL(bind_virq_to_irq); void unbind_virq_from_irq(int virq) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_close }; int cpu = smp_processor_id(); int irq = per_cpu(virq_to_irq, cpu)[virq]; int evtchn = irq_to_evtchn[irq]; @@ -220,7 +219,6 @@ void unbind_virq_from_irq(int virq) spin_lock(&irq_mapping_update_lock); if (--irq_bindcount[irq] == 0) { - op.cmd = EVTCHNOP_close; op.u.close.dom = DOMID_SELF; op.u.close.port = evtchn; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); @@ -245,14 +243,13 @@ EXPORT_SYMBOL(unbind_virq_from_irq); int bind_ipi_to_irq(int ipi) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi }; int evtchn, irq; int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) { - op.cmd = EVTCHNOP_bind_ipi; op.u.bind_ipi.vcpu = cpu; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); evtchn = op.u.bind_ipi.port; @@ -278,7 +275,7 @@ EXPORT_SYMBOL(bind_ipi_to_irq); void unbind_ipi_from_irq(int ipi) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_close }; int cpu = smp_processor_id(); int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; int irq = evtchn_to_irq[evtchn]; @@ -286,7 +283,6 @@ void unbind_ipi_from_irq(int ipi) spin_lock(&irq_mapping_update_lock); if (--irq_bindcount[irq] == 0) { - op.cmd = EVTCHNOP_close; op.u.close.dom = DOMID_SELF; op.u.close.port = evtchn; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); @@ -324,13 +320,12 @@ EXPORT_SYMBOL(bind_evtchn_to_irq); void unbind_evtchn_from_irq(unsigned int irq) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_close }; int evtchn = irq_to_evtchn[irq]; spin_lock(&irq_mapping_update_lock); if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) { - op.cmd = EVTCHNOP_close; op.u.close.dom = DOMID_SELF; op.u.close.port = evtchn; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); @@ -378,7 +373,7 @@ static void do_nothing_function(void *ign) /* Rebind an evtchn so that it gets delivered to a specific cpu */ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu }; int evtchn; spin_lock(&irq_mapping_update_lock); @@ -389,7 +384,6 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu) } /* Send future instances of this interrupt to other vcpu. */ - op.cmd = EVTCHNOP_bind_vcpu; op.u.bind_vcpu.port = evtchn; op.u.bind_vcpu.vcpu = tcpu; @@ -518,10 +512,9 @@ static inline void pirq_query_unmask(int pirq) static unsigned int startup_pirq(unsigned int irq) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq }; int evtchn; - op.cmd = EVTCHNOP_bind_pirq; op.u.bind_pirq.pirq = irq; /* NB. We are happy to share unless we are probing. */ op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE; @@ -547,7 +540,7 @@ static unsigned int startup_pirq(unsigned int irq) static void shutdown_pirq(unsigned int irq) { - evtchn_op_t op; + evtchn_op_t op = { .cmd = EVTCHNOP_close }; int evtchn = irq_to_evtchn[irq]; if (!VALID_EVTCHN(evtchn)) @@ -555,7 +548,6 @@ static void shutdown_pirq(unsigned int irq) mask_evtchn(evtchn); - op.cmd = EVTCHNOP_close; op.u.close.dom = DOMID_SELF; op.u.close.port = evtchn; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); @@ -666,6 +658,7 @@ void irq_resume(void) continue; /* Get a new binding from Xen. */ + memset(&op, 0, sizeof(op)); op.cmd = EVTCHNOP_bind_virq; op.u.bind_virq.virq = virq; op.u.bind_virq.vcpu = 0; @@ -689,6 +682,7 @@ void irq_resume(void) evtchn_to_irq[evtchn] = -1; /* Get a new binding from Xen. */ + memset(&op, 0, sizeof(op)); op.cmd = EVTCHNOP_bind_ipi; op.u.bind_ipi.vcpu = 0; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c index 92e37850b3..5deb5b0cb6 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -68,8 +68,13 @@ static void unmap_frontend_page(blkif_t *blkif) int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { blkif_sring_t *sring; - evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_interdomain, + .u.bind_interdomain.dom1 = DOMID_SELF, + .u.bind_interdomain.dom2 = blkif->domid, + .u.bind_interdomain.port1 = 0, + .u.bind_interdomain.port2 = evtchn }; if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) return -ENOMEM; @@ -80,10 +85,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) return err; } - op.u.bind_interdomain.dom1 = DOMID_SELF; - op.u.bind_interdomain.dom2 = blkif->domid; - op.u.bind_interdomain.port1 = 0; - op.u.bind_interdomain.port2 = evtchn; err = HYPERVISOR_event_channel_op(&op); if (err) { unmap_frontend_page(blkif); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 00caac5d95..c30ab0f8b0 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -485,8 +485,11 @@ static void watch_for_status(struct xenbus_watch *watch, const char *node) static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info) { blkif_sring_t *sring; - evtchn_op_t op; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_alloc_unbound, + .u.alloc_unbound.dom = DOMID_SELF, + .u.alloc_unbound.remote_dom = info->backend_id }; info->ring_ref = GRANT_INVALID_REF; @@ -508,9 +511,6 @@ static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info) } info->ring_ref = err; - op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.dom = DOMID_SELF; - op.u.alloc_unbound.remote_dom = info->backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { gnttab_end_foreign_access(info->ring_ref, 0); diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c index 85cf5d7362..364025d8f8 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c @@ -68,8 +68,13 @@ static void unmap_frontend_page(blkif_t *blkif) int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) { blkif_sring_t *sring; - evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_interdomain, + .u.bind_interdomain.dom1 = DOMID_SELF, + .u.bind_interdomain.dom2 = blkif->domid, + .u.bind_interdomain.port1 = 0, + .u.bind_interdomain.port2 = evtchn }; if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL) return -ENOMEM; @@ -80,10 +85,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) return err; } - op.u.bind_interdomain.dom1 = DOMID_SELF; - op.u.bind_interdomain.dom2 = blkif->domid; - op.u.bind_interdomain.port1 = 0; - op.u.bind_interdomain.port2 = evtchn; err = HYPERVISOR_event_channel_op(&op); if (err) { unmap_frontend_page(blkif); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index b8b495ecb3..ab8f9518c7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -177,8 +177,13 @@ static void unmap_frontend_pages(netif_t *netif) int netif_map(netif_t *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn) { - evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_interdomain, + .u.bind_interdomain.dom1 = DOMID_SELF, + .u.bind_interdomain.dom2 = netif->domid, + .u.bind_interdomain.port1 = 0, + .u.bind_interdomain.port2 = evtchn }; netif->comms_area = alloc_vm_area(2*PAGE_SIZE); if (netif->comms_area == NULL) @@ -190,10 +195,6 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref, return err; } - op.u.bind_interdomain.dom1 = DOMID_SELF; - op.u.bind_interdomain.dom2 = netif->domid; - op.u.bind_interdomain.port1 = 0; - op.u.bind_interdomain.port2 = evtchn; err = HYPERVISOR_event_channel_op(&op); if (err) { unmap_frontend_pages(netif); diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index 7bd156625b..f78cbad13e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -972,8 +972,11 @@ static void watch_for_status(struct xenbus_watch *watch, const char *node) static int setup_device(struct xenbus_device *dev, struct netfront_info *info) { - evtchn_op_t op; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_alloc_unbound, + .u.alloc_unbound.dom = DOMID_SELF, + .u.alloc_unbound.remote_dom = info->backend_id }; info->tx_ring_ref = GRANT_INVALID_REF; info->rx_ring_ref = GRANT_INVALID_REF; @@ -1010,9 +1013,6 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info) } info->rx_ring_ref = err; - op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.dom = DOMID_SELF; - op.u.alloc_unbound.remote_dom = info->backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { xenbus_dev_error(dev, err, "allocating event channel"); diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c index 43c6f6e0cc..514cf1130a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c @@ -117,8 +117,13 @@ unmap_frontend_page(tpmif_t *tpmif) int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn) { - evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain }; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_interdomain, + .u.bind_interdomain.dom1 = DOMID_SELF, + .u.bind_interdomain.dom2 = tpmif->domid, + .u.bind_interdomain.port1 = 0, + .u.bind_interdomain.port2 = evtchn }; if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL) return -ENOMEM; @@ -129,10 +134,6 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn) return err; } - op.u.bind_interdomain.dom1 = DOMID_SELF; - op.u.bind_interdomain.dom2 = tpmif->domid; - op.u.bind_interdomain.port1 = 0; - op.u.bind_interdomain.port2 = evtchn; err = HYPERVISOR_event_channel_op(&op); if (err) { unmap_frontend_page(tpmif); diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c index 384f39ffcb..8fda9cee72 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c @@ -244,8 +244,11 @@ static int setup_tpmring(struct xenbus_device *dev, { tpmif_tx_interface_t *sring; struct tpm_private *tp = &my_private; - evtchn_op_t op; int err; + evtchn_op_t op = { + .cmd = EVTCHNOP_alloc_unbound, + .u.alloc_unbound.dom = DOMID_SELF, + .u.alloc_unbound.remote_dom = backend_id } ; sring = (void *)__get_free_page(GFP_KERNEL); if (!sring) { @@ -268,9 +271,6 @@ static int setup_tpmring(struct xenbus_device *dev, } info->ring_ref = err; - op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.dom = DOMID_SELF; - op.u.alloc_unbound.remote_dom = backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { gnttab_end_foreign_access(info->ring_ref, 0); diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index d2f5279be8..149f01fe7b 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -123,9 +123,9 @@ static inline void clear_evtchn(int port) static inline void notify_remote_via_evtchn(int port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_send; - op.u.send.local_port = port; + evtchn_op_t op = { + .cmd = EVTCHNOP_send, + .u.send.local_port = port }; (void)HYPERVISOR_event_channel_op(&op); } diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c index 3bdacf36a3..ed6256654b 100644 --- a/tools/libxc/xc_evtchn.c +++ b/tools/libxc/xc_evtchn.c @@ -37,13 +37,12 @@ int xc_evtchn_alloc_unbound(int xc_handle, u32 dom, int *port) { - evtchn_op_t op; int rc; - - op.cmd = EVTCHNOP_alloc_unbound; - op.u.alloc_unbound.remote_dom = (domid_t)remote_dom; - op.u.alloc_unbound.dom = (domid_t)dom; - op.u.alloc_unbound.port = (port != NULL) ? *port : 0; + evtchn_op_t op = { + .cmd = EVTCHNOP_alloc_unbound, + .u.alloc_unbound.remote_dom = (domid_t)remote_dom, + .u.alloc_unbound.dom = (domid_t)dom, + .u.alloc_unbound.port = (port != NULL) ? *port : 0 }; if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) { @@ -61,15 +60,13 @@ int xc_evtchn_bind_interdomain(int xc_handle, int *port1, int *port2) { - evtchn_op_t op; int rc; - - op.cmd = EVTCHNOP_bind_interdomain; - op.u.bind_interdomain.dom1 = (domid_t)dom1; - op.u.bind_interdomain.dom2 = (domid_t)dom2; - op.u.bind_interdomain.port1 = (port1 != NULL) ? *port1 : 0; - op.u.bind_interdomain.port2 = (port2 != NULL) ? *port2 : 0; - + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_interdomain, + .u.bind_interdomain.dom1 = (domid_t)dom1, + .u.bind_interdomain.dom2 = (domid_t)dom2, + .u.bind_interdomain.port1 = (port1 != NULL) ? *port1 : 0, + .u.bind_interdomain.port2 = (port2 != NULL) ? *port2 : 0 }; if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) { @@ -87,12 +84,11 @@ int xc_evtchn_bind_virq(int xc_handle, int virq, int *port) { - evtchn_op_t op; int rc; - - op.cmd = EVTCHNOP_bind_virq; - op.u.bind_virq.virq = (u32)virq; - op.u.bind_virq.vcpu = 0; + evtchn_op_t op = { + .cmd = EVTCHNOP_bind_virq, + .u.bind_virq.virq = (u32)virq, + .u.bind_virq.vcpu = 0 }; if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) { @@ -108,10 +104,10 @@ int xc_evtchn_close(int xc_handle, u32 dom, int port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_close; - op.u.close.dom = (domid_t)dom; - op.u.close.port = port; + evtchn_op_t op = { + .cmd = EVTCHNOP_close, + .u.close.dom = (domid_t)dom, + .u.close.port = port }; return do_evtchn_op(xc_handle, &op); } @@ -119,9 +115,9 @@ int xc_evtchn_close(int xc_handle, int xc_evtchn_send(int xc_handle, int local_port) { - evtchn_op_t op; - op.cmd = EVTCHNOP_send; - op.u.send.local_port = local_port; + evtchn_op_t op = { + .cmd = EVTCHNOP_send, + .u.send.local_port = local_port }; return do_evtchn_op(xc_handle, &op); } @@ -131,13 +127,12 @@ int xc_evtchn_status(int xc_handle, int port, xc_evtchn_status_t *status) { - evtchn_op_t op; int rc; + evtchn_op_t op = { + .cmd = EVTCHNOP_status, + .u.status.dom = (domid_t)dom, + .u.status.port = port }; - op.cmd = EVTCHNOP_status; - op.u.status.dom = (domid_t)dom; - op.u.status.port = port; - if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) memcpy(status, &op.u.status, sizeof(*status));