#define XEN_EVTCHN_TYPE_VIRQ 0
#define XEN_EVTCHN_TYPE_IPI 1
#define XEN_EVTCHN_TYPE_INTERDOM 2
+#define XEN_EVTCHN_TYPE_UNBOUND 3
int type;
-#define XEN_EVTCHN_STATE_FREE 0
-#define XEN_EVTCHN_STATE_INUSE 1
+#define XEN_EVTCHN_STATE_FREE 0
+#define XEN_EVTCHN_STATE_INUSE 1
+#define XEN_EVTCHN_STATE_UNBOUND 2
int state;
} XenEvtChn;
static struct XenEvtChn *evtchn_from_port(int port)
{
- if (port <= 0 || !group_from_port(port)) {
+ if (port <= 0 || (groupid_from_port(port) >= EVTCHN_MAX_GROUPS) ||
+ !group_from_port(port)) {
return NULL;
}
if (e->type == XEN_EVTCHN_TYPE_VIRQ) {
xenevfd.virq.type = e->virq;
- } else if (e->type == XEN_EVTCHN_TYPE_INTERDOM) {
+ } else if ((e->type == XEN_EVTCHN_TYPE_INTERDOM) ||
+ (e->type == XEN_EVTCHN_TYPE_UNBOUND)) {
xenevfd.remote.domid = e->remote_dom;
xenevfd.remote.port = e->remote_port;
}
return 0;
}
+int kvm_xen_evtchn_alloc_unbound(X86CPU *cpu, void *arg)
+{
+ struct evtchn_alloc_unbound *out = arg;
+ struct evtchn_alloc_unbound alloc;
+ struct XenEvtChn *evtchn;
+ int default_vcpu = 0;
+ CPUState *dest;
+ int r;
+
+ memcpy(&alloc, arg, sizeof(alloc));
+
+ dest = qemu_get_cpu(default_vcpu);
+ if (!dest) {
+ return -EINVAL;
+ }
+
+ evtchn = alloc_evtchn(CPU(cpu)->xen_state);
+ if (!evtchn) {
+ return -ENOMEM;
+ }
+
+ if (alloc.remote_dom == DOMID_SELF) {
+ alloc.remote_dom = dest->xen_state->domid;
+ }
+ if (alloc.dom == DOMID_SELF) {
+ alloc.dom = dest->xen_state->domid;
+ }
+
+ evtchn->type = XEN_EVTCHN_TYPE_UNBOUND;
+ evtchn->remote_dom = alloc.remote_dom;
+ evtchn->notify_vcpu_id = default_vcpu;
+ evtchn->state = XEN_EVTCHN_STATE_UNBOUND;
+
+ if (evtchn->remote_dom >= 0) {
+ r = kvm_set_xen_event(dest->kvm_state, evtchn, NULL);
+ if (r) {
+ evtchn->state = XEN_EVTCHN_STATE_FREE;
+ return -EINVAL;
+ }
+ }
+
+ out->port = evtchn->port;
+
+ return 0;
+}
+
int kvm_xen_evtchn_close(X86CPU *cpu, void *arg)
{
struct evtchn_close close;
trace_kvm_xen_evtchn_send(CPU(cpu)->cpu_index, evtchn->notify_vcpu_id,
send.port);
+
return 0;
}
int kvm_xen_evtchn_bind_ipi(X86CPU *cpu, void *arg);
int kvm_xen_evtchn_bind_virq(X86CPU *cpu, void *arg);
int kvm_xen_evtchn_bind_interdomain(X86CPU *cpu, void *arg);
+int kvm_xen_evtchn_alloc_unbound(X86CPU *cpu, void *arg);
int kvm_xen_evtchn_close(X86CPU *cpu, void *arg);
int kvm_xen_evtchn_unmask(X86CPU *cpu, void *arg);
int kvm_xen_evtchn_status(X86CPU *cpu, void *arg);