From: Jan Beulich <jbeulich@suse.com>
Subject: domctl: handle XEN_DOMCTL_{,un}bind_pt_irq without acquiring domctl lock

With dedicated locking added, the domctl lock isn't required here anymore.
(It also already isn't used when pt_irq_{create,destroy}_bind() are
invoked for PVH Dom0.) As the handling is in arch-specific code, no code
is being moved, but the 2nd (extensible to other sub-ops like the ones
here) invocation of arch_do_domctl() is being re-used.

This is part of XSA-492.

Fixes: fda49f9b3fbb ("Add build option to allow more hypercalls from stubdoms")
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Acked-by: Julien Grall <julien@xen.org>

--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -103,7 +103,7 @@ long arch_do_domctl(struct xen_domctl *d
         if ( rc )
             return rc;
 
-        rc = xsm_bind_pt_irq(XSM_HOOK, d, bind);
+        rc = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
         if ( rc )
             return rc;
 
@@ -139,7 +139,7 @@ long arch_do_domctl(struct xen_domctl *d
         if ( irq != virq )
             return -EINVAL;
 
-        rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
+        rc = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
         if ( rc )
             return rc;
 
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -530,7 +530,7 @@ long arch_do_domctl(
         if ( !is_hvm_domain(d) )
             break;
 
-        ret = xsm_bind_pt_irq(XSM_HOOK, d, bind);
+        ret = xsm_bind_pt_irq(XSM_DM_PRIV, d, bind);
         if ( ret )
             break;
 
@@ -568,7 +568,7 @@ long arch_do_domctl(
         if ( !is_hvm_domain(d) )
             break;
 
-        ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
+        ret = xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind);
         if ( ret )
             break;
 
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -423,6 +423,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe
     }
 
     case XEN_DOMCTL_ioport_mapping:
+    case XEN_DOMCTL_bind_pt_irq:
+    case XEN_DOMCTL_unbind_pt_irq:
         ret = arch_do_domctl(op, d, u_domctl);
         goto domctl_out_unlock_domonly;
 
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -168,12 +168,10 @@ static XSM_INLINE int cf_check xsm_domct
     switch ( cmd )
     {
     case XEN_DOMCTL_bind_pt_irq:
-    case XEN_DOMCTL_unbind_pt_irq:
-        return xsm_default_action(XSM_DM_PRIV, current->domain, d);
-
     case XEN_DOMCTL_getdomaininfo:
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_memory_mapping:
+    case XEN_DOMCTL_unbind_pt_irq:
         ASSERT_UNREACHABLE();
         return -EILSEQ;
 
@@ -540,14 +538,14 @@ static XSM_INLINE int cf_check xsm_unmap
 static XSM_INLINE int cf_check xsm_bind_pt_irq(
     XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
 {
-    XSM_ASSERT_ACTION(XSM_HOOK);
+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
     return xsm_default_action(action, current->domain, d);
 }
 
 static XSM_INLINE int cf_check xsm_unbind_pt_irq(
     XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
 {
-    XSM_ASSERT_ACTION(XSM_HOOK);
+    XSM_ASSERT_ACTION(XSM_DM_PRIV);
     return xsm_default_action(action, current->domain, d);
 }
 
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -679,9 +679,11 @@ static int cf_check flask_domctl(struct
         return avc_current_has_perm(ssidref, SECCLASS_DOMAIN, DOMAIN__CREATE, NULL);
 
     /* These have individual XSM hooks and don't make it here. */
+    case XEN_DOMCTL_bind_pt_irq:
     case XEN_DOMCTL_getdomaininfo:
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_memory_mapping:
+    case XEN_DOMCTL_unbind_pt_irq:
         ASSERT_UNREACHABLE();
         return -EILSEQ;
 
@@ -692,9 +694,6 @@ static int cf_check flask_domctl(struct
     case XEN_DOMCTL_set_target:
     case XEN_DOMCTL_vm_event_op:
 
-    /* These have individual XSM hooks (arch/../domctl.c) */
-    case XEN_DOMCTL_bind_pt_irq:
-    case XEN_DOMCTL_unbind_pt_irq:
 #ifdef CONFIG_X86
     /* These have individual XSM hooks (arch/x86/domctl.c) */
     case XEN_DOMCTL_shadow_op:
