|
@@ -877,11 +877,32 @@ static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
|
|
return err ? : bind_evtchn_to_irq(bind_interdomain.local_port);
|
|
return err ? : bind_evtchn_to_irq(bind_interdomain.local_port);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int find_virq(unsigned int virq, unsigned int cpu)
|
|
|
|
+{
|
|
|
|
+ struct evtchn_status status;
|
|
|
|
+ int port, rc = -ENOENT;
|
|
|
|
+
|
|
|
|
+ memset(&status, 0, sizeof(status));
|
|
|
|
+ for (port = 0; port <= NR_EVENT_CHANNELS; port++) {
|
|
|
|
+ status.dom = DOMID_SELF;
|
|
|
|
+ status.port = port;
|
|
|
|
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status);
|
|
|
|
+ if (rc < 0)
|
|
|
|
+ continue;
|
|
|
|
+ if (status.status != EVTCHNSTAT_virq)
|
|
|
|
+ continue;
|
|
|
|
+ if (status.u.virq == virq && status.vcpu == cpu) {
|
|
|
|
+ rc = port;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
|
|
int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
|
|
int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
|
|
{
|
|
{
|
|
struct evtchn_bind_virq bind_virq;
|
|
struct evtchn_bind_virq bind_virq;
|
|
- int evtchn, irq;
|
|
|
|
|
|
+ int evtchn, irq, ret;
|
|
|
|
|
|
spin_lock(&irq_mapping_update_lock);
|
|
spin_lock(&irq_mapping_update_lock);
|
|
|
|
|
|
@@ -897,10 +918,16 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
|
|
|
|
|
|
bind_virq.virq = virq;
|
|
bind_virq.virq = virq;
|
|
bind_virq.vcpu = cpu;
|
|
bind_virq.vcpu = cpu;
|
|
- if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
|
|
|
|
- &bind_virq) != 0)
|
|
|
|
- BUG();
|
|
|
|
- evtchn = bind_virq.port;
|
|
|
|
|
|
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
|
|
|
|
+ &bind_virq);
|
|
|
|
+ if (ret == 0)
|
|
|
|
+ evtchn = bind_virq.port;
|
|
|
|
+ else {
|
|
|
|
+ if (ret == -EEXIST)
|
|
|
|
+ ret = find_virq(virq, cpu);
|
|
|
|
+ BUG_ON(ret < 0);
|
|
|
|
+ evtchn = ret;
|
|
|
|
+ }
|
|
|
|
|
|
xen_irq_info_virq_init(cpu, irq, evtchn, virq);
|
|
xen_irq_info_virq_init(cpu, irq, evtchn, virq);
|
|
|
|
|