return do_domctl(xc_handle, &domctl);
}
-int xc_dom_subscribe(int xc_handle, domid_t dom, evtchn_port_t port)
+int xc_domain_subscribe_for_suspend(
+ int xc_handle, domid_t dom, evtchn_port_t port)
{
DECLARE_DOMCTL;
* Subscribe to state changes in a domain via evtchn.
* Returns -1 on failure, in which case errno will be set appropriately.
*/
-int xc_dom_subscribe(int xc_handle, domid_t domid, evtchn_port_t port);
+int xc_domain_subscribe_for_suspend(
+ int xc_handle, domid_t domid, evtchn_port_t port);
/**************************
* GRANT TABLE OPERATIONS *
static struct suspendinfo {
int xce; /* event channel handle */
-
int suspend_evtchn;
- int suspended_evtchn;
} si;
/**
static int suspend_evtchn_release(int xc, int domid)
{
- if (si.suspended_evtchn >= 0) {
- xc_dom_subscribe(xc, domid, 0);
- xc_evtchn_unbind(si.xce, si.suspended_evtchn);
- si.suspended_evtchn = -1;
- }
if (si.suspend_evtchn >= 0) {
xc_evtchn_unbind(si.xce, si.suspend_evtchn);
si.suspend_evtchn = -1;
si.xce = -1;
si.suspend_evtchn = -1;
- si.suspended_evtchn = -1;
xs = xs_daemon_open();
if (!xs) {
goto cleanup;
}
- si.suspended_evtchn = xc_evtchn_bind_unbound_port(si.xce, domid);
- if (si.suspended_evtchn < 0) {
- errx(1, "failed to allocate suspend notification port: %d",
- si.suspended_evtchn);
- goto cleanup;
- }
-
- rc = xc_dom_subscribe(xc, domid, si.suspended_evtchn);
+ rc = xc_domain_subscribe_for_suspend(xc, domid, port);
if (rc < 0) {
errx(1, "failed to subscribe to domain: %d", rc);
goto cleanup;
errx(1, "error polling suspend notification channel: %d", rc);
return 0;
}
- } while (rc != si.suspended_evtchn);
+ } while (rc != si.suspend_evtchn);
/* harmless for one-off suspend */
- if (xc_evtchn_unmask(si.xce, si.suspended_evtchn) < 0)
+ if (xc_evtchn_unmask(si.xce, si.suspend_evtchn) < 0)
errx(1, "failed to unmask suspend notification channel: %d", rc);
/* notify xend that it can do device migration */
d->is_shut_down = 1;
if ( (d->shutdown_code == SHUTDOWN_suspend) && d->suspend_evtchn )
- evtchn_set_pending(dom0->vcpu[0], d->suspend_evtchn);
+ evtchn_send(d, d->suspend_evtchn);
else
send_guest_global_virq(dom0, VIRQ_DOM_EXC);
}
goto out; \
} while ( 0 )
+static int evtchn_set_pending(struct vcpu *v, int port);
+
static int virq_is_global(int virq)
{
int rc;
return __evtchn_close(current->domain, close->port);
}
-
-long evtchn_send(unsigned int lport)
+int evtchn_send(struct domain *d, unsigned int lport)
{
struct evtchn *lchn, *rchn;
- struct domain *ld = current->domain, *rd;
+ struct domain *ld = d, *rd;
struct vcpu *rvcpu;
int rport, ret = 0;
return ret;
}
-
-int evtchn_set_pending(struct vcpu *v, int port)
+static int evtchn_set_pending(struct vcpu *v, int port)
{
struct domain *d = v->domain;
struct evtchn_send send;
if ( copy_from_guest(&send, arg, 1) != 0 )
return -EFAULT;
- rc = evtchn_send(send.port);
+ rc = evtchn_send(current->domain, send.port);
break;
}
#include <asm/bitops.h>
#include <asm/event.h>
-/* Returns TRUE if the delivery port was already pending. */
-int evtchn_set_pending(struct vcpu *v, int port);
-
/*
* send_guest_vcpu_virq: Notify guest via a per-VCPU VIRQ.
* @v: VCPU to which virtual IRQ should be sent
*/
int send_guest_pirq(struct domain *d, int pirq);
-/* Send a notification from a local event-channel port. */
-long evtchn_send(unsigned int lport);
+/* Send a notification from a given domain's event-channel port. */
+int evtchn_send(struct domain *d, unsigned int lport);
/* Bind a local event-channel port to the specified VCPU. */
long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);