mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: Implement hypercall DOMCTL_{, un}bind_pt_pirq
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>
This commit is contained in:
1 parent
28e8ad25bb
commit
b49a7517bb
8 files changed
+213
-65
No files matched your search
@@ -2124,6 +2124,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);
|
||||
|
||||
+57
-3
@@ -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,
|
||||
@@ -1847,6 +1851,21 @@ int xc_domain_unbind_pt_irq(
|
||||
uint8_t device,
|
||||
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;
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
+12
-12
@@ -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);
|
||||
|
||||
+14
-14
@@ -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);
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+36
-34
@@ -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:
|
||||
@@ -913,6 +915,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 */
|
||||
@@ -1484,36 +1516,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);
|
||||
@@ -1572,6 +1574,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,
|
||||
@@ -1641,8 +1645,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
|
||||
|
||||