diff options
-rw-r--r-- | xen/arch/x86/mm/mem_event.c | 41 | ||||
-rw-r--r-- | xen/include/public/domctl.h | 20 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 3 |
3 files changed, 63 insertions, 1 deletions
diff --git a/xen/arch/x86/mm/mem_event.c b/xen/arch/x86/mm/mem_event.c index b6dde8d0de..79cb44859a 100644 --- a/xen/arch/x86/mm/mem_event.c +++ b/xen/arch/x86/mm/mem_event.c @@ -431,6 +431,13 @@ static void mem_access_notification(struct vcpu *v, unsigned int port) p2m_mem_access_resume(v->domain); } +/* Registered with Xen-bound event channel for incoming notifications. */ +static void mem_sharing_notification(struct vcpu *v, unsigned int port) +{ + if ( likely(v->domain->mem_event->share.ring_page != NULL) ) + mem_sharing_sharing_resume(v->domain); +} + struct domain *get_mem_event_op_target(uint32_t domain, int *rc) { struct domain *d; @@ -598,6 +605,40 @@ int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, } break; + case XEN_DOMCTL_MEM_EVENT_OP_SHARING: + { + struct mem_event_domain *med = &d->mem_event->share; + rc = -EINVAL; + + switch( mec->op ) + { + case XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE: + { + rc = -ENODEV; + /* Only HAP is supported */ + if ( !hap_enabled(d) ) + break; + + rc = mem_event_enable(d, mec, med, _VPF_mem_sharing, + HVM_PARAM_SHARING_RING_PFN, + mem_sharing_notification); + } + break; + + case XEN_DOMCTL_MEM_EVENT_OP_SHARING_DISABLE: + { + if ( med->ring_page ) + rc = mem_event_disable(d, med); + } + break; + + default: + rc = -ENOSYS; + break; + } + } + break; + default: rc = -ENOSYS; } diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index a3ed8d76be..494520743d 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -711,7 +711,7 @@ struct xen_domctl_gdbsx_domstatus { /* XEN_DOMCTL_mem_event_op */ /* -* Domain memory paging + * Domain memory paging * Page memory in and out. * Domctl interface to set up and tear down the * pager<->hypervisor interface. Use XENMEM_paging_op* @@ -741,6 +741,24 @@ struct xen_domctl_gdbsx_domstatus { #define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE 0 #define XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE 1 +/* + * Sharing ENOMEM helper. + * + * As with paging, use the domctl for teardown/setup of the + * helper<->hypervisor interface. + * + * If setup, this ring is used to communicate failed allocations + * in the unshare path. XENMEM_sharing_op_resume is used to wake up + * vcpus that could not unshare. + * + * Note that shring can be turned on (as per the domctl below) + * *without* this ring being setup. + */ +#define XEN_DOMCTL_MEM_EVENT_OP_SHARING 3 + +#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE 0 +#define XEN_DOMCTL_MEM_EVENT_OP_SHARING_DISABLE 1 + /* Use for teardown/setup of helper<->hypervisor interface for paging, * access and sharing.*/ struct xen_domctl_mem_event_op { diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 65219cf988..53804c87d5 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -636,6 +636,9 @@ static inline struct domain *next_domain_in_cpupool( /* VCPU is blocked due to missing mem_access ring. */ #define _VPF_mem_access 5 #define VPF_mem_access (1UL<<_VPF_mem_access) + /* VCPU is blocked due to missing mem_sharing ring. */ +#define _VPF_mem_sharing 6 +#define VPF_mem_sharing (1UL<<_VPF_mem_sharing) static inline int vcpu_runnable(struct vcpu *v) { |