diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index da7d142ad8..c39e56f5b9 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -1400,6 +1400,24 @@ static int range_share(struct domain *d, struct domain *cd, return rc; } +static inline int mem_sharing_control(struct domain *d, bool enable) +{ + if ( enable ) + { + if ( unlikely(!is_hvm_domain(d)) ) + return -EOPNOTSUPP; + + if ( unlikely(!hap_enabled(d)) ) + return -ENODEV; + + if ( unlikely(is_iommu_enabled(d)) ) + return -EXDEV; + } + + d->arch.hvm.mem_sharing.enabled = enable; + return 0; +} + int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) { int rc; @@ -1421,10 +1439,8 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) if ( rc ) goto out; - /* Only HAP is supported */ - rc = -ENODEV; - if ( !mem_sharing_enabled(d) ) - goto out; + if ( !mem_sharing_enabled(d) && (rc = mem_sharing_control(d, true)) ) + return rc; switch ( mso.op ) { @@ -1432,10 +1448,6 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) { shr_handle_t handle; - rc = -EINVAL; - if ( !mem_sharing_enabled(d) ) - goto out; - rc = nominate_page(d, _gfn(mso.u.nominate.u.gfn), 0, &handle); mso.u.nominate.handle = handle; } @@ -1447,9 +1459,6 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) gfn_t gfn; shr_handle_t handle; - rc = -EINVAL; - if ( !mem_sharing_enabled(d) ) - goto out; rc = mem_sharing_gref_to_gfn(d->grant_table, gref, &gfn, NULL); if ( rc < 0 ) goto out; @@ -1465,10 +1474,6 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) struct domain *cd; shr_handle_t sh, ch; - rc = -EINVAL; - if ( !mem_sharing_enabled(d) ) - goto out; - rc = rcu_lock_live_remote_domain_by_id(mso.u.share.client_domain, &cd); if ( rc ) @@ -1535,10 +1540,6 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) struct domain *cd; shr_handle_t sh; - rc = -EINVAL; - if ( !mem_sharing_enabled(d) ) - goto out; - rc = rcu_lock_live_remote_domain_by_id(mso.u.share.client_domain, &cd); if ( rc ) @@ -1597,9 +1598,6 @@ int mem_sharing_memop(XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) mso.u.range.opaque > mso.u.range.last_gfn) ) goto out; - if ( !mem_sharing_enabled(d) ) - goto out; - rc = rcu_lock_live_remote_domain_by_id(mso.u.range.client_domain, &cd); if ( rc ) @@ -1691,18 +1689,10 @@ int mem_sharing_domctl(struct domain *d, struct xen_domctl_mem_sharing_op *mec) { int rc; - /* Only HAP is supported */ - if ( !hap_enabled(d) ) - return -ENODEV; - switch ( mec->op ) { case XEN_DOMCTL_MEM_SHARING_CONTROL: - rc = 0; - if ( unlikely(is_iommu_enabled(d) && mec->u.enable) ) - rc = -EXDEV; - else - d->arch.hvm.mem_sharing_enabled = mec->u.enable; + rc = mem_sharing_control(d, mec->u.enable); break; default: