The memop handler function for paging/sharing responsible for calling XSM doesn't really have anything to do with vm_event, thus in this patch we relocate it into mem_paging_memop and mem_sharing_memop. This has already been the approach in mem_access_memop, so in this patch we just make it consistent.
Signed-off-by: Tamas K Lengyel <tamas.leng...@zentific.com> --- xen/arch/x86/mm/mem_paging.c | 36 ++++++++++++++----- xen/arch/x86/mm/mem_sharing.c | 76 ++++++++++++++++++++++++++------------- xen/arch/x86/x86_64/compat/mm.c | 28 +++------------ xen/arch/x86/x86_64/mm.c | 26 +++----------- xen/common/vm_event.c | 43 ---------------------- xen/include/asm-x86/mem_paging.h | 7 +++- xen/include/asm-x86/mem_sharing.h | 4 +-- xen/include/xen/vm_event.h | 1 - 8 files changed, 97 insertions(+), 124 deletions(-) diff --git a/xen/arch/x86/mm/mem_paging.c b/xen/arch/x86/mm/mem_paging.c index e63d8c1..4aee6b7 100644 --- a/xen/arch/x86/mm/mem_paging.c +++ b/xen/arch/x86/mm/mem_paging.c @@ -21,28 +21,45 @@ */ +#include <xen/guest_access.h> #include <asm/p2m.h> -#include <xen/vm_event.h> +#include <xsm/xsm.h> - -int mem_paging_memop(struct domain *d, xen_mem_paging_op_t *mpo) +int mem_paging_memop(unsigned long cmd, + XEN_GUEST_HANDLE_PARAM(xen_mem_paging_op_t) arg) { - int rc = -ENODEV; + int rc; + xen_mem_paging_op_t mpo; + struct domain *d; + + rc = -EFAULT; + if ( copy_from_guest(&mpo, arg, 1) ) + return rc; + + rc = rcu_lock_live_remote_domain_by_id(mpo.domain, &d); + if ( rc ) + return rc; + + rc = xsm_vm_event_op(XSM_DM_PRIV, d, XENMEM_paging_op); + if ( rc ) + return rc; + + rc = -ENODEV; if ( unlikely(!d->vm_event->paging.ring_page) ) return rc; - switch( mpo->op ) + switch( mpo.op ) { case XENMEM_paging_op_nominate: - rc = p2m_mem_paging_nominate(d, mpo->gfn); + rc = p2m_mem_paging_nominate(d, mpo.gfn); break; case XENMEM_paging_op_evict: - rc = p2m_mem_paging_evict(d, mpo->gfn); + rc = p2m_mem_paging_evict(d, mpo.gfn); break; case XENMEM_paging_op_prep: - rc = p2m_mem_paging_prep(d, mpo->gfn, mpo->buffer); + rc = p2m_mem_paging_prep(d, mpo.gfn, mpo.buffer); break; default: @@ -50,6 +67,9 @@ int mem_paging_memop(struct domain *d, xen_mem_paging_op_t *mpo) break; } + if ( !rc && __copy_to_guest(arg, &mpo, 1) ) + rc = -EFAULT; + return rc; } diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 4959407..612ed89 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -28,6 +28,7 @@ #include <xen/grant_table.h> #include <xen/sched.h> #include <xen/rcupdate.h> +#include <xen/guest_access.h> #include <xen/vm_event.h> #include <asm/page.h> #include <asm/string.h> @@ -1293,30 +1294,52 @@ int relinquish_shared_pages(struct domain *d) return rc; } -int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) +int mem_sharing_memop(unsigned long cmd, + XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg) { - int rc = 0; + int rc; + xen_mem_sharing_op_t mso; + struct domain *d; + + rc = -EFAULT; + if ( copy_from_guest(&mso, arg, 1) ) + return rc; + + if ( mso.op == XENMEM_sharing_op_audit ) + return mem_sharing_audit(); + + rc = rcu_lock_live_remote_domain_by_id(mso.domain, &d); + if ( rc ) + return rc; /* Only HAP is supported */ if ( !hap_enabled(d) || !d->arch.hvm_domain.mem_sharing_enabled ) return -ENODEV; - switch(mec->op) + rc = xsm_vm_event_op(XSM_DM_PRIV, d, XENMEM_sharing_op); + if ( rc ) + return rc; + + rc = -ENODEV; + if ( unlikely(!d->vm_event->share.ring_page) ) + return rc; + + switch(mso.op) { case XENMEM_sharing_op_nominate_gfn: { - unsigned long gfn = mec->u.nominate.u.gfn; + unsigned long gfn = mso.u.nominate.u.gfn; shr_handle_t handle; if ( !mem_sharing_enabled(d) ) return -EINVAL; rc = mem_sharing_nominate_page(d, gfn, 0, &handle); - mec->u.nominate.handle = handle; + mso.u.nominate.handle = handle; } break; case XENMEM_sharing_op_nominate_gref: { - grant_ref_t gref = mec->u.nominate.u.grant_ref; + grant_ref_t gref = mso.u.nominate.u.grant_ref; unsigned long gfn; shr_handle_t handle; @@ -1325,7 +1348,7 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( mem_sharing_gref_to_gfn(d, gref, &gfn) < 0 ) return -EINVAL; rc = mem_sharing_nominate_page(d, gfn, 3, &handle); - mec->u.nominate.handle = handle; + mso.u.nominate.handle = handle; } break; @@ -1338,12 +1361,12 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + rc = rcu_lock_live_remote_domain_by_id(mso.u.share.client_domain, &cd); if ( rc ) return rc; - rc = xsm_mem_sharing_op(XSM_DM_PRIV, d, cd, mec->op); + rc = xsm_mem_sharing_op(XSM_DM_PRIV, d, cd, mso.op); if ( rc ) { rcu_unlock_domain(cd); @@ -1356,36 +1379,36 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) return -EINVAL; } - if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mec->u.share.source_gfn) ) + if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mso.u.share.source_gfn) ) { grant_ref_t gref = (grant_ref_t) (XENMEM_SHARING_OP_FIELD_GET_GREF( - mec->u.share.source_gfn)); + mso.u.share.source_gfn)); if ( mem_sharing_gref_to_gfn(d, gref, &sgfn) < 0 ) { rcu_unlock_domain(cd); return -EINVAL; } } else { - sgfn = mec->u.share.source_gfn; + sgfn = mso.u.share.source_gfn; } - if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mec->u.share.client_gfn) ) + if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mso.u.share.client_gfn) ) { grant_ref_t gref = (grant_ref_t) (XENMEM_SHARING_OP_FIELD_GET_GREF( - mec->u.share.client_gfn)); + mso.u.share.client_gfn)); if ( mem_sharing_gref_to_gfn(cd, gref, &cgfn) < 0 ) { rcu_unlock_domain(cd); return -EINVAL; } } else { - cgfn = mec->u.share.client_gfn; + cgfn = mso.u.share.client_gfn; } - sh = mec->u.share.source_handle; - ch = mec->u.share.client_handle; + sh = mso.u.share.source_handle; + ch = mso.u.share.client_handle; rc = mem_sharing_share_pages(d, sgfn, sh, cd, cgfn, ch); @@ -1402,12 +1425,12 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) if ( !mem_sharing_enabled(d) ) return -EINVAL; - rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + rc = rcu_lock_live_remote_domain_by_id(mso.u.share.client_domain, &cd); if ( rc ) return rc; - rc = xsm_mem_sharing_op(XSM_DM_PRIV, d, cd, mec->op); + rc = xsm_mem_sharing_op(XSM_DM_PRIV, d, cd, mso.op); if ( rc ) { rcu_unlock_domain(cd); @@ -1420,16 +1443,16 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) return -EINVAL; } - if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mec->u.share.source_gfn) ) + if ( XENMEM_SHARING_OP_FIELD_IS_GREF(mso.u.share.source_gfn) ) { /* Cannot add a gref to the physmap */ rcu_unlock_domain(cd); return -EINVAL; } - sgfn = mec->u.share.source_gfn; - sh = mec->u.share.source_handle; - cgfn = mec->u.share.client_gfn; + sgfn = mso.u.share.source_gfn; + sh = mso.u.share.source_handle; + cgfn = mso.u.share.client_gfn; rc = mem_sharing_add_to_physmap(d, sgfn, sh, cd, cgfn); @@ -1448,14 +1471,14 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) case XENMEM_sharing_op_debug_gfn: { - unsigned long gfn = mec->u.debug.u.gfn; + unsigned long gfn = mso.u.debug.u.gfn; rc = mem_sharing_debug_gfn(d, gfn); } break; case XENMEM_sharing_op_debug_gref: { - grant_ref_t gref = mec->u.debug.u.gref; + grant_ref_t gref = mso.u.debug.u.gref; rc = mem_sharing_debug_gref(d, gref); } break; @@ -1465,6 +1488,9 @@ int mem_sharing_memop(struct domain *d, xen_mem_sharing_op_t *mec) break; } + if ( !rc && __copy_to_guest(arg, &mso, 1) ) + return -EFAULT; + return rc; } diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c index 85f138b..bb03870 100644 --- a/xen/arch/x86/x86_64/compat/mm.c +++ b/xen/arch/x86/x86_64/compat/mm.c @@ -1,9 +1,9 @@ #include <xen/event.h> -#include <xen/vm_event.h> #include <xen/mem_access.h> #include <xen/multicall.h> #include <compat/memory.h> #include <compat/xen.h> +#include <asm/mem_paging.h> #include <asm/mem_sharing.h> int compat_set_gdt(XEN_GUEST_HANDLE_PARAM(uint) frame_list, unsigned int entries) @@ -187,30 +187,12 @@ int compat_arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return mem_sharing_get_nr_shared_mfns(); case XENMEM_paging_op: - { - xen_mem_paging_op_t mpo; - - if ( copy_from_guest(&mpo, arg, 1) ) - return -EFAULT; - rc = do_vm_event_op(cmd, mpo.domain, &mpo); - if ( !rc && __copy_to_guest(arg, &mpo, 1) ) - return -EFAULT; - break; - } + return mem_paging_memop(cmd, + guest_handle_cast(arg, xen_mem_paging_op_t)); case XENMEM_sharing_op: - { - xen_mem_sharing_op_t mso; - - if ( copy_from_guest(&mso, arg, 1) ) - return -EFAULT; - if ( mso.op == XENMEM_sharing_op_audit ) - return mem_sharing_audit(); - rc = do_vm_event_op(cmd, mso.domain, &mso); - if ( !rc && __copy_to_guest(arg, &mso, 1) ) - return -EFAULT; - break; - } + return mem_sharing_memop(cmd, + guest_handle_cast(arg, xen_mem_sharing_op_t)); default: rc = -ENOSYS; diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 1e2bd1a..bdefe5c 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -26,7 +26,6 @@ #include <xen/nodemask.h> #include <xen/guest_access.h> #include <xen/hypercall.h> -#include <xen/vm_event.h> #include <xen/mem_access.h> #include <asm/current.h> #include <asm/asm_defns.h> @@ -37,6 +36,7 @@ #include <asm/msr.h> #include <asm/setup.h> #include <asm/numa.h> +#include <asm/mem_paging.h> #include <asm/mem_sharing.h> #include <public/memory.h> @@ -984,28 +984,12 @@ long subarch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return mem_sharing_get_nr_shared_mfns(); case XENMEM_paging_op: - { - xen_mem_paging_op_t mpo; - if ( copy_from_guest(&mpo, arg, 1) ) - return -EFAULT; - rc = do_vm_event_op(cmd, mpo.domain, &mpo); - if ( !rc && __copy_to_guest(arg, &mpo, 1) ) - return -EFAULT; - break; - } + return mem_paging_memop(cmd, + guest_handle_cast(arg, xen_mem_paging_op_t)); case XENMEM_sharing_op: - { - xen_mem_sharing_op_t mso; - if ( copy_from_guest(&mso, arg, 1) ) - return -EFAULT; - if ( mso.op == XENMEM_sharing_op_audit ) - return mem_sharing_audit(); - rc = do_vm_event_op(cmd, mso.domain, &mso); - if ( !rc && __copy_to_guest(arg, &mso, 1) ) - return -EFAULT; - break; - } + return mem_sharing_memop(cmd, + guest_handle_cast(arg, xen_mem_sharing_op_t)); default: rc = -ENOSYS; diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c index f89361e..2343ae5 100644 --- a/xen/common/vm_event.c +++ b/xen/common/vm_event.c @@ -27,15 +27,6 @@ #include <xen/vm_event.h> #include <xen/mem_access.h> #include <asm/p2m.h> - -#ifdef HAS_MEM_PAGING -#include <asm/mem_paging.h> -#endif - -#ifdef HAS_MEM_SHARING -#include <asm/mem_sharing.h> -#endif - #include <xsm/xsm.h> /* for public/io/ring.h macros */ @@ -517,40 +508,6 @@ static void mem_sharing_notification(struct vcpu *v, unsigned int port) } #endif -int do_vm_event_op(int op, uint32_t domain, void *arg) -{ - int ret; - struct domain *d; - - ret = rcu_lock_live_remote_domain_by_id(domain, &d); - if ( ret ) - return ret; - - ret = xsm_vm_event_op(XSM_DM_PRIV, d, op); - if ( ret ) - goto out; - - switch (op) - { -#ifdef HAS_MEM_PAGING - case XENMEM_paging_op: - ret = mem_paging_memop(d, arg); - break; -#endif -#ifdef HAS_MEM_SHARING - case XENMEM_sharing_op: - ret = mem_sharing_memop(d, arg); - break; -#endif - default: - ret = -ENOSYS; - } - - out: - rcu_unlock_domain(d); - return ret; -} - /* Clean up on domain destruction */ void vm_event_cleanup(struct domain *d) { diff --git a/xen/include/asm-x86/mem_paging.h b/xen/include/asm-x86/mem_paging.h index 92ed2fa..9d8bc67 100644 --- a/xen/include/asm-x86/mem_paging.h +++ b/xen/include/asm-x86/mem_paging.h @@ -20,8 +20,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef __MEM_PAGING_H__ +#define __MEM_PAGING_H__ -int mem_paging_memop(struct domain *d, xen_mem_paging_op_t *meo); +int mem_paging_memop(unsigned long cmd, + XEN_GUEST_HANDLE_PARAM(xen_mem_paging_op_t) arg); + +#endif /*__MEM_PAGING_H__ */ /* diff --git a/xen/include/asm-x86/mem_sharing.h b/xen/include/asm-x86/mem_sharing.h index da99d46..51d4364 100644 --- a/xen/include/asm-x86/mem_sharing.h +++ b/xen/include/asm-x86/mem_sharing.h @@ -90,8 +90,8 @@ static inline int mem_sharing_unshare_page(struct domain *d, */ int mem_sharing_notify_enomem(struct domain *d, unsigned long gfn, bool_t allow_sleep); -int mem_sharing_memop(struct domain *d, - xen_mem_sharing_op_t *mec); +int mem_sharing_memop(unsigned long cmd, + XEN_GUEST_HANDLE_PARAM(xen_mem_sharing_op_t) arg); int mem_sharing_domctl(struct domain *d, xen_domctl_mem_sharing_op_t *mec); int mem_sharing_audit(void); diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h index 82a6e56..871a519 100644 --- a/xen/include/xen/vm_event.h +++ b/xen/include/xen/vm_event.h @@ -69,7 +69,6 @@ int vm_event_get_response(struct domain *d, struct vm_event_domain *med, void vm_event_resume(struct domain *d, struct vm_event_domain *ved); -int do_vm_event_op(int op, uint32_t domain, void *arg); int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *mec, XEN_GUEST_HANDLE_PARAM(void) u_domctl); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel