# pmu_ctrl is for)
allow domain_type xen_t:xen2 pmu_use;
-# Allow all domains:
+# Allow all domains to enable the Argo interdomain communication hypercall;
# to register single-sender (unicast) rings to partner with any domain;
# to register any-sender (wildcard) rings that can be sent to by any domain;
# and send messages to rings.
-allow domain_type xen_t:argo { register_any_source };
+allow domain_type xen_t:argo { enable register_any_source };
allow domain_type domain_type:argo { send register_single_source };
# Allow guest console output to the serial console. This is used by PV Linux
if ( unlikely(!opt_argo) )
return -EOPNOTSUPP;
+ rc = xsm_argo_enable(currd);
+ if ( rc )
+ return rc;
+
switch ( cmd )
{
case XEN_ARGO_OP_register_ring:
if ( unlikely(!opt_argo) )
return -EOPNOTSUPP;
+ rc = xsm_argo_enable(currd);
+ if ( rc )
+ return rc;
+
argo_dprintk("->compat_argo_op(%u,%p,%p,%lu,0x%lx)\n", cmd,
(void *)arg1.p, (void *)arg2.p, arg3, arg4);
{
struct argo_domain *argo;
- if ( !opt_argo )
+ if ( !opt_argo || xsm_argo_enable(d) )
{
argo_dprintk("argo disabled, domid: %u\n", d->domain_id);
return 0;
wildcard_rings_pending_remove(d);
/*
- * Since opt_argo cannot change at runtime, if d->argo is true then
- * opt_argo must be true, and we can assume that init is allowed to
- * proceed again here.
+ * Since neither opt_argo or xsm_argo_enable(d) can change at runtime,
+ * if d->argo is true then both opt_argo and xsm_argo_enable(d) must be
+ * true, and we can assume that init is allowed to proceed again here.
*/
argo_domain_init(d->argo);
}
#endif /* CONFIG_X86 */
#ifdef CONFIG_ARGO
+static XSM_INLINE int xsm_argo_enable(const struct domain *d)
+{
+ return 0;
+}
+
static XSM_INLINE int xsm_argo_register_single_source(const struct domain *d,
const struct domain *t)
{
int (*xen_version) (uint32_t cmd);
int (*domain_resource_map) (struct domain *d);
#ifdef CONFIG_ARGO
+ int (*argo_enable) (const struct domain *d);
int (*argo_register_single_source) (const struct domain *d,
const struct domain *t);
int (*argo_register_any_source) (const struct domain *d);
}
#ifdef CONFIG_ARGO
+static inline int xsm_argo_enable(const struct domain *d)
+{
+ return xsm_ops->argo_enable(d);
+}
+
static inline int xsm_argo_register_single_source(const struct domain *d,
const struct domain *t)
{
set_to_dummy_if_null(ops, xen_version);
set_to_dummy_if_null(ops, domain_resource_map);
#ifdef CONFIG_ARGO
+ set_to_dummy_if_null(ops, argo_enable);
set_to_dummy_if_null(ops, argo_register_single_source);
set_to_dummy_if_null(ops, argo_register_any_source);
set_to_dummy_if_null(ops, argo_send);
}
#ifdef CONFIG_ARGO
+static int flask_argo_enable(const struct domain *d)
+{
+ return avc_has_perm(domain_sid(d), SECINITSID_XEN, SECCLASS_ARGO,
+ ARGO__ENABLE, NULL);
+}
+
static int flask_argo_register_single_source(const struct domain *d,
const struct domain *t)
{
.xen_version = flask_xen_version,
.domain_resource_map = flask_domain_resource_map,
#ifdef CONFIG_ARGO
+ .argo_enable = flask_argo_enable,
.argo_register_single_source = flask_argo_register_single_source,
.argo_register_any_source = flask_argo_register_any_source,
.argo_send = flask_argo_send,
# Class argo is used to describe the Argo interdomain communication system.
class argo
{
+ # Enable initialization of a domain's argo subsystem and
+ # permission to access the argo hypercall operations.
+ enable
# Domain requesting registration of a communication ring
# to receive messages from a specific other domain.
register_single_source