domctl: fix IRQ permission granting/revocation Commit 545607eb3c ("x86: fix various issues with handling guest IRQs") wasn't really consistent in one respect: The granting of access to an IRQ shouldn't assume the pIRQ->IRQ translation to be the same in both domains. In fact it is wrong to assume that a translation is already/ still in place at the time access is being granted/revoked. Signed-off-by: Jan Beulich --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -981,18 +981,18 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_irq_permission: { - unsigned int pirq = op->u.irq_permission.pirq; + unsigned int pirq = op->u.irq_permission.pirq, irq; int allow = op->u.irq_permission.allow_access; if ( pirq >= d->nr_pirqs ) ret = -EINVAL; - else if ( !pirq_access_permitted(current->domain, pirq) || + else if ( !(irq = pirq_access_permitted(current->domain, pirq)) || xsm_irq_permission(XSM_HOOK, d, pirq, allow) ) ret = -EPERM; else if ( allow ) - ret = pirq_permit_access(d, pirq); + ret = irq_permit_access(d, irq); else - ret = pirq_deny_access(d, pirq); + ret = irq_deny_access(d, irq); } break; --- a/xen/include/xen/iocap.h +++ b/xen/include/xen/iocap.h @@ -28,22 +28,11 @@ #define irq_access_permitted(d, i) \ rangeset_contains_singleton((d)->irq_caps, i) -#define pirq_permit_access(d, i) ({ \ - struct domain *d__ = (d); \ - int i__ = domain_pirq_to_irq(d__, i); \ - i__ > 0 ? rangeset_add_singleton(d__->irq_caps, i__)\ - : -EINVAL; \ -}) -#define pirq_deny_access(d, i) ({ \ - struct domain *d__ = (d); \ - int i__ = domain_pirq_to_irq(d__, i); \ - i__ > 0 ? rangeset_remove_singleton(d__->irq_caps, i__)\ - : -EINVAL; \ -}) #define pirq_access_permitted(d, i) ({ \ struct domain *d__ = (d); \ - rangeset_contains_singleton(d__->irq_caps, \ - domain_pirq_to_irq(d__, i));\ + int irq__ = domain_pirq_to_irq(d__, i); \ + irq__ > 0 && irq_access_permitted(d__, irq__) \ + ? irq__ : 0; \ }) #endif /* __XEN_IOCAP_H__ */