From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tamas K Lengyel Subject: [RFC PATCH V3 11/12] xen/vm_event: Decouple vm_event and mem_access. Date: Thu, 29 Jan 2015 22:46:37 +0100 Message-ID: <1422567998-29995-12-git-send-email-tamas.lengyel@zentific.com> References: <1422567998-29995-1-git-send-email-tamas.lengyel@zentific.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1422567998-29995-1-git-send-email-tamas.lengyel@zentific.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: kevin.tian@intel.com, wei.liu2@citrix.com, ian.campbell@citrix.com, steve@zentific.com, stefano.stabellini@eu.citrix.com, jun.nakajima@intel.com, tim@xen.org, ian.jackson@eu.citrix.com, eddie.dong@intel.com, andres@lagarcavilla.org, jbeulich@suse.com, Tamas K Lengyel , rshriram@cs.ubc.ca, keir@xen.org, dgdegra@tycho.nsa.gov, yanghy@cn.fujitsu.com, rcojocaru@bitdefender.com List-Id: xen-devel@lists.xenproject.org The vm_event subsystem has been artifically tied to the presence of mem_access. While mem_access does depend on vm_event, vm_event is an entirely independent subsystem that can be used for arbitrary function-offloading to helper apps in domains. This patch removes the dependency that mem_access needs to be supported in order to enable vm_event. Signed-off-by: Tamas K Lengyel --- v3: Move ring processing out from mem_access.c to monitor.c in common --- MAINTAINERS | 1 + xen/common/Makefile | 3 ++- xen/common/mem_access.c | 32 ++-------------------- xen/common/monitor.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ xen/common/vm_event.c | 14 +++------- xen/include/xen/mem_access.h | 10 ++++--- xen/include/xen/monitor.h | 38 ++++++++++++++++++++++++++ xen/include/xen/vm_event.h | 56 -------------------------------------- xen/include/xsm/dummy.h | 2 -- xen/include/xsm/xsm.h | 4 --- xen/xsm/dummy.c | 2 -- xen/xsm/flask/hooks.c | 32 +++++++++------------- 12 files changed, 131 insertions(+), 127 deletions(-) create mode 100644 xen/common/monitor.c create mode 100644 xen/include/xen/monitor.h diff --git a/MAINTAINERS b/MAINTAINERS index 4c445bb..5d88d85 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -365,6 +365,7 @@ VM EVENT AND ACCESS M: Tim Deegan S: Supported F: xen/common/vm_event.c +F: xen/common/monitor.c F: xen/common/mem_access.c XENTRACE diff --git a/xen/common/Makefile b/xen/common/Makefile index e5bd75b..d86c073 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -52,9 +52,10 @@ obj-y += tmem_xen.o obj-y += radix-tree.o obj-y += rbtree.o obj-y += lzo.o +obj-y += vm_event.o +obj-y += monitor.o obj-$(HAS_PDX) += pdx.o obj-$(HAS_MEM_ACCESS) += mem_access.o -obj-$(HAS_MEM_ACCESS) += vm_event.o obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo unlz4 earlycpio,$(n).init.o) diff --git a/xen/common/mem_access.c b/xen/common/mem_access.c index 1f655b0..3655165 100644 --- a/xen/common/mem_access.c +++ b/xen/common/mem_access.c @@ -25,39 +25,11 @@ #include #include #include +#include #include #include #include -void mem_access_resume(struct domain *d) -{ - vm_event_response_t rsp; - - /* Pull all responses off the ring. */ - while ( vm_event_get_response(d, &d->vm_event->monitor, &rsp) ) - { - struct vcpu *v; - - if ( rsp.version != VM_EVENT_INTERFACE_VERSION ) - continue; - - if ( rsp.flags & VM_EVENT_FLAG_DUMMY ) - continue; - - /* Validate the vcpu_id in the response. */ - if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] ) - continue; - - v = d->vcpu[rsp.vcpu_id]; - - p2m_vm_event_emulate_check(v, &rsp); - - /* Unpause domain. */ - if ( rsp.flags & VM_EVENT_FLAG_VCPU_PAUSED ) - vm_event_vcpu_unpause(v); - } -} - int mem_access_memop(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg) { @@ -92,7 +64,7 @@ int mem_access_memop(unsigned long cmd, rc = -ENOSYS; else { - mem_access_resume(d); + monitor_resume(d); rc = 0; } break; diff --git a/xen/common/monitor.c b/xen/common/monitor.c new file mode 100644 index 0000000..172381a --- /dev/null +++ b/xen/common/monitor.c @@ -0,0 +1,64 @@ +/****************************************************************************** + * monitor.c + * + * VM event monitor support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +void monitor_resume(struct domain *d) +{ + vm_event_response_t rsp; + + /* Pull all responses off the ring. */ + while ( vm_event_get_response(d, &d->vm_event->monitor, &rsp) ) + { + struct vcpu *v; + + if ( rsp.version != VM_EVENT_INTERFACE_VERSION ) + continue; + +#ifndef NDEBUG + if ( rsp.flags & VM_EVENT_FLAG_DUMMY ) + continue; +#endif + + /* Validate the vcpu_id in the response. */ + if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] ) + continue; + + v = d->vcpu[rsp.vcpu_id]; + + if ( rsp.reason == VM_EVENT_REASON_MEM_ACCESS ) + mem_access_resume(v, &rsp); + + /* Unpause domain. */ + if ( rsp.flags & VM_EVENT_FLAG_VCPU_PAUSED ) + vm_event_vcpu_unpause(v); + } +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c index 0b30750..7eba58c 100644 --- a/xen/common/vm_event.c +++ b/xen/common/vm_event.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #ifdef HAS_MEM_PAGING @@ -439,14 +439,12 @@ static void mem_paging_notification(struct vcpu *v, unsigned int port) } #endif -#ifdef HAS_MEM_ACCESS /* Registered with Xen-bound event channel for incoming notifications. */ -static void mem_access_notification(struct vcpu *v, unsigned int port) +static void monitor_notification(struct vcpu *v, unsigned int port) { if ( likely(v->domain->vm_event->monitor.ring_page != NULL) ) - mem_access_resume(v->domain); + monitor_resume(v->domain); } -#endif #ifdef HAS_MEM_SHARING /* Registered with Xen-bound event channel for incoming notifications. */ @@ -507,12 +505,10 @@ void vm_event_cleanup(struct domain *d) (void)vm_event_disable(d, &d->vm_event->paging); } #endif -#ifdef HAS_MEM_ACCESS if ( d->vm_event->monitor.ring_page ) { destroy_waitqueue_head(&d->vm_event->monitor.wq); (void)vm_event_disable(d, &d->vm_event->monitor); } -#endif #ifdef HAS_MEM_SHARING if ( d->vm_event->share.ring_page ) { destroy_waitqueue_head(&d->vm_event->share.wq); @@ -608,7 +604,6 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, break; #endif -#ifdef HAS_MEM_ACCESS case XEN_DOMCTL_VM_EVENT_OP_MONITOR: { struct vm_event_domain *ved = &d->vm_event->monitor; @@ -620,7 +615,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, { rc = vm_event_enable(d, vec, ved, _VPF_mem_access, HVM_PARAM_MONITOR_RING_PFN, - mem_access_notification); + monitor_notification); } break; @@ -639,7 +634,6 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, } } break; -#endif #ifdef HAS_MEM_SHARING case XEN_DOMCTL_VM_EVENT_OP_SHARING: diff --git a/xen/include/xen/mem_access.h b/xen/include/xen/mem_access.h index 1d01221..aed2e13 100644 --- a/xen/include/xen/mem_access.h +++ b/xen/include/xen/mem_access.h @@ -24,6 +24,7 @@ #define _XEN_ASM_MEM_ACCESS_H #include +#include #ifdef HAS_MEM_ACCESS @@ -31,8 +32,11 @@ int mem_access_memop(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg); int mem_access_send_req(struct domain *d, vm_event_request_t *req); -/* Resumes the running of the VCPU, restarting the last instruction */ -void mem_access_resume(struct domain *d); +static inline +void mem_access_resume(struct vcpu *v, vm_event_response_t *rsp) +{ + p2m_vm_event_emulate_check(v, rsp); +} #else @@ -49,7 +53,7 @@ int mem_access_send_req(struct domain *d, vm_event_request_t *req) return -ENOSYS; } -static inline void mem_access_resume(struct domain *d) {} +static inline void mem_access_resume(struct vcpu *vcpu, vm_event_response_t *rsp) {} #endif /* HAS_MEM_ACCESS */ diff --git a/xen/include/xen/monitor.h b/xen/include/xen/monitor.h new file mode 100644 index 0000000..aad821b --- /dev/null +++ b/xen/include/xen/monitor.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * monitor.h + * + * Monitor event support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _XEN_ASM_MONITOR_H +#define _XEN_ASM_MONITOR_H + +#include + +/* Resumes the running of the VCPU, restarting the last instruction */ +void monitor_resume(struct domain *d); + +#endif /* _XEN_ASM_MEM_ACCESS_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h index 988ea42..477ef7e 100644 --- a/xen/include/xen/vm_event.h +++ b/xen/include/xen/vm_event.h @@ -26,8 +26,6 @@ #include -#ifdef HAS_MEM_ACCESS - /* Clean up on domain destruction */ void vm_event_cleanup(struct domain *d); @@ -76,60 +74,6 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *mec, void vm_event_vcpu_pause(struct vcpu *v); void vm_event_vcpu_unpause(struct vcpu *v); -#else - -static inline void vm_event_cleanup(struct domain *d) {} - -static inline bool_t vm_event_check_ring(struct vm_event_domain *med) -{ - return 0; -} - -static inline int vm_event_claim_slot(struct domain *d, - struct vm_event_domain *med) -{ - return -ENOSYS; -} - -static inline int vm_event_claim_slot_nosleep(struct domain *d, - struct vm_event_domain *med) -{ - return -ENOSYS; -} - -static inline -void vm_event_cancel_slot(struct domain *d, struct vm_event_domain *med) -{} - -static inline -void vm_event_put_request(struct domain *d, struct vm_event_domain *med, - vm_event_request_t *req) -{} - -static inline -int vm_event_get_response(struct domain *d, struct vm_event_domain *med, - vm_event_response_t *rsp) -{ - return -ENOSYS; -} - -static inline int do_vm_event_op(int op, uint32_t domain, void *arg) -{ - return -ENOSYS; -} - -static inline -int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *mec, - XEN_GUEST_HANDLE_PARAM(void) u_domctl) -{ - return -ENOSYS; -} - -static inline void vm_event_vcpu_pause(struct vcpu *v) {} -static inline void vm_event_vcpu_unpause(struct vcpu *v) {} - -#endif /* HAS_MEM_ACCESS */ - #endif /* __VM_EVENT_H__ */ diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 4227093..50ee929 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -513,7 +513,6 @@ static XSM_INLINE int xsm_hvm_param_nested(XSM_DEFAULT_ARG struct domain *d) return xsm_default_action(action, current->domain, d); } -#ifdef HAS_MEM_ACCESS static XSM_INLINE int xsm_vm_event_control(XSM_DEFAULT_ARG struct domain *d, int mode, int op) { XSM_ASSERT_ACTION(XSM_PRIV); @@ -525,7 +524,6 @@ static XSM_INLINE int xsm_vm_event_op(XSM_DEFAULT_ARG struct domain *d, int op) XSM_ASSERT_ACTION(XSM_DM_PRIV); return xsm_default_action(action, current->domain, d); } -#endif #ifdef CONFIG_X86 static XSM_INLINE int xsm_do_mca(XSM_DEFAULT_VOID) diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index cff9d35..d56a68f 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -141,10 +141,8 @@ struct xsm_operations { int (*hvm_param_nested) (struct domain *d); int (*get_vnumainfo) (struct domain *d); -#ifdef HAS_MEM_ACCESS int (*vm_event_control) (struct domain *d, int mode, int op); int (*vm_event_op) (struct domain *d, int op); -#endif #ifdef CONFIG_X86 int (*do_mca) (void); @@ -543,7 +541,6 @@ static inline int xsm_get_vnumainfo (xsm_default_t def, struct domain *d) return xsm_ops->get_vnumainfo(d); } -#ifdef HAS_MEM_ACCESS static inline int xsm_vm_event_control (xsm_default_t def, struct domain *d, int mode, int op) { return xsm_ops->vm_event_control(d, mode, op); @@ -553,7 +550,6 @@ static inline int xsm_vm_event_op (xsm_default_t def, struct domain *d, int op) { return xsm_ops->vm_event_op(d, op); } -#endif #ifdef CONFIG_X86 static inline int xsm_do_mca(xsm_default_t def) diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 25fca68..6d12d32 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -118,10 +118,8 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, remove_from_physmap); set_to_dummy_if_null(ops, map_gmfn_foreign); -#ifdef HAS_MEM_ACCESS set_to_dummy_if_null(ops, vm_event_control); set_to_dummy_if_null(ops, vm_event_op); -#endif #ifdef CONFIG_X86 set_to_dummy_if_null(ops, do_mca); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index c419543..5008b79 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -577,9 +577,7 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_iomem_permission: case XEN_DOMCTL_memory_mapping: case XEN_DOMCTL_set_target: -#ifdef HAS_MEM_ACCESS case XEN_DOMCTL_vm_event_op: -#endif #ifdef CONFIG_X86 /* These have individual XSM hooks (arch/x86/domctl.c) */ case XEN_DOMCTL_shadow_op: @@ -1136,6 +1134,16 @@ static int flask_hvm_param_nested(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__NESTED); } +static int flask_vm_event_control(struct domain *d, int mode, int op) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__VM_EVENT); +} + +static int flask_vm_event_op(struct domain *d, int op) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__VM_EVENT); +} + #if defined(HAS_PASSTHROUGH) && defined(HAS_PCI) static int flask_get_device_group(uint32_t machine_bdf) { @@ -1202,18 +1210,6 @@ static int flask_deassign_device(struct domain *d, uint32_t machine_bdf) } #endif /* HAS_PASSTHROUGH && HAS_PCI */ -#ifdef HAS_MEM_ACCESS -static int flask_vm_event_control(struct domain *d, int mode, int op) -{ - return current_has_perm(d, SECCLASS_HVM, HVM__VM_EVENT); -} - -static int flask_vm_event_op(struct domain *d, int op) -{ - return current_has_perm(d, SECCLASS_HVM, HVM__VM_EVENT); -} -#endif /* HAS_MEM_ACCESS */ - #ifdef CONFIG_X86 static int flask_do_mca(void) { @@ -1581,6 +1577,9 @@ static struct xsm_operations flask_ops = { .do_xsm_op = do_flask_op, .get_vnumainfo = flask_get_vnumainfo, + .vm_event_control = flask_vm_event_control, + .vm_event_op = flask_vm_event_op, + #ifdef CONFIG_COMPAT .do_compat_op = compat_flask_op, #endif @@ -1596,11 +1595,6 @@ static struct xsm_operations flask_ops = { .deassign_device = flask_deassign_device, #endif -#ifdef HAS_MEM_ACCESS - .vm_event_control = flask_vm_event_control, - .vm_event_op = flask_vm_event_op, -#endif - #ifdef CONFIG_X86 .do_mca = flask_do_mca, .shadow_control = flask_shadow_control, -- 2.1.4