[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] domctl support for generic memory event handling.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1261031275 0 # Node ID 66e29f42247a2f5342d6b748c1e026ebf5dba74e # Parent a1ab94c514b80b3f0845465752ed72cfe4fafa73 domctl support for generic memory event handling. Signed-off-by: Patrick Colp <Patrick.Colp@xxxxxxxxxx> --- xen/arch/x86/domctl.c | 18 +++++++ xen/arch/x86/mm/mem_event.c | 91 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/mem_event.h | 3 + xen/include/public/domctl.h | 26 +++++++++++ 4 files changed, 138 insertions(+) diff -r a1ab94c514b8 -r 66e29f42247a xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Thu Dec 17 06:27:55 2009 +0000 +++ b/xen/arch/x86/domctl.c Thu Dec 17 06:27:55 2009 +0000 @@ -30,6 +30,8 @@ #include <asm/hypercall.h> /* for arch_do_domctl */ #include <xsm/xsm.h> #include <xen/iommu.h> +#include <asm/mem_event.h> +#include <public/mem_event.h> #ifdef XEN_GDBSX_CONFIG #ifdef XEN_KDB_CONFIG @@ -1299,6 +1301,22 @@ long arch_do_domctl( break; #endif /* XEN_GDBSX_CONFIG */ + case XEN_DOMCTL_mem_event_op: + { + struct domain *d; + + ret = -ESRCH; + d = rcu_lock_domain_by_id(domctl->domain); + if ( d != NULL ) + { + ret = mem_event_domctl(d, &domctl->u.mem_event_op, + guest_handle_cast(u_domctl, void)); + rcu_unlock_domain(d); + copy_to_guest(u_domctl, domctl, 1); + } + } + break; + default: ret = -ENOSYS; break; diff -r a1ab94c514b8 -r 66e29f42247a xen/arch/x86/mm/mem_event.c --- a/xen/arch/x86/mm/mem_event.c Thu Dec 17 06:27:55 2009 +0000 +++ b/xen/arch/x86/mm/mem_event.c Thu Dec 17 06:27:55 2009 +0000 @@ -188,6 +188,97 @@ int mem_event_check_ring(struct domain * return ring_full; } +int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, + XEN_GUEST_HANDLE(void) u_domctl) +{ + int rc; + + if ( unlikely(d == current->domain) ) + { + gdprintk(XENLOG_INFO, "Tried to do a memory paging op on itself.\n"); + return -EINVAL; + } + + if ( unlikely(d->is_dying) ) + { + gdprintk(XENLOG_INFO, "Ignoring memory paging op on dying domain %u\n", + d->domain_id); + return 0; + } + + if ( unlikely(d->vcpu == NULL) || unlikely(d->vcpu[0] == NULL) ) + { + MEM_EVENT_ERROR("Memory paging op on a domain (%u) with no vcpus\n", + d->domain_id); + return -EINVAL; + } + + /* TODO: XSM hook */ +#if 0 + rc = xsm_mem_event_control(d, mec->op); + if ( rc ) + return rc; +#endif + + if ( mec->mode == 0 ) + { + switch( mec->op ) + { + case XEN_DOMCTL_MEM_EVENT_OP_ENABLE: + { + struct domain *dom_mem_event = current->domain; + struct vcpu *v = current; + unsigned long ring_addr = mec->ring_addr; + unsigned long shared_addr = mec->shared_addr; + l1_pgentry_t l1e; + unsigned long gfn; + p2m_type_t p2mt; + mfn_t ring_mfn; + mfn_t shared_mfn; + + /* Get MFN of ring page */ + guest_get_eff_l1e(v, ring_addr, &l1e); + gfn = l1e_get_pfn(l1e); + ring_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt); + + rc = -EINVAL; + if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) ) + break; + + /* Get MFN of shared page */ + guest_get_eff_l1e(v, shared_addr, &l1e); + gfn = l1e_get_pfn(l1e); + shared_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt); + + rc = -EINVAL; + if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) ) + break; + + rc = -EINVAL; + if ( mem_event_enable(d, ring_mfn, shared_mfn) != 0 ) + break; + + rc = 0; + } + break; + + case XEN_DOMCTL_MEM_EVENT_OP_DISABLE: + { + rc = mem_event_disable(d); + } + break; + + default: + rc = -ENOSYS; + break; + } + } + else + rc = -ENOSYS; + + return rc; +} + /* * Local variables: diff -r a1ab94c514b8 -r 66e29f42247a xen/include/asm-x86/mem_event.h --- a/xen/include/asm-x86/mem_event.h Thu Dec 17 06:27:55 2009 +0000 +++ b/xen/include/asm-x86/mem_event.h Thu Dec 17 06:27:55 2009 +0000 @@ -54,6 +54,9 @@ void mem_event_get_response(struct domai void mem_event_get_response(struct domain *d, mem_event_response_t *rsp); void mem_event_unpause_vcpus(struct domain *d); +int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, + XEN_GUEST_HANDLE(void) u_domctl); + #endif /* __MEM_EVENT_H__ */ diff -r a1ab94c514b8 -r 66e29f42247a xen/include/public/domctl.h --- a/xen/include/public/domctl.h Thu Dec 17 06:27:55 2009 +0000 +++ b/xen/include/public/domctl.h Thu Dec 17 06:27:55 2009 +0000 @@ -690,6 +690,31 @@ struct xen_domctl_gdbsx_domstatus { uint32_t vcpu_ev; /* if yes, what event? */ }; + +/* + * Memory event operations + */ + +#define XEN_DOMCTL_mem_event_op 56 + +/* Add and remove memory handlers */ +#define XEN_DOMCTL_MEM_EVENT_OP_ENABLE 0 +#define XEN_DOMCTL_MEM_EVENT_OP_DISABLE 1 + +struct xen_domctl_mem_event_op { + uint32_t op; /* XEN_DOMCTL_MEM_EVENT_OP_* */ + uint32_t mode; /* XEN_DOMCTL_MEM_EVENT_ENABLE_* */ + + /* OP_ENABLE */ + unsigned long shared_addr; /* IN: Virtual address of shared page */ + unsigned long ring_addr; /* IN: Virtual address of ring page */ + + /* Other OPs */ + unsigned long gfn; /* IN: gfn of page being operated on */ +}; +typedef struct xen_domctl_mem_event_op xen_domctl_mem_event_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_event_op_t); + struct xen_domctl { uint32_t cmd; @@ -734,6 +759,7 @@ struct xen_domctl { struct xen_domctl_set_target set_target; struct xen_domctl_subscribe subscribe; struct xen_domctl_debug_op debug_op; + struct xen_domctl_mem_event_op mem_event_op; #if defined(__i386__) || defined(__x86_64__) struct xen_domctl_cpuid cpuid; #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |