diff mbox

[Xen-devel,v6,04/19] xen/arm: Implement hypercall DOMCTL_{, un}bind_pt_pirq

Message ID 1430231563-25648-5-git-send-email-julien.grall@citrix.com
State New
Headers show

Commit Message

Julien Grall April 28, 2015, 2:32 p.m. UTC
From: Julien Grall <julien.grall@linaro.org>

On x86, an IRQ is assigned in 2 steps to an HVM guest:
    - The toolstack is calling PHYSDEVOP_map_pirq in order to create a
    guest PIRQ (IRQ bound to an event channel)
    - The emulator (QEMU) is calling DOMCTL_bind_pt_irq in order to
    bind the IRQ

On ARM, there is no concept of PIRQ as the IRQ can be assigned to a
virtual IRQ using the interrupt controller.

It's not clear if we will need 2 different hypercalls on ARM to assign
IRQ and, for now, only the toolstack will manage IRQ.

In order to avoid re-using a fixed ABI hypercall (PHYSDEVOP_*) for a
different purpose and allow us more time to figure out the right out,
only DOMCTL_{,un}bind_pt_pirq is implemented on ARM.

The DOMCTL is extended with a new type PT_IRQ_TYPE_SPI and only IRQ ==
vIRQ (i.e machine_irq == spi) is supported.

In order to keep the same XSM checks done by the 2 hypercalls on x86,
call both xsm_map_domain_irq & xsm_bind_pt_irq in the ARM implementation.

Note: The toolstack changes for routing an IRQ to a guest will be done
in a separate patch.

Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Cc: Jan Beulich <jbeulich@suse.com>

---
    Contrawise PHYSDEV, DOMCTL interface is not fixed. This version is
    using a DOMCTL in order to let us more to to see if we need a new
    PHYSDEV op for vIRQ assignation.

    DOMCTL_unbind_pt_irq has been implemented, although I haven't test
    it. I'm not sure if we want to keep it.

    xc_domain_{,un}bind_pt_irq are left unchanged because QEMU upstream
    & traditional are using them. I will send a follow-up series to drop this 2
    functions in order to avoid defering this series while awaiting
    changes pushed for QEMU upstream.

    Changes in v6:
        - Rebase on the latest staging (conflict in xsm/flask/hooks.c
          with memaccess changes)
        - Remove obsolete paragraph in the commit message
        - Fix indentation in libxc
        - Don't rely on vspi == spi in xc_domain_{,un}bind_pt_spi_irq
        - Typoes in comment
        - Add Daniel's ack (XSM part)

    Changes in v5:
        - Do the check of XSM PHYSDEVOP_map_pirq in the ARM implementation
        - Left xc_domain_{,un}bind_pt_irq unchanged
        - Introduce xc_domain_{,un}bind_pt_spi_irq

    Changes in v4:
        - Move the implementation from PHYSDEV to DOMCTL. Reuse
        DOMCTL_{,un}bind_pt_irq for this purpose.

    Changes in v3:
        - Functions to allocate/release/reserved a VIRQ has been moved
        in a separate patch
        - Make clear that only MAP_PIRQ_GSI is only supported for now

    Changes in v2:
        - Add PHYSDEVOP_unmap_pirq
        - Rework commit message
        - Add functions to allocate/release a VIRQ
        - is_routable_irq has been renamed into is_assignable_irq
---
 tools/libxc/include/xenctrl.h | 10 ++++++
 tools/libxc/xc_domain.c       | 60 +++++++++++++++++++++++++++++++--
 xen/arch/arm/domctl.c         | 78 +++++++++++++++++++++++++++++++++++++++++++
 xen/include/public/domctl.h   |  4 +++
 xen/include/xsm/dummy.h       | 24 ++++++-------
 xen/include/xsm/xsm.h         | 28 ++++++++--------
 xen/xsm/dummy.c               |  4 +--
 xen/xsm/flask/hooks.c         | 70 +++++++++++++++++++-------------------
 8 files changed, 213 insertions(+), 65 deletions(-)
diff mbox

Patch

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 6994c51..517a25f 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2115,6 +2115,16 @@  int xc_domain_bind_pt_isa_irq(xc_interface *xch,
                               uint32_t domid,
                               uint8_t machine_irq);
 
+int xc_domain_bind_pt_spi_irq(xc_interface *xch,
+                              uint32_t domid,
+                              uint16_t vspi,
+                              uint16_t spi);
+
+int xc_domain_unbind_pt_spi_irq(xc_interface *xch,
+                                uint32_t domid,
+                                uint16_t vspi,
+                                uint16_t spi);
+
 int xc_domain_set_machine_address_size(xc_interface *xch,
 				       uint32_t domid,
 				       unsigned int width);
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index d1dec6c..3ca9215 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1797,7 +1797,7 @@  int xc_domain_unbind_msi_irq(
 }
 
 /* Pass-through: binds machine irq to guests irq */
-int xc_domain_bind_pt_irq(
+static int xc_domain_bind_pt_irq_int(
     xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq,
@@ -1805,7 +1805,8 @@  int xc_domain_bind_pt_irq(
     uint8_t bus,
     uint8_t device,
     uint8_t intx,
-    uint8_t isa_irq)
+    uint8_t isa_irq,
+    uint16_t spi)
 {
     int rc;
     xen_domctl_bind_pt_irq_t * bind;
@@ -1829,6 +1830,9 @@  int xc_domain_bind_pt_irq(
     case PT_IRQ_TYPE_ISA:
         bind->u.isa.isa_irq = isa_irq;
         break;
+    case PT_IRQ_TYPE_SPI:
+        bind->u.spi.spi = spi;
+        break;
     default:
         errno = EINVAL;
         return -1;
@@ -1838,7 +1842,7 @@  int xc_domain_bind_pt_irq(
     return rc;
 }
 
-int xc_domain_unbind_pt_irq(
+int xc_domain_bind_pt_irq(
     xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq,
@@ -1848,6 +1852,21 @@  int xc_domain_unbind_pt_irq(
     uint8_t intx,
     uint8_t isa_irq)
 {
+    return xc_domain_bind_pt_irq_int(xch, domid, machine_irq, irq_type,
+                                     bus, device, intx, isa_irq, 0);
+}
+
+static int xc_domain_unbind_pt_irq_int(
+    xc_interface *xch,
+    uint32_t domid,
+    uint8_t machine_irq,
+    uint8_t irq_type,
+    uint8_t bus,
+    uint8_t device,
+    uint8_t intx,
+    uint8_t isa_irq,
+    uint8_t spi)
+{
     int rc;
     xen_domctl_bind_pt_irq_t * bind;
     DECLARE_DOMCTL;
@@ -1870,6 +1889,8 @@  int xc_domain_unbind_pt_irq(
     case PT_IRQ_TYPE_ISA:
         bind->u.isa.isa_irq = isa_irq;
         break;
+    case PT_IRQ_TYPE_SPI:
+        bind->u.spi.spi = spi;
     default:
         errno = EINVAL;
         return -1;
@@ -1879,6 +1900,20 @@  int xc_domain_unbind_pt_irq(
     return rc;
 }
 
+int xc_domain_unbind_pt_irq(
+    xc_interface *xch,
+    uint32_t domid,
+    uint8_t machine_irq,
+    uint8_t irq_type,
+    uint8_t bus,
+    uint8_t device,
+    uint8_t intx,
+    uint8_t isa_irq)
+{
+    return xc_domain_unbind_pt_irq_int(xch, domid, machine_irq, irq_type,
+                                       bus, device, intx, isa_irq, 0);
+}
+
 int xc_domain_bind_pt_pci_irq(
     xc_interface *xch,
     uint32_t domid,
@@ -1902,6 +1937,25 @@  int xc_domain_bind_pt_isa_irq(
                                   PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
 }
 
+int xc_domain_bind_pt_spi_irq(
+    xc_interface *xch,
+    uint32_t domid,
+    uint16_t vspi,
+    uint16_t spi)
+{
+    return (xc_domain_bind_pt_irq_int(xch, domid, vspi,
+                                      PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi));
+}
+
+int xc_domain_unbind_pt_spi_irq(xc_interface *xch,
+                                uint32_t domid,
+                                uint16_t vspi,
+                                uint16_t spi)
+{
+    return (xc_domain_unbind_pt_irq_int(xch, domid, vspi,
+                                        PT_IRQ_TYPE_SPI, 0, 0, 0, 0, spi));
+}
+
 int xc_unmap_domain_meminfo(xc_interface *xch, struct xc_domain_meminfo *minfo)
 {
     struct domain_info_context _di = { .guest_width = minfo->guest_width,
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 6f30af7..4600019 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -10,6 +10,8 @@ 
 #include <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/hypercall.h>
+#include <xen/iocap.h>
+#include <xsm/xsm.h>
 #include <public/domctl.h>
 
 long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
@@ -30,6 +32,82 @@  long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
 
         return p2m_cache_flush(d, s, e);
     }
+    case XEN_DOMCTL_bind_pt_irq:
+    {
+        int rc;
+        xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq;
+        uint32_t irq = bind->u.spi.spi;
+        uint32_t virq = bind->machine_irq;
+
+        /* We only support PT_IRQ_TYPE_SPI */
+        if ( bind->irq_type != PT_IRQ_TYPE_SPI )
+            return -EOPNOTSUPP;
+
+        /*
+         * XXX: For now map the interrupt 1:1. Other support will require to
+         * modify domain_pirq_to_irq macro.
+         */
+        if ( irq != virq )
+            return -EINVAL;
+
+        /*
+         * ARM doesn't require separating IRQ assignation into 2
+         * hypercalls (PHYSDEVOP_map_pirq and DOMCTL_bind_pt_irq).
+         *
+         * Call xsm_map_domain_irq in order to keep the same XSM checks
+         * done by the 2 hypercalls for consistency with other
+         * architectures.
+         */
+        rc = xsm_map_domain_irq(XSM_HOOK, d, irq, NULL);
+        if ( rc )
+            return rc;
+
+        rc = xsm_bind_pt_irq(XSM_HOOK, d, bind);
+        if ( rc )
+            return rc;
+
+        if ( !irq_access_permitted(current->domain, irq) )
+            return -EPERM;
+
+        if ( !vgic_reserve_virq(d, virq) )
+            return -EBUSY;
+
+        rc = route_irq_to_guest(d, virq, irq, "routed IRQ");
+        if ( rc )
+            vgic_free_virq(d, virq);
+
+        return rc;
+    }
+    case XEN_DOMCTL_unbind_pt_irq:
+    {
+        int rc;
+        xen_domctl_bind_pt_irq_t *bind = &domctl->u.bind_pt_irq;
+        uint32_t irq = bind->u.spi.spi;
+        uint32_t virq = bind->machine_irq;
+
+        /* We only support PT_IRQ_TYPE_SPI */
+        if ( bind->irq_type != PT_IRQ_TYPE_SPI )
+            return -EOPNOTSUPP;
+
+        /* For now map the interrupt 1:1 */
+        if ( irq != virq )
+            return -EINVAL;
+
+        rc = xsm_unbind_pt_irq(XSM_HOOK, d, bind);
+        if ( rc )
+            return rc;
+
+        if ( !irq_access_permitted(current->domain, irq) )
+            return -EPERM;
+
+        rc = release_guest_irq(d, virq);
+        if ( rc )
+            return rc;
+
+        vgic_free_virq(d, virq);
+
+        return 0;
+    }
     default:
         return subarch_do_domctl(domctl, d, u_domctl);
     }
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 10b51ef..35ed4f2 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -504,6 +504,7 @@  typedef enum pt_irq_type_e {
     PT_IRQ_TYPE_ISA,
     PT_IRQ_TYPE_MSI,
     PT_IRQ_TYPE_MSI_TRANSLATE,
+    PT_IRQ_TYPE_SPI,    /* ARM: valid range 32-1019 */
 } pt_irq_type_t;
 struct xen_domctl_bind_pt_irq {
     uint32_t machine_irq;
@@ -524,6 +525,9 @@  struct xen_domctl_bind_pt_irq {
             uint32_t gflags;
             uint64_aligned_t gtable;
         } msi;
+        struct {
+            uint16_t spi;
+        } spi;
     } u;
 };
 typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 16967ed..faeb096 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -445,6 +445,18 @@  static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
     return xsm_default_action(action, current->domain, d);
 }
 
+static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
+static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
+{
+    XSM_ASSERT_ACTION(XSM_HOOK);
+    return xsm_default_action(action, current->domain, d);
+}
+
 static XSM_INLINE int xsm_unmap_domain_irq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data)
 {
     XSM_ASSERT_ACTION(XSM_HOOK);
@@ -647,18 +659,6 @@  static XSM_INLINE int xsm_priv_mapping(XSM_DEFAULT_ARG struct domain *d, struct
     return xsm_default_action(action, d, t);
 }
 
-static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
-{
-    XSM_ASSERT_ACTION(XSM_HOOK);
-    return xsm_default_action(action, current->domain, d);
-}
-
-static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind)
-{
-    XSM_ASSERT_ACTION(XSM_HOOK);
-    return xsm_default_action(action, current->domain, d);
-}
-
 static XSM_INLINE int xsm_ioport_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
 {
     XSM_ASSERT_ACTION(XSM_HOOK);
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 49f06c9..bbd4a18 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -107,6 +107,8 @@  struct xsm_operations {
     int (*map_domain_irq) (struct domain *d, int irq, void *data);
     int (*unmap_domain_pirq) (struct domain *d);
     int (*unmap_domain_irq) (struct domain *d, int irq, void *data);
+    int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
+    int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
     int (*irq_permission) (struct domain *d, int pirq, uint8_t allow);
     int (*iomem_permission) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow);
     int (*iomem_mapping) (struct domain *d, uint64_t s, uint64_t e, uint8_t allow);
@@ -178,8 +180,6 @@  struct xsm_operations {
     int (*mmuext_op) (struct domain *d, struct domain *f);
     int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte);
     int (*priv_mapping) (struct domain *d, struct domain *t);
-    int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
-    int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind);
     int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow);
     int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow);
 #endif
@@ -428,6 +428,18 @@  static inline int xsm_unmap_domain_irq (xsm_default_t def, struct domain *d, int
     return xsm_ops->unmap_domain_irq(d, irq, data);
 }
 
+static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d,
+                                  struct xen_domctl_bind_pt_irq *bind)
+{
+    return xsm_ops->bind_pt_irq(d, bind);
+}
+
+static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d,
+                                    struct xen_domctl_bind_pt_irq *bind)
+{
+    return xsm_ops->unbind_pt_irq(d, bind);
+}
+
 static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int pirq, uint8_t allow)
 {
     return xsm_ops->irq_permission(d, pirq, allow);
@@ -666,18 +678,6 @@  static inline int xsm_priv_mapping(xsm_default_t def, struct domain *d, struct d
     return xsm_ops->priv_mapping(d, t);
 }
 
-static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d,
-                                                struct xen_domctl_bind_pt_irq *bind)
-{
-    return xsm_ops->bind_pt_irq(d, bind);
-}
-
-static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d,
-                                                struct xen_domctl_bind_pt_irq *bind)
-{
-    return xsm_ops->unbind_pt_irq(d, bind);
-}
-
 static inline int xsm_ioport_permission (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow)
 {
     return xsm_ops->ioport_permission(d, s, e, allow);
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 3ddb4f6..041ccf9 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -81,6 +81,8 @@  void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, map_domain_irq);
     set_to_dummy_if_null(ops, unmap_domain_pirq);
     set_to_dummy_if_null(ops, unmap_domain_irq);
+    set_to_dummy_if_null(ops, bind_pt_irq);
+    set_to_dummy_if_null(ops, unbind_pt_irq);
     set_to_dummy_if_null(ops, irq_permission);
     set_to_dummy_if_null(ops, iomem_permission);
     set_to_dummy_if_null(ops, iomem_mapping);
@@ -149,8 +151,6 @@  void xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, mmuext_op);
     set_to_dummy_if_null(ops, update_va_mapping);
     set_to_dummy_if_null(ops, priv_mapping);
-    set_to_dummy_if_null(ops, bind_pt_irq);
-    set_to_dummy_if_null(ops, unbind_pt_irq);
     set_to_dummy_if_null(ops, ioport_permission);
     set_to_dummy_if_null(ops, ioport_mapping);
 #endif
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 6215001..29865d2 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -578,12 +578,14 @@  static int flask_domctl(struct domain *d, int cmd)
     case XEN_DOMCTL_memory_mapping:
     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:
     case XEN_DOMCTL_ioport_permission:
-    case XEN_DOMCTL_bind_pt_irq:
-    case XEN_DOMCTL_unbind_pt_irq:
     case XEN_DOMCTL_ioport_mapping:
     /* These have individual XSM hooks (drivers/passthrough/iommu.c) */
     case XEN_DOMCTL_get_device_group:
@@ -912,6 +914,36 @@  static int flask_unmap_domain_irq (struct domain *d, int irq, void *data)
     return rc;
 }
 
+static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind)
+{
+    u32 dsid, rsid;
+    int rc = -EPERM;
+    int irq;
+    struct avc_audit_data ad;
+
+    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
+    if ( rc )
+        return rc;
+
+    irq = domain_pirq_to_irq(d, bind->machine_irq);
+
+    rc = get_irq_sid(irq, &rsid, &ad);
+    if ( rc )
+        return rc;
+
+    rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
+    if ( rc )
+        return rc;
+
+    dsid = domain_sid(d);
+    return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
+}
+
+static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind)
+{
+    return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
+}
+
 static int flask_irq_permission (struct domain *d, int pirq, uint8_t access)
 {
     /* the PIRQ number is not useful; real IRQ is checked during mapping */
@@ -1483,36 +1515,6 @@  static int flask_priv_mapping(struct domain *d, struct domain *t)
 {
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__TARGET_HACK);
 }
-
-static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind)
-{
-    u32 dsid, rsid;
-    int rc = -EPERM;
-    int irq;
-    struct avc_audit_data ad;
-
-    rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
-    if ( rc )
-        return rc;
-
-    irq = domain_pirq_to_irq(d, bind->machine_irq);
-
-    rc = get_irq_sid(irq, &rsid, &ad);
-    if ( rc )
-        return rc;
-
-    rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad);
-    if ( rc )
-        return rc;
-
-    dsid = domain_sid(d);
-    return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad);
-}
-
-static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind)
-{
-    return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
-}
 #endif /* CONFIG_X86 */
 
 long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op);
@@ -1571,6 +1573,8 @@  static struct xsm_operations flask_ops = {
     .map_domain_irq = flask_map_domain_irq,
     .unmap_domain_pirq = flask_unmap_domain_pirq,
     .unmap_domain_irq = flask_unmap_domain_irq,
+    .bind_pt_irq = flask_bind_pt_irq,
+    .unbind_pt_irq = flask_unbind_pt_irq,
     .irq_permission = flask_irq_permission,
     .iomem_permission = flask_iomem_permission,
     .iomem_mapping = flask_iomem_mapping,
@@ -1640,8 +1644,6 @@  static struct xsm_operations flask_ops = {
     .mmuext_op = flask_mmuext_op,
     .update_va_mapping = flask_update_va_mapping,
     .priv_mapping = flask_priv_mapping,
-    .bind_pt_irq = flask_bind_pt_irq,
-    .unbind_pt_irq = flask_unbind_pt_irq,
     .ioport_permission = flask_ioport_permission,
     .ioport_mapping = flask_ioport_mapping,
 #endif