From patchwork Thu May 30 14:18:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petre Ovidiu PIRCALABU X-Patchwork-Id: 10968921 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2206B1575 for ; Thu, 30 May 2019 14:19:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 127D128917 for ; Thu, 30 May 2019 14:19:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0676E28B95; Thu, 30 May 2019 14:19:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id ED0A028BA3 for ; Thu, 30 May 2019 14:19:55 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hWLt1-000383-3u; Thu, 30 May 2019 14:18:31 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hWLsz-00036u-EZ for xen-devel@lists.xenproject.org; Thu, 30 May 2019 14:18:29 +0000 X-Inumbo-ID: c9cb4248-82e5-11e9-b1fc-1fb024e09d15 Received: from mx01.bbu.dsd.mx.bitdefender.com (unknown [91.199.104.161]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id c9cb4248-82e5-11e9-b1fc-1fb024e09d15; Thu, 30 May 2019 14:18:26 +0000 (UTC) Received: from smtp.bitdefender.com (smtp02.buh.bitdefender.net [10.17.80.76]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 2970F305FFA2; Thu, 30 May 2019 17:18:25 +0300 (EEST) Received: from bitdefender.com (unknown [195.189.155.70]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 097B93086D00; Thu, 30 May 2019 17:18:25 +0300 (EEST) From: Petre Pircalabu To: xen-devel@lists.xenproject.org Date: Thu, 30 May 2019 17:18:16 +0300 Message-Id: <9cde4926b56fa05afffee270e5e28a3b9bd830d9.1559224640.git.ppircalabu@bitdefender.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Subject: [Xen-devel] [PATCH 2/9] vm_event: Define VM_EVENT type X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Petre Pircalabu , Stefano Stabellini , Razvan Cojocaru , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Tamas K Lengyel , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Define the type for each of the supported vm_event rings (paging, monitor and sharing) and replace the ring param field with this type. Replace XEN_DOMCTL_VM_EVENT_OP_ occurrences with their corresponding XEN_VM_EVENT_TYPE_ counterpart. Signed-off-by: Petre Pircalabu --- tools/libxc/include/xenctrl.h | 1 + tools/libxc/xc_mem_paging.c | 6 ++-- tools/libxc/xc_monitor.c | 6 ++-- tools/libxc/xc_private.h | 8 ++--- tools/libxc/xc_vm_event.c | 70 ++++++++++++++++++------------------- xen/common/vm_event.c | 12 +++---- xen/include/public/domctl.h | 81 ++++++------------------------------------- xen/include/public/vm_event.h | 31 +++++++++++++++++ 8 files changed, 93 insertions(+), 122 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 28fdbc0..943b933 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -46,6 +46,7 @@ #include #include #include +#include #include "xentoollog.h" diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c index 08468fb..37a8224 100644 --- a/tools/libxc/xc_mem_paging.c +++ b/tools/libxc/xc_mem_paging.c @@ -41,7 +41,7 @@ void *xc_mem_paging_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port) { return xc_vm_event_enable(xch, domain_id, - XEN_DOMCTL_VM_EVENT_OP_PAGING, + XEN_VM_EVENT_TYPE_PAGING, port); } @@ -49,14 +49,14 @@ int xc_mem_paging_disable(xc_interface *xch, uint32_t domain_id) { return xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_DISABLE, - XEN_DOMCTL_VM_EVENT_OP_PAGING); + XEN_VM_EVENT_TYPE_PAGING); } int xc_mem_paging_resume(xc_interface *xch, uint32_t domain_id) { return xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_RESUME, - XEN_DOMCTL_VM_EVENT_OP_PAGING); + XEN_VM_EVENT_TYPE_PAGING); } int xc_mem_paging_nominate(xc_interface *xch, uint32_t domain_id, uint64_t gfn) diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c index d190c29..718fe8b 100644 --- a/tools/libxc/xc_monitor.c +++ b/tools/libxc/xc_monitor.c @@ -35,7 +35,7 @@ void *xc_monitor_enable(xc_interface *xch, uint32_t domain_id, uint32_t *port) } buffer = xc_vm_event_enable(xch, domain_id, - HVM_PARAM_MONITOR_RING_PFN, + XEN_VM_EVENT_TYPE_MONITOR, port); saved_errno = errno; if ( xc_domain_unpause(xch, domain_id) ) @@ -53,14 +53,14 @@ int xc_monitor_disable(xc_interface *xch, uint32_t domain_id) { return xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_DISABLE, - XEN_DOMCTL_VM_EVENT_OP_MONITOR); + XEN_VM_EVENT_TYPE_MONITOR); } int xc_monitor_resume(xc_interface *xch, uint32_t domain_id) { return xc_vm_event_control(xch, domain_id, XEN_VM_EVENT_RESUME, - XEN_DOMCTL_VM_EVENT_OP_MONITOR); + XEN_VM_EVENT_TYPE_MONITOR); } int xc_monitor_get_capabilities(xc_interface *xch, uint32_t domain_id, diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 663e78b..482451c 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -412,12 +412,12 @@ int xc_ffs64(uint64_t x); * vm_event operations. Internal use only. */ int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op, - unsigned int mode); + unsigned int type); /* - * Enables vm_event and returns the mapped ring page indicated by param. - * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN + * Enables vm_event and returns the mapped ring page indicated by type. + * type can be XEN_VM_EVENT_TYPE_(PAGING/MONITOR/SHARING) */ -void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param, +void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type, uint32_t *port); int do_dm_op(xc_interface *xch, uint32_t domid, unsigned int nr_bufs, ...); diff --git a/tools/libxc/xc_vm_event.c b/tools/libxc/xc_vm_event.c index ea10366..3b1018b 100644 --- a/tools/libxc/xc_vm_event.c +++ b/tools/libxc/xc_vm_event.c @@ -23,29 +23,54 @@ #include "xc_private.h" int xc_vm_event_control(xc_interface *xch, uint32_t domain_id, unsigned int op, - unsigned int mode) + unsigned int type) { DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_vm_event_op; domctl.domain = domain_id; domctl.u.vm_event_op.op = op; - domctl.u.vm_event_op.mode = mode; + domctl.u.vm_event_op.type = type; return do_domctl(xch, &domctl); } -void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param, +static int xc_vm_event_ring_pfn_param(int type, int *param) +{ + if ( !param ) + return -EINVAL; + + switch ( type ) + { + case XEN_VM_EVENT_TYPE_PAGING: + *param = HVM_PARAM_PAGING_RING_PFN; + break; + + case XEN_VM_EVENT_TYPE_MONITOR: + *param = HVM_PARAM_MONITOR_RING_PFN; + break; + + case XEN_VM_EVENT_TYPE_SHARING: + *param = HVM_PARAM_SHARING_RING_PFN; + break; + + default: + return -EINVAL; + } + + return 0; +} + +void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int type, uint32_t *port) { void *ring_page = NULL; uint64_t pfn; xen_pfn_t ring_pfn, mmap_pfn; - unsigned int op, mode; - int rc; + int param, rc; DECLARE_DOMCTL; - if ( !port ) + if ( !port || xc_vm_event_ring_pfn_param(type, ¶m) != 0 ) { errno = EINVAL; return NULL; @@ -83,37 +108,10 @@ void *xc_vm_event_enable(xc_interface *xch, uint32_t domain_id, int param, goto out; } - switch ( param ) - { - case HVM_PARAM_PAGING_RING_PFN: - op = XEN_VM_EVENT_ENABLE; - mode = XEN_DOMCTL_VM_EVENT_OP_PAGING; - break; - - case HVM_PARAM_MONITOR_RING_PFN: - op = XEN_VM_EVENT_ENABLE; - mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR; - break; - - case HVM_PARAM_SHARING_RING_PFN: - op = XEN_VM_EVENT_ENABLE; - mode = XEN_DOMCTL_VM_EVENT_OP_SHARING; - break; - - /* - * This is for the outside chance that the HVM_PARAM is valid but is invalid - * as far as vm_event goes. - */ - default: - errno = EINVAL; - rc = -1; - goto out; - } - domctl.cmd = XEN_DOMCTL_vm_event_op; domctl.domain = domain_id; - domctl.u.vm_event_op.op = op; - domctl.u.vm_event_op.mode = mode; + domctl.u.vm_event_op.op = XEN_VM_EVENT_ENABLE; + domctl.u.vm_event_op.type = type; rc = do_domctl(xch, &domctl); if ( rc != 0 ) @@ -148,7 +146,7 @@ int xc_vm_event_get_version(xc_interface *xch) domctl.cmd = XEN_DOMCTL_vm_event_op; domctl.domain = DOMID_INVALID; domctl.u.vm_event_op.op = XEN_VM_EVENT_GET_VERSION; - domctl.u.vm_event_op.mode = XEN_DOMCTL_VM_EVENT_OP_MONITOR; + domctl.u.vm_event_op.type = XEN_VM_EVENT_TYPE_MONITOR; rc = do_domctl(xch, &domctl); if ( !rc ) diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c index 6833c21..d7c5f22 100644 --- a/xen/common/vm_event.c +++ b/xen/common/vm_event.c @@ -371,7 +371,7 @@ static int vm_event_resume(struct domain *d, struct vm_event_domain *ved) vm_event_response_t rsp; /* - * vm_event_resume() runs in either XEN_DOMCTL_VM_EVENT_OP_*, or + * vm_event_resume() runs in either XEN_VM_EVENT_* domctls, or * EVTCHN_send context from the introspection consumer. Both contexts * are guaranteed not to be the subject of vm_event responses. * While we could ASSERT(v != current) for each VCPU in d in the loop @@ -597,7 +597,7 @@ int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec, if ( unlikely(d == NULL) ) return -ESRCH; - rc = xsm_vm_event_control(XSM_PRIV, d, vec->mode, vec->op); + rc = xsm_vm_event_control(XSM_PRIV, d, vec->type, vec->op); if ( rc ) return rc; @@ -624,10 +624,10 @@ int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec, rc = -ENOSYS; - switch ( vec->mode ) + switch ( vec->type ) { #ifdef CONFIG_HAS_MEM_PAGING - case XEN_DOMCTL_VM_EVENT_OP_PAGING: + case XEN_VM_EVENT_TYPE_PAGING: { rc = -EINVAL; @@ -683,7 +683,7 @@ int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec, break; #endif - case XEN_DOMCTL_VM_EVENT_OP_MONITOR: + case XEN_VM_EVENT_TYPE_MONITOR: { rc = -EINVAL; @@ -721,7 +721,7 @@ int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec, break; #ifdef CONFIG_HAS_MEM_SHARING - case XEN_DOMCTL_VM_EVENT_OP_SHARING: + case XEN_VM_EVENT_TYPE_SHARING: { rc = -EINVAL; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 19486d5..19281fa 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -38,7 +38,7 @@ #include "hvm/save.h" #include "memory.h" -#define XEN_DOMCTL_INTERFACE_VERSION 0x00000011 +#define XEN_DOMCTL_INTERFACE_VERSION 0x00000012 /* * NB. xen_domctl.domain is an IN/OUT parameter for this operation. @@ -769,80 +769,18 @@ struct xen_domctl_gdbsx_domstatus { * VM event operations */ -/* XEN_DOMCTL_vm_event_op */ - -/* - * There are currently three rings available for VM events: - * sharing, monitor and paging. This hypercall allows one to - * control these rings (enable/disable), as well as to signal - * to the hypervisor to pull responses (resume) from the given - * ring. +/* XEN_DOMCTL_vm_event_op. + * Use for teardown/setup of helper<->hypervisor interface for paging, + * access and sharing. */ #define XEN_VM_EVENT_ENABLE 0 #define XEN_VM_EVENT_DISABLE 1 #define XEN_VM_EVENT_RESUME 2 #define XEN_VM_EVENT_GET_VERSION 3 -/* - * Domain memory paging - * Page memory in and out. - * Domctl interface to set up and tear down the - * pager<->hypervisor interface. Use XENMEM_paging_op* - * to perform per-page operations. - * - * The XEN_VM_EVENT_PAGING_ENABLE domctl returns several - * non-standard error codes to indicate why paging could not be enabled: - * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest - * EMLINK - guest has iommu passthrough enabled - * EXDEV - guest has PoD enabled - * EBUSY - guest has or had paging enabled, ring buffer still active - */ -#define XEN_DOMCTL_VM_EVENT_OP_PAGING 1 - -/* - * Monitor helper. - * - * As with paging, use the domctl for teardown/setup of the - * helper<->hypervisor interface. - * - * The monitor interface can be used to register for various VM events. For - * example, there are HVM hypercalls to set the per-page access permissions - * of every page in a domain. When one of these permissions--independent, - * read, write, and execute--is violated, the VCPU is paused and a memory event - * is sent with what happened. The memory event handler can then resume the - * VCPU and redo the access with a XEN_VM_EVENT_RESUME option. - * - * See public/vm_event.h for the list of available events that can be - * subscribed to via the monitor interface. - * - * The XEN_VM_EVENT_MONITOR_* domctls returns - * non-standard error codes to indicate why access could not be enabled: - * ENODEV - host lacks HAP support (EPT/NPT) or HAP is disabled in guest - * EBUSY - guest has or had access enabled, ring buffer still active - * - */ -#define XEN_DOMCTL_VM_EVENT_OP_MONITOR 2 - -/* - * 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_VM_EVENT_OP_SHARING 3 - -/* Use for teardown/setup of helper<->hypervisor interface for paging, - * access and sharing.*/ struct xen_domctl_vm_event_op { - uint32_t op; /* XEN_VM_EVENT_* */ - uint32_t mode; /* XEN_DOMCTL_VM_EVENT_OP_* */ + uint32_t op; /* XEN_VM_EVENT_* */ + uint32_t type; /* XEN_VM_EVENT_TYPE_* */ union { struct { @@ -857,7 +795,10 @@ struct xen_domctl_vm_event_op { * Memory sharing operations */ /* XEN_DOMCTL_mem_sharing_op. - * The CONTROL sub-domctl is used for bringup/teardown. */ + * The CONTROL sub-domctl is used for bringup/teardown. + * Please note that mem sharing can be turned on *without* setting-up the + * correspondin ring + */ #define XEN_DOMCTL_MEM_SHARING_CONTROL 0 struct xen_domctl_mem_sharing_op { @@ -1004,7 +945,7 @@ struct xen_domctl_psr_cmt_op { * Enable/disable monitoring various VM events. * This domctl configures what events will be reported to helper apps * via the ring buffer "MONITOR". The ring has to be first enabled - * with the domctl XEN_DOMCTL_VM_EVENT_OP_MONITOR. + * with XEN_VM_EVENT_ENABLE. * * GET_CAPABILITIES can be used to determine which of these features is * available on a given platform. diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h index 959083d..c48bc21 100644 --- a/xen/include/public/vm_event.h +++ b/xen/include/public/vm_event.h @@ -36,6 +36,37 @@ #include "io/ring.h" /* + * There are currently three types of VM events. + */ + +/* + * Domain memory paging + * + * Page memory in and out. + */ +#define XEN_VM_EVENT_TYPE_PAGING 1 + +/* + * Monitor. + * + * The monitor interface can be used to register for various VM events. For + * example, there are HVM hypercalls to set the per-page access permissions + * of every page in a domain. When one of these permissions--independent, + * read, write, and execute--is violated, the VCPU is paused and a memory event + * is sent with what happened. The memory event handler can then resume the + * VCPU and redo the access with a XEN_VM_EVENT_RESUME option. + */ +#define XEN_VM_EVENT_TYPE_MONITOR 2 + +/* + * Sharing ENOMEM. + * + * Used to communicate failed allocations in the unshare path. + * XENMEM_sharing_op_resume is used to wake up vcpus that could not unshare. + */ +#define XEN_VM_EVENT_TYPE_SHARING 3 + +/* * Memory event flags */