From patchwork Fri Jan 29 08:55:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Razvan Cojocaru X-Patchwork-Id: 8160691 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D4FD19F38B for ; Fri, 29 Jan 2016 08:58:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CD1382037E for ; Fri, 29 Jan 2016 08:58:39 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A660A202C8 for ; Fri, 29 Jan 2016 08:58:38 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aP4px-0001Wq-RG; Fri, 29 Jan 2016 08:55:25 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aP4pw-0001Wl-0m for xen-devel@lists.xen.org; Fri, 29 Jan 2016 08:55:24 +0000 Received: from [193.109.254.147] by server-8.bemta-14.messagelabs.com id A2/89-24450-7F82BA65; Fri, 29 Jan 2016 08:55:19 +0000 X-Env-Sender: rcojocaru@bitdefender.com X-Msg-Ref: server-12.tower-27.messagelabs.com!1454057716!19900835!1 X-Originating-IP: [91.199.104.161] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 7704 invoked from network); 29 Jan 2016 08:55:18 -0000 Received: from mx01.buh.bitdefender.com (HELO mx01.buh.bitdefender.com) (91.199.104.161) by server-12.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 29 Jan 2016 08:55:18 -0000 Comment: DomainKeys? See http://domainkeys.sourceforge.net/ DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=bitdefender.com; b=eI9OSvxf+dx44gyLFPg1IHngoX0685G40YWHcM3x99mOAwmZ+ALn3YVrVkdsXDNnmDIHJZ9aEwGY9eONzYP1VLZl/XThSkugZna+FG7G8n2K7oEGmlqIJG0KGW/FQMBBl2BdAv/i/57WOyfuIe8lVbpZ9ImvYNIkXfCOYTrsW9+svem7fewvDXjh6FAXibBHX0BnlNk1moXdxH2aYUk4EcEdHa9oAPjiMDvAdlOK2Aw9LK7WjUV78uWizj0cT4KSSAMqMHDAKMF144JAIfy5jcR5w9HsPUulJ+W2ObR7/2/TN6bj0GlLq6aNEODQw0ruOW1HTKQYRv5hwZ0j9ZpxbA==; h=Received:Received:Received:Received:Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer:X-BitDefender-Scanner:X-BitDefender-Spam:X-BitDefender-SpamStamp:X-BitDefender-CF-Stamp; DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=bitdefender.com; h=from:to :cc:subject:date:message-id; s=default; bh=KKPnEbiChnBTfrJnEOtYx bLUITw=; b=AwwbhExZj8zWsqOPE8+jtQ2E4uV0PQJomqHIU78g0Ov/BXm2F03Jn htApo21vkU/C9vaeDiFN8YAsJBBLRMk8NLkp/t/KE1slhCDY7SWXHXuFNgU/FNEj wl5CNevoAJ5kDjAQAO7CwOsWU4sZ8xfftYvqFN+odf8g+/eg1Z2Qm0srJv8rWly1 bx4hUst3YcUilfgPm+x/gkBaALDNocMU09EOVV6z/mQnPPGN6pTBKmq28mgMsRri VGqOr4MkpkKOdVgZ8kVaBpHbv0NRbDYSh6XDT67igfVc/POazTqNSdSw0mIHJVTf WHp8LPfwGLfPFDyLtBDD+WpHvIpKnNWyA== Received: (qmail 19263 invoked from network); 29 Jan 2016 10:55:15 +0200 Received: from unknown (HELO mx-sr.buh.bitdefender.com) (10.17.80.103) by mx01.buh.bitdefender.com with AES256-GCM-SHA384 encrypted SMTP; 29 Jan 2016 10:55:15 +0200 Received: from smtp03.buh.bitdefender.org (unknown [10.17.80.77]) by mx-sr.buh.bitdefender.com (Postfix) with ESMTP id 0621B803B3 for ; Fri, 29 Jan 2016 10:55:15 +0200 (EET) Received: (qmail 8548 invoked from network); 29 Jan 2016 10:55:14 +0200 Received: from xen.dsd.ro (HELO xen.dsd.bitdefender.biz) (rcojocaru@bitdefender.com@10.10.14.109) by smtp03.buh.bitdefender.org with AES128-SHA256 encrypted SMTP; 29 Jan 2016 10:55:14 +0200 From: Razvan Cojocaru To: xen-devel@lists.xen.org Date: Fri, 29 Jan 2016 10:55:04 +0200 Message-Id: <1454057704-11740-1-git-send-email-rcojocaru@bitdefender.com> X-Mailer: git-send-email 1.9.1 X-BitDefender-Scanner: Clean, Agent: BitDefender qmail 3.1.4 on smtp03.buh.bitdefender.org, sigver: 7.64324 X-BitDefender-Spam: No (0) X-BitDefender-SpamStamp: Build: [Engines: 2.15.6.743, Dats: 413453, Stamp: 3], Multi: [Enabled, t: (0.000009, 0.005681)], BW: [Enabled, t: (0.000006,0.000001)], RBL DNSBL: [Disabled], APM: [Enabled, Score: 500, t: (0.004638), Flags: 2A917CE3; NN_LARGISH_BIGGISH; NN_NO_CONTENT_TYPE; NN_LEGIT_SUMM_400_WORDS; NN_NO_LINK_NMD; NN_LEGIT_BITDEFENDER; NN_LEGIT_S_SQARE_BRACKETS; NN_LEGIT_MAILING_LIST_TO], SGN: [Enabled, t: (0.012000)], URL: [Enabled, t: (0.000005)], RTDA: [Enabled, t: (0.029255), Hit: No, Details: v2.3.2; Id: 2m1ghaq.1a9vgk1hu.1k5l2], total: 0(775) X-BitDefender-CF-Stamp: none Cc: andrew.cooper3@citrix.com, tamas@tklengyel.com, keir@xen.org, Razvan Cojocaru , jbeulich@suse.com Subject: [Xen-devel] [PATCH V2] vm_event: make sure the domain is paused in key domctls X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch pauses the domain for all writes through the 'ad' pointer in monitor_domctl(), defers a domain_unpause() call until after the CRs are updated for the MONITOR_EVENT_WRITE_CTRLREG case, and makes sure that the domain is paused for both vm_event enable and disable cases in vm_event_domctl(). Thanks go to Andrew Cooper for his review and suggestions. Signed-off-by: Razvan Cojocaru Reviewed-by: Andrew Cooper Acked-by: Tamas K Lengyel --- Changes since V1: - Annotated domctl d != current->domain checks with /* no domain_pause() */. - Moved the XEN_DOMCTL_monitor_op current->domain check into monitor_domctl(). - Reworked the return -EOPNOTSUPP statement to not leave the domain accidentally paused. - Found an additional instance of lacking domain_pause() at XEN_DOMCTL_set_access_required. - Replaced the vm_event_enable() pause_domain() call with a comment pointing to XSA-99, which made sure that the domain is paused in libxc for the enable case (at Tamas K Lengyel's suggestion). --- xen/arch/x86/monitor.c | 32 +++++++++++++++++++------------- xen/common/domctl.c | 12 ++++++------ xen/common/vm_event.c | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c index 7611f7b..1d43880 100644 --- a/xen/arch/x86/monitor.c +++ b/xen/arch/x86/monitor.c @@ -69,6 +69,9 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) struct arch_domain *ad = &d->arch; uint32_t capabilities = get_capabilities(d); + if ( current->domain == d ) /* no domain_pause() */ + return -EPERM; + rc = xsm_vm_event_control(XSM_PRIV, d, mop->op, mop->event); if ( rc ) return rc; @@ -80,7 +83,9 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) return 0; case XEN_DOMCTL_MONITOR_OP_EMULATE_EACH_REP: - d->arch.mem_access_emulate_each_rep = !!mop->event; + domain_pause(d); + ad->mem_access_emulate_each_rep = !!mop->event; + domain_unpause(d); return 0; } @@ -109,6 +114,8 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) if ( rc ) return rc; + domain_pause(d); + if ( mop->u.mov_to_cr.sync ) ad->monitor.write_ctrlreg_sync |= ctrlreg_bitmask; else @@ -119,20 +126,18 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) else ad->monitor.write_ctrlreg_onchangeonly &= ~ctrlreg_bitmask; - domain_pause(d); - if ( !status ) ad->monitor.write_ctrlreg_enabled |= ctrlreg_bitmask; else ad->monitor.write_ctrlreg_enabled &= ~ctrlreg_bitmask; - domain_unpause(d); - if ( mop->u.mov_to_cr.index == VM_EVENT_X86_CR3 ) /* Latches new CR3 mask through CR0 code */ for_each_vcpu ( d, v ) hvm_update_guest_cr(v, 0); + domain_unpause(d); + break; } @@ -145,16 +150,18 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) return rc; if ( mop->op == XEN_DOMCTL_MONITOR_OP_ENABLE && + mop->u.mov_to_msr.extended_capture && + !hvm_enable_msr_exit_interception(d) ) + return -EOPNOTSUPP; + + domain_pause(d); + + if ( mop->op == XEN_DOMCTL_MONITOR_OP_ENABLE && mop->u.mov_to_msr.extended_capture ) - { - if ( hvm_enable_msr_exit_interception(d) ) ad->monitor.mov_to_msr_extended = 1; - else - return -EOPNOTSUPP; - } else + else ad->monitor.mov_to_msr_extended = 0; - domain_pause(d); ad->monitor.mov_to_msr_enabled = !status; domain_unpause(d); break; @@ -196,9 +203,8 @@ int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *mop) if ( rc ) return rc; - ad->monitor.guest_request_sync = mop->u.guest_request.sync; - domain_pause(d); + ad->monitor.guest_request_sync = mop->u.guest_request.sync; ad->monitor.guest_request_enabled = !status; domain_unpause(d); break; diff --git a/xen/common/domctl.c b/xen/common/domctl.c index dc1ea06..121a34a 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -709,7 +709,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } case XEN_DOMCTL_soft_reset: - if ( d == current->domain ) + if ( d == current->domain ) /* no domain_pause() */ { ret = -EINVAL; break; @@ -1136,11 +1136,15 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) #ifdef CONFIG_HAS_MEM_ACCESS case XEN_DOMCTL_set_access_required: - if ( unlikely(current->domain == d) ) + if ( unlikely(current->domain == d) ) /* no domain_pause() */ ret = -EPERM; else + { + domain_pause(d); p2m_get_hostp2m(d)->access_required = op->u.access_required.access_required; + domain_unpause(d); + } break; #endif @@ -1175,10 +1179,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) } case XEN_DOMCTL_monitor_op: - ret = -EPERM; - if ( current->domain == d ) - break; - ret = monitor_domctl(d, &op->u.monitor_op); if ( !ret ) copyback = 1; diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c index 28a7add..9f43a76 100644 --- a/xen/common/vm_event.c +++ b/xen/common/vm_event.c @@ -567,7 +567,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, if ( rc ) return rc; - if ( unlikely(d == current->domain) ) + if ( unlikely(d == current->domain) ) /* no domain_pause() */ { gdprintk(XENLOG_INFO, "Tried to do a memory event op on itself.\n"); return -EINVAL; @@ -624,6 +624,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, if ( p2m->pod.entry_count ) break; + /* domain_pause() not required here, see XSA-99 */ rc = vm_event_enable(d, vec, ved, _VPF_mem_paging, HVM_PARAM_PAGING_RING_PFN, mem_paging_notification); @@ -632,7 +633,11 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, case XEN_VM_EVENT_DISABLE: if ( ved->ring_page ) + { + domain_pause(d); rc = vm_event_disable(d, ved); + domain_unpause(d); + } break; case XEN_VM_EVENT_RESUME: @@ -658,6 +663,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, switch( vec->op ) { case XEN_VM_EVENT_ENABLE: + /* domain_pause() not required here, see XSA-99 */ rc = vm_event_enable(d, vec, ved, _VPF_mem_access, HVM_PARAM_MONITOR_RING_PFN, monitor_notification); @@ -665,7 +671,11 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, case XEN_VM_EVENT_DISABLE: if ( ved->ring_page ) + { + domain_pause(d); rc = vm_event_disable(d, ved); + domain_unpause(d); + } break; case XEN_VM_EVENT_RESUME: @@ -701,6 +711,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, if ( !hap_enabled(d) ) break; + /* domain_pause() not required here, see XSA-99 */ rc = vm_event_enable(d, vec, ved, _VPF_mem_sharing, HVM_PARAM_SHARING_RING_PFN, mem_sharing_notification); @@ -708,7 +719,11 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, case XEN_VM_EVENT_DISABLE: if ( ved->ring_page ) + { + domain_pause(d); rc = vm_event_disable(d, ved); + domain_unpause(d); + } break; case XEN_VM_EVENT_RESUME: