--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -488,27 +488,11 @@ int xc_hvm_set_isa_irq_level(
     uint8_t isa_irq,
     unsigned int level)
 {
-    DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_isa_irq_level, arg);
-    int rc;
+    DECLARE_HVMCTL(set_isa_irq_level, dom,
+                   .isa_irq = isa_irq,
+                   .level   = level);
 
-    arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
-    if ( arg == NULL )
-    {
-        PERROR("Could not allocate memory for xc_hvm_set_isa_irq_level hypercall");
-        return -1;
-    }
-
-    arg->domid   = dom;
-    arg->isa_irq = isa_irq;
-    arg->level   = level;
-
-    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
-                  HVMOP_set_isa_irq_level,
-                  HYPERCALL_BUFFER_AS_ARG(arg));
-
-    xc_hypercall_buffer_free(xch, arg);
-
-    return rc;
+    return do_hvmctl(xch, &hvmctl);
 }
 
 int xc_hvm_set_pci_link_route(
--- a/xen/arch/x86/hvm/control.c
+++ b/xen/arch/x86/hvm/control.c
@@ -43,6 +43,30 @@ static int set_pci_intx_level(struct dom
     return 0;
 }
 
+static int set_isa_irq_level(struct domain *d,
+                             const struct xen_hvm_set_isa_irq_level *op)
+{
+    if ( op->isa_irq > 15 )
+        return -EINVAL;
+
+    if ( !is_hvm_domain(d) )
+        return -EINVAL;
+
+    switch ( op->level )
+    {
+    case 0:
+        hvm_isa_irq_deassert(d, op->isa_irq);
+        break;
+    case 1:
+        hvm_isa_irq_assert(d, op->isa_irq);
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
 long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xen_hvmctl_t) u_hvmctl)
 {
     xen_hvmctl_t op;
@@ -80,6 +104,10 @@ long do_hvmctl(XEN_GUEST_HANDLE_PARAM(xe
         rc = set_pci_intx_level(d, &op.u.set_pci_intx_level);
         break;
 
+    case XEN_HVMCTL_set_isa_irq_level:
+        rc = set_isa_irq_level(d, &op.u.set_isa_irq_level);
+        break;
+
     default:
         rc = -EOPNOTSUPP;
         break;
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4446,50 +4446,6 @@ static void hvm_s3_resume(struct domain
     }
 }
 
-static int hvmop_set_isa_irq_level(
-    XEN_GUEST_HANDLE_PARAM(xen_hvm_set_isa_irq_level_t) uop)
-{
-    struct xen_hvm_set_isa_irq_level op;
-    struct domain *d;
-    int rc;
-
-    if ( copy_from_guest(&op, uop, 1) )
-        return -EFAULT;
-
-    if ( op.isa_irq > 15 )
-        return -EINVAL;
-
-    rc = rcu_lock_remote_domain_by_id(op.domid, &d);
-    if ( rc != 0 )
-        return rc;
-
-    rc = -EINVAL;
-    if ( !is_hvm_domain(d) )
-        goto out;
-
-    rc = xsm_hvm_set_isa_irq_level(XSM_DM_PRIV, d);
-    if ( rc )
-        goto out;
-
-    rc = 0;
-    switch ( op.level )
-    {
-    case 0:
-        hvm_isa_irq_deassert(d, op.isa_irq);
-        break;
-    case 1:
-        hvm_isa_irq_assert(d, op.isa_irq);
-        break;
-    default:
-        rc = -EINVAL;
-        break;
-    }
-
- out:
-    rcu_unlock_domain(d);
-    return rc;
-}
-
 static int hvmop_set_pci_link_route(
     XEN_GUEST_HANDLE_PARAM(xen_hvm_set_pci_link_route_t) uop)
 {
@@ -5364,11 +5320,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
             guest_handle_cast(arg, xen_hvm_param_t));
         break;
 
-    case HVMOP_set_isa_irq_level:
-        rc = hvmop_set_isa_irq_level(
-            guest_handle_cast(arg, xen_hvm_set_isa_irq_level_t));
-        break;
-
     case HVMOP_inject_msi:
         rc = hvmop_inject_msi(
             guest_handle_cast(arg, xen_hvm_inject_msi_t));
--- a/xen/include/public/hvm/control.h
+++ b/xen/include/public/hvm/control.h
@@ -38,14 +38,25 @@ struct xen_hvm_set_pci_intx_level {
     uint8_t level;
 };
 
+/* XEN_HVMCTL_set_isa_irq_level */
+/* Set the logical level of one of a domain's ISA IRQ wires. */
+struct xen_hvm_set_isa_irq_level {
+    /* ISA device identification, by ISA IRQ (0-15). */
+    uint8_t  isa_irq;
+    /* Assertion level (0 = unasserted, 1 = asserted). */
+    uint8_t  level;
+};
+
 struct xen_hvmctl {
     uint16_t interface_version;    /* XEN_HVMCTL_INTERFACE_VERSION */
     domid_t domain;
     uint32_t cmd;
 #define XEN_HVMCTL_set_pci_intx_level            1
+#define XEN_HVMCTL_set_isa_irq_level             2
     uint64_t opaque;               /* Must be zero on initial invocation. */
     union {
         struct xen_hvm_set_pci_intx_level set_pci_intx_level;
+        struct xen_hvm_set_isa_irq_level set_isa_irq_level;
         uint8_t pad[120];
     } u;
 };
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -53,8 +53,6 @@ struct xen_hvm_set_pci_intx_level {
 typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t;
 DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t);
 
-#endif
-
 /* Set the logical level of one of a domain's ISA IRQ wires. */
 #define HVMOP_set_isa_irq_level   3
 struct xen_hvm_set_isa_irq_level {
@@ -68,6 +66,8 @@ struct xen_hvm_set_isa_irq_level {
 typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t;
 DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t);
 
+#endif
+
 #define HVMOP_set_pci_link_route  4
 struct xen_hvm_set_pci_link_route {
     /* Domain to be updated. */
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -609,12 +609,6 @@ static XSM_INLINE int xsm_shadow_control
     return xsm_default_action(action, current->domain, d);
 }
 
-static XSM_INLINE int xsm_hvm_set_isa_irq_level(XSM_DEFAULT_ARG struct domain *d)
-{
-    XSM_ASSERT_ACTION(XSM_DM_PRIV);
-    return xsm_default_action(action, current->domain, d);
-}
-
 static XSM_INLINE int xsm_hvm_set_pci_link_route(XSM_DEFAULT_ARG struct domain *d)
 {
     XSM_ASSERT_ACTION(XSM_DM_PRIV);
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -173,7 +173,6 @@ struct xsm_operations {
 #ifdef CONFIG_X86
     int (*do_mca) (void);
     int (*shadow_control) (struct domain *d, uint32_t op);
-    int (*hvm_set_isa_irq_level) (struct domain *d);
     int (*hvm_set_pci_link_route) (struct domain *d);
     int (*hvm_inject_msi) (struct domain *d);
     int (*hvm_ioreq_server) (struct domain *d, int op);
@@ -645,11 +644,6 @@ static inline int xsm_shadow_control (xs
     return xsm_ops->shadow_control(d, op);
 }
 
-static inline int xsm_hvm_set_isa_irq_level (xsm_default_t def, struct domain *d)
-{
-    return xsm_ops->hvm_set_isa_irq_level(d);
-}
-
 static inline int xsm_hvm_set_pci_link_route (xsm_default_t def, struct domain *d)
 {
     return xsm_ops->hvm_set_pci_link_route(d);
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -145,7 +145,6 @@ void xsm_fixup_ops (struct xsm_operation
 #ifdef CONFIG_X86
     set_to_dummy_if_null(ops, do_mca);
     set_to_dummy_if_null(ops, shadow_control);
-    set_to_dummy_if_null(ops, hvm_set_isa_irq_level);
     set_to_dummy_if_null(ops, hvm_set_pci_link_route);
     set_to_dummy_if_null(ops, hvm_inject_msi);
     set_to_dummy_if_null(ops, hvm_ioreq_server);
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1193,6 +1193,9 @@ static int flask_hvm_control(struct doma
     case XEN_HVMCTL_set_pci_intx_level:
         perm = HVM__PCILEVEL;
         break;
+    case XEN_HVMCTL_set_isa_irq_level:
+        perm = HVM__IRQLEVEL;
+        break;
     default:
         perm = HVM__HVMCTL;
         break;
@@ -1517,11 +1520,6 @@ static int flask_ioport_mapping(struct d
     return flask_ioport_permission(d, start, end, access);
 }
 
-static int flask_hvm_set_isa_irq_level(struct domain *d)
-{
-    return current_has_perm(d, SECCLASS_HVM, HVM__IRQLEVEL);
-}
-
 static int flask_hvm_set_pci_link_route(struct domain *d)
 {
     return current_has_perm(d, SECCLASS_HVM, HVM__PCIROUTE);
@@ -1805,7 +1803,6 @@ static struct xsm_operations flask_ops =
 #ifdef CONFIG_X86
     .do_mca = flask_do_mca,
     .shadow_control = flask_shadow_control,
-    .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level,
     .hvm_set_pci_link_route = flask_hvm_set_pci_link_route,
     .hvm_inject_msi = flask_hvm_inject_msi,
     .hvm_ioreq_server = flask_hvm_ioreq_server,
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -263,7 +263,7 @@ class hvm
     getparam
 # XEN_HVMCTL_set_pci_intx_level
     pcilevel
-# HVMOP_set_isa_irq_level
+# XEN_HVMCTL_set_isa_irq_level
     irqlevel
 # HVMOP_set_pci_link_route
     pciroute
