aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/mm/mem_event.c41
-rw-r--r--xen/include/public/domctl.h20
-rw-r--r--xen/include/xen/sched.h3
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)
{