return 0;
}
- ret = xsm_map_domain_pirq(XSM_HOOK, d, irq, data);
+ ret = xsm_map_domain_irq(XSM_HOOK, d, irq, data);
if ( ret )
{
dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d mapping to pirq %d\n",
goto done;
}
+ desc = irq_to_desc(irq);
+ msi_desc = desc->msi_desc;
+
+ ret = xsm_unmap_domain_irq(XSM_HOOK, d, irq, msi_desc);
+ if ( ret )
+ goto done;
+
forced_unbind = pirq_guest_force_unbind(d, info);
if ( forced_unbind )
dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
d->domain_id, pirq);
- desc = irq_to_desc(irq);
-
- if ( (msi_desc = desc->msi_desc) != NULL )
+ if ( msi_desc != NULL )
pci_disable_msi(msi_desc);
spin_lock_irqsave(&desc->lock, flags);
return physdev_hvm_map_pirq(d, type, index, pirq_p);
}
- ret = rcu_lock_target_domain_by_id(domid, &d);
+ d = rcu_lock_domain_by_any_id(domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ ret = xsm_map_domain_pirq(XSM_TARGET, d);
if ( ret )
return ret;
struct domain *d;
int ret;
- ret = rcu_lock_target_domain_by_id(domid, &d);
+ d = rcu_lock_domain_by_any_id(domid);
+ if ( d == NULL )
+ return -ESRCH;
+
+ ret = xsm_unmap_domain_pirq(XSM_TARGET, d);
if ( ret )
- return ret;
+ goto free_domain;
if ( is_hvm_domain(d) )
{
goto free_domain;
}
- ret = xsm_unmap_domain_pirq(XSM_TARGET, d, domain_pirq_to_irq(d, pirq));
- if ( ret )
- goto free_domain;
-
spin_lock(&pcidevs_lock);
spin_lock(&d->event_lock);
ret = unmap_domain_pirq(d, pirq);
return NULL;
}
-static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data)
+static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
+{
+ XSM_ASSERT_ACTION(XSM_TARGET);
+ return xsm_default_action(action, current->domain, d);
+}
+
+static XSM_INLINE int xsm_map_domain_irq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data)
{
XSM_ASSERT_ACTION(XSM_HOOK);
return xsm_default_action(action, current->domain, d);
}
-static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq)
+static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d)
{
XSM_ASSERT_ACTION(XSM_TARGET);
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);
+ return xsm_default_action(action, current->domain, d);
+}
+
static XSM_INLINE int xsm_irq_permission(XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow)
{
XSM_ASSERT_ACTION(XSM_HOOK);
int (*schedop_shutdown) (struct domain *d1, struct domain *d2);
char *(*show_irq_sid) (int irq);
- int (*map_domain_pirq) (struct domain *d, int irq, void *data);
- int (*unmap_domain_pirq) (struct domain *d, int irq);
+ int (*map_domain_pirq) (struct domain *d);
+ 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 (*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);
return xsm_ops->show_irq_sid(irq);
}
-static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d, int irq, void *data)
+static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d)
{
- return xsm_ops->map_domain_pirq(d, irq, data);
+ return xsm_ops->map_domain_pirq(d);
}
-static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d, int irq)
+static inline int xsm_map_domain_irq (xsm_default_t def, struct domain *d, int irq, void *data)
{
- return xsm_ops->unmap_domain_pirq(d, irq);
+ return xsm_ops->map_domain_irq(d, irq, data);
+}
+
+static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d)
+{
+ return xsm_ops->unmap_domain_pirq(d);
+}
+
+static inline int xsm_unmap_domain_irq (xsm_default_t def, struct domain *d, int irq, void *data)
+{
+ return xsm_ops->unmap_domain_irq(d, irq, data);
}
static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int pirq, uint8_t allow)
set_to_dummy_if_null(ops, show_irq_sid);
set_to_dummy_if_null(ops, map_domain_pirq);
+ 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, irq_permission);
set_to_dummy_if_null(ops, iomem_permission);
set_to_dummy_if_null(ops, iomem_mapping);
return ctx;
}
-static int flask_map_domain_pirq (struct domain *d, int irq, void *data)
+static int flask_map_domain_pirq (struct domain *d)
+{
+ return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
+}
+
+static int flask_map_domain_irq (struct domain *d, int irq, void *data)
{
u32 sid, dsid;
int rc = -EPERM;
struct msi_info *msi = data;
struct avc_audit_data ad;
- rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
-
- if ( rc )
- return rc;
-
if ( irq >= nr_static_irqs && msi ) {
u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
AVC_AUDIT_DATA_INIT(&ad, DEV);
return rc;
}
-static int flask_unmap_domain_pirq (struct domain *d, int irq)
+static int flask_unmap_domain_pirq (struct domain *d)
+{
+ return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
+}
+
+static int flask_unmap_domain_irq (struct domain *d, int irq, void *data)
{
u32 sid;
int rc = -EPERM;
+ struct msi_info *msi = data;
struct avc_audit_data ad;
- rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE);
- if ( rc )
- return rc;
-
- if ( irq < nr_static_irqs ) {
- rc = get_irq_sid(irq, &sid, &ad);
+ if ( irq >= nr_static_irqs && msi ) {
+ u32 machine_bdf = (msi->seg << 16) | (msi->bus << 8) | msi->devfn;
+ AVC_AUDIT_DATA_INIT(&ad, DEV);
+ ad.device = machine_bdf;
+ rc = security_device_sid(machine_bdf, &sid);
} else {
- /* It is currently not possible to check the specific MSI IRQ being
- * removed, since we do not have the msi_info like map_domain_pirq */
- return 0;
+ rc = get_irq_sid(irq, &sid, &ad);
}
if ( rc )
return rc;
.show_irq_sid = flask_show_irq_sid,
.map_domain_pirq = flask_map_domain_pirq,
+ .map_domain_irq = flask_map_domain_irq,
.unmap_domain_pirq = flask_unmap_domain_pirq,
+ .unmap_domain_irq = flask_unmap_domain_irq,
.irq_permission = flask_irq_permission,
.iomem_permission = flask_iomem_permission,
.iomem_mapping = flask_iomem_mapping,
# target = resource's security label
# also checked when using some core Xen devices (target xen_t)
use
-# PHYSDEVOP_map_pirq and ioapic writes for dom0
+# PHYSDEVOP_map_pirq and ioapic writes for dom0, when acting on real IRQs
# For GSI interrupts, the IRQ's label is indexed by the IRQ number
# For MSI interrupts, the label of the PCI device is used
add_irq
-# PHYSDEVOP_unmap_pirq:
-# This is currently only checked for GSI interrupts
+# PHYSDEVOP_unmap_pirq (same as map, and only for real IRQs)
remove_irq
# XEN_DOMCTL_ioport_permission, XEN_DOMCTL_ioport_mapping
add_ioport