return rc;
}
-static inline int mem_sharing_control(struct domain *d, bool enable)
+static inline int mem_sharing_control(struct domain *d, bool enable,
+ uint16_t flags)
{
if ( enable )
{
if ( unlikely(!hap_enabled(d)) )
return -ENODEV;
- if ( unlikely(is_iommu_enabled(d)) )
+ if ( unlikely(is_iommu_enabled(d) &&
+ !(flags & XENMEM_FORK_WITH_IOMMU_ALLOWED)) )
return -EXDEV;
}
if ( rc )
goto out;
- if ( !mem_sharing_enabled(d) && (rc = mem_sharing_control(d, true)) )
+ if ( !mem_sharing_enabled(d) &&
+ (rc = mem_sharing_control(d, true, 0)) )
return rc;
switch ( mso.op )
struct domain *pd;
rc = -EINVAL;
- if ( mso.u.fork.pad[0] || mso.u.fork.pad[1] || mso.u.fork.pad[2] )
+ if ( mso.u.fork.pad )
+ goto out;
+ if ( mso.u.fork.flags & ~XENMEM_FORK_WITH_IOMMU_ALLOWED )
goto out;
rc = rcu_lock_live_remote_domain_by_id(mso.u.fork.parent_domain,
goto out;
}
- if ( !mem_sharing_enabled(pd) && (rc = mem_sharing_control(pd, true)) )
+ if ( !mem_sharing_enabled(pd) &&
+ (rc = mem_sharing_control(pd, true, mso.u.fork.flags)) )
{
rcu_unlock_domain(pd);
goto out;
struct domain *pd;
rc = -EINVAL;
- if ( mso.u.fork.pad[0] || mso.u.fork.pad[1] || mso.u.fork.pad[2] )
+ if ( mso.u.fork.pad || mso.u.fork.flags )
goto out;
rc = -ENOSYS;
switch ( mec->op )
{
case XEN_DOMCTL_MEM_SHARING_CONTROL:
- rc = mem_sharing_control(d, mec->u.enable);
+ rc = mem_sharing_control(d, mec->u.enable, 0);
break;
default:
} debug;
struct mem_sharing_op_fork { /* OP_FORK */
domid_t parent_domain; /* IN: parent's domain id */
- uint16_t pad[3]; /* Must be set to 0 */
+#define XENMEM_FORK_WITH_IOMMU_ALLOWED (1u << 0)
+ uint16_t flags; /* IN: optional settings */
+ uint32_t pad; /* Must be set to 0 */
} fork;
} u;
};