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
@@ -104,7 +104,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;
 
@@ -140,7 +140,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
@@ -579,7 +579,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;
 
@@ -617,7 +617,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
@@ -437,6 +437,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,13 +168,11 @@ 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_get_domain_state:
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_memory_mapping:
+    case XEN_DOMCTL_unbind_pt_irq:
         ASSERT_UNREACHABLE();
         return -EILSEQ;
 
@@ -534,14 +532,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
@@ -650,10 +650,12 @@ 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_get_domain_state:
     case XEN_DOMCTL_ioport_mapping:
     case XEN_DOMCTL_memory_mapping:
+    case XEN_DOMCTL_unbind_pt_irq:
         ASSERT_UNREACHABLE();
         return -EILSEQ;
 
@@ -664,9 +666,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:
