diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 18c19c4b63..83bf51e498 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -276,10 +276,13 @@ long arch_do_domctl( break; } + ret = xsm_irq_permission(XSM_PRIV, d, irq, flags); + if ( ret ) + break; + iocaps_double_lock(d, true); - if ( !irq_access_permitted(currd, irq) || - xsm_irq_permission(XSM_HOOK, d, irq, flags) ) + if ( !irq_access_permitted(currd, irq) ) ret = -EPERM; else if ( flags ) ret = irq_permit_access(d, irq); diff --git a/xen/common/domctl.c b/xen/common/domctl.c index c6c8e0440b..4bb4be009b 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -464,8 +464,41 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) goto domctl_out_unlock_domonly; } +#ifdef CONFIG_HAS_PIRQ + case XEN_DOMCTL_irq_permission: + { + unsigned int pirq = op->u.irq_permission.pirq, irq; + bool allow = op->u.irq_permission.allow_access; + + ret = -EINVAL; + if ( pirq >= current->domain->nr_pirqs ) + goto domctl_out_unlock_domonly; + + irq = domain_pirq_to_irq(current->domain, pirq); + + ret = -EPERM; + if ( irq ) + ret = xsm_irq_permission(XSM_PRIV, d, irq, allow); + if ( ret ) + goto domctl_out_unlock_domonly; + + iocaps_double_lock(d, true); + + if ( !irq_access_permitted(current->domain, irq) ) + ret = -EPERM; + else if ( allow ) + ret = irq_permit_access(d, irq); + else + ret = irq_deny_access(d, irq); + + iocaps_double_unlock(d, true); + goto domctl_out_unlock_domonly; + } +#endif + case XEN_DOMCTL_ioport_permission: case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_gsi_permission: case XEN_DOMCTL_bind_pt_irq: case XEN_DOMCTL_unbind_pt_irq: ret = arch_do_domctl(op, d, u_domctl); @@ -784,33 +817,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } break; -#ifdef CONFIG_HAS_PIRQ - case XEN_DOMCTL_irq_permission: - { - unsigned int pirq = op->u.irq_permission.pirq, irq; - int allow = op->u.irq_permission.allow_access; - - if ( pirq >= current->domain->nr_pirqs ) - { - ret = -EINVAL; - break; - } - - iocaps_double_lock(d, true); - - irq = pirq_access_permitted(current->domain, pirq); - if ( !irq || xsm_irq_permission(XSM_HOOK, d, irq, allow) ) - ret = -EPERM; - else if ( allow ) - ret = irq_permit_access(d, irq); - else - ret = irq_deny_access(d, irq); - - iocaps_double_unlock(d, true); - break; - } -#endif - case XEN_DOMCTL_settimeoffset: domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds); break; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index d3d2a29ae4..d4e3e27ab4 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -170,9 +170,11 @@ static XSM_INLINE int cf_check xsm_domctl( case XEN_DOMCTL_bind_pt_irq: case XEN_DOMCTL_getdomaininfo: case XEN_DOMCTL_get_domain_state: + case XEN_DOMCTL_gsi_permission: case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_ioport_permission: + case XEN_DOMCTL_irq_permission: case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_unbind_pt_irq: ASSERT_UNREACHABLE(); @@ -555,7 +557,7 @@ static XSM_INLINE int cf_check xsm_unmap_domain_irq( static XSM_INLINE int cf_check xsm_irq_permission( XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow) { - XSM_ASSERT_ACTION(XSM_HOOK); + XSM_ASSERT_ACTION(XSM_PRIV); return xsm_default_action(action, current->domain, d); } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 3338a35c1e..14df9b78d4 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -653,9 +653,11 @@ static int cf_check flask_domctl(struct domain *d, unsigned int cmd, case XEN_DOMCTL_bind_pt_irq: case XEN_DOMCTL_getdomaininfo: case XEN_DOMCTL_get_domain_state: + case XEN_DOMCTL_gsi_permission: case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_ioport_mapping: case XEN_DOMCTL_ioport_permission: + case XEN_DOMCTL_irq_permission: case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_unbind_pt_irq: ASSERT_UNREACHABLE(); @@ -663,14 +665,12 @@ static int cf_check flask_domctl(struct domain *d, unsigned int cmd, /* These have individual XSM hooks (common/domctl.c) */ case XEN_DOMCTL_scheduler_op: - case XEN_DOMCTL_irq_permission: case XEN_DOMCTL_set_target: case XEN_DOMCTL_vm_event_op: #ifdef CONFIG_X86 /* These have individual XSM hooks (arch/x86/domctl.c) */ case XEN_DOMCTL_shadow_op: - case XEN_DOMCTL_gsi_permission: #endif #ifdef CONFIG_HAS_PASSTHROUGH /*