static int physdev_unmap_pirq(struct physdev_unmap_pirq *unmap) { struct domain *d; int ret; ret = rcu_lock_target_domain_by_id(unmap->domid, &d); if ( ret ) return ret; if ( is_hvm_domain(d) ) { spin_lock(&d->event_lock); if ( domain_pirq_to_emuirq(d, unmap->pirq) != IRQ_UNBOUND ) ret = unmap_domain_pirq_emuirq(d, unmap->pirq); spin_unlock(&d->event_lock); if ( unmap->domid == DOMID_SELF || ret ) goto free_domain; } ret = -EPERM; if ( !IS_PRIV_FOR(current->domain, d) ) goto free_domain; spin_lock(&pcidevs_lock); spin_lock(&d->event_lock); ret = unmap_domain_pirq(d, unmap->pirq); spin_unlock(&d->event_lock); spin_unlock(&pcidevs_lock); free_domain: rcu_unlock_domain(d); return ret; }
int physdev_unmap_pirq(domid_t domid, int pirq) { struct domain *d; int ret; d = rcu_lock_domain_by_any_id(domid); if ( d == NULL ) return -ESRCH; ret = xsm_unmap_domain_pirq(XSM_TARGET, d); if ( ret ) goto free_domain; if ( is_hvm_domain(d) ) { spin_lock(&d->event_lock); if ( domain_pirq_to_emuirq(d, pirq) != IRQ_UNBOUND ) ret = unmap_domain_pirq_emuirq(d, pirq); spin_unlock(&d->event_lock); if ( domid == DOMID_SELF || ret ) goto free_domain; } spin_lock(&pcidevs_lock); spin_lock(&d->event_lock); ret = unmap_domain_pirq(d, pirq); spin_unlock(&d->event_lock); spin_unlock(&pcidevs_lock); free_domain: rcu_unlock_domain(d); return ret; }
static int physdev_unmap_pirq(struct physdev_unmap_pirq *unmap) { struct domain *d; int ret; if ( !IS_PRIV(current->domain) ) return -EPERM; if ( unmap->domid == DOMID_SELF ) d = rcu_lock_domain(current->domain); else d = rcu_lock_domain_by_id(unmap->domid); if ( d == NULL ) return -ESRCH; spin_lock(&pcidevs_lock); spin_lock(&d->event_lock); ret = unmap_domain_pirq(d, unmap->pirq); spin_unlock(&d->event_lock); spin_unlock(&pcidevs_lock); rcu_unlock_domain(d); return ret; }