From patchwork Thu Apr 6 14:27:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9667593 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3DD6A601EB for ; Thu, 6 Apr 2017 14:29:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59B4228375 for ; Thu, 6 Apr 2017 14:29:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E6DD2858A; Thu, 6 Apr 2017 14:29:55 +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=-4.2 required=2.0 tests=BAYES_00, 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 AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CFA4928375 for ; Thu, 6 Apr 2017 14:29:54 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cw8O1-0001aR-SW; Thu, 06 Apr 2017 14:27:45 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cw8O0-0001aJ-Ma for xen-devel@lists.xenproject.org; Thu, 06 Apr 2017 14:27:44 +0000 Received: from [85.158.137.68] by server-6.bemta-3.messagelabs.com id 26/E9-08534-F5056E85; Thu, 06 Apr 2017 14:27:43 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrIIsWRWlGSWpSXmKPExsXS6fjDSzc+4Fm EwYFPwhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8aZX89YCt45VHROcW5gvK7fxcjJISSQJ9F/ YD0ziM0rYCfxpLsRzJYQMJR4+v46G4jNIqAqsW7jLyYQm01AXaLt2XbWLkYODhEBA4lzR5O6G Lk4mAUmMUmcmtHGDlIjLGAtcf//eWaI+XYSD1rPsoDU8woISvzdIQwSZgYKH163hmUCI/cshM wsJBkIW0vi4a9bULa2xLKFr5lBypkFpCWW/+OACDtLbPm3lh1VCYjtJ3Fmai/bAkaOVYwaxal FZalFukYWeklFmekZJbmJmTm6hgbGermpxcWJ6ak5iUnFesn5uZsYgUFZz8DAuIOx/YTfIUZJ DiYlUV4FnycRQnxJ+SmVGYnFGfFFpTmpxYcYZTg4lCR4HfyfRQgJFqWmp1akZeYA4wMmLcHBo yTC6wmS5i0uSMwtzkyHSJ1iVJQS5+UASQiAJDJK8+DaYDF5iVFWSpiXkYGBQYinILUoN7MEVf 4VozgHo5Iwrw/IFJ7MvBK46a+AFjMBLfa59RRkcUkiQkqqgVHYrGVWEFeRQ+bXy65qctxfNu5 0TDlUPb9OJ/PsBtlb3O2G52Xl9y/z/u/ApbH2eLJG2p5W9Skcc9R3O383vfi9oeC3Xa9BreSK H4f1jspMeLZo9zKZOYJvzmZ9nqm4s097yU1Gq+/CXxtvKO1NbBWRaPBIvJ2ZodumlqD6wquF4 8a72jM745RYijMSDbWYi4oTAX4mPDzEAgAA X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-12.tower-31.messagelabs.com!1491488861!77805582!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17858 invoked from network); 6 Apr 2017 14:27:42 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-12.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 6 Apr 2017 14:27:42 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 06 Apr 2017 08:27:40 -0600 Message-Id: <58E66C79020000780014E07A@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Thu, 06 Apr 2017 08:27:37 -0600 From: "Jan Beulich" To: "xen-devel" References: <58E66C79020000780014E07A@prv-mh.provo.novell.com> Mime-Version: 1.0 Cc: Kevin Tian , Suravee Suthikulpanit , Andrew Cooper , Julien Grall , Jun Nakajima , Boris Ostrovsky Subject: [Xen-devel] [PATCH] x86/HVM: don't leak PFEC_implict to guests X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Doing so may not only confuse them, but will - on VMX - lead to VMRESUME failures. Add respective ASSERT()s where the fields get set to guard against future similar issues (or - in the restore case - fail the operation). In that latter code at once convert the mis-used gdprintk() to dprintk(), as the vCPU of interest is not "current". Signed-off-by: Jan Beulich x86/HVM: don't leak PFEC_implict to guests Doing so may not only confuse them, but will - on VMX - lead to VMRESUME failures. Add respective ASSERT()s where the fields get set to guard against future similar issues (or - in the restore case - fail the operation). In that latter code at once convert the mis-used gdprintk() to dprintk(), as the vCPU of interest is not "current". Signed-off-by: Jan Beulich --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3111,7 +3111,7 @@ static enum hvm_copy_result __hvm_copy( if ( pfinfo ) { pfinfo->linear = addr; - pfinfo->ec = pfec; + pfinfo->ec = pfec & ~PFEC_implicit; } return HVMCOPY_bad_gva_to_gfn; } --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -269,13 +269,23 @@ static int svm_vmcb_restore(struct vcpu struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; struct p2m_domain *p2m = p2m_get_hostp2m(v->domain); - if ( c->pending_valid && - ((c->pending_type == 1) || (c->pending_type > 6) || - (c->pending_reserved != 0)) ) + if ( c->pending_valid ) { - gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n", - c->pending_event); - return -EINVAL; + if ( (c->pending_type == 1) || (c->pending_type > 6) || + (c->pending_reserved != 0) ) + { + dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32".\n", + v, c->pending_event); + return -EINVAL; + } + + if ( c->pending_error_valid && + c->error_code != (uint16_t)c->error_code ) + { + dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32".\n", + v, c->error_code); + return -EINVAL; + } } if ( !paging_mode_hap(v->domain) ) @@ -1288,6 +1298,8 @@ static void svm_inject_event(const struc vmcb->nextrip = (uint32_t)vmcb->nextrip; } + ASSERT(!eventinj.fields.ev || + eventinj.fields.errorcode == (uint16_t)eventinj.fields.errorcode); vmcb->eventinj = eventinj; if ( _event.vector == TRAP_page_fault ) --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -731,13 +731,23 @@ static int vmx_vmcs_restore(struct vcpu { int rc; - if ( c->pending_valid && - ((c->pending_type == 1) || (c->pending_type > 6) || - (c->pending_reserved != 0)) ) + if ( c->pending_valid ) { - gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n", - c->pending_event); - return -EINVAL; + if ( (c->pending_type == 1) || (c->pending_type > 6) || + (c->pending_reserved != 0) ) + { + dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32".\n", + v, c->pending_event); + return -EINVAL; + } + + if ( c->pending_error_valid && + c->error_code != (uint16_t)c->error_code ) + { + dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32".\n", + v, c->error_code); + return -EINVAL; + } } rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3); @@ -1660,6 +1670,7 @@ static void __vmx_inject_exception(int t MASK_INSR(trap, INTR_INFO_VECTOR_MASK); if ( error_code != X86_EVENT_NO_EC ) { + ASSERT(error_code == (uint16_t)error_code); __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); intr_fields |= INTR_INFO_DELIVER_CODE_MASK; } Reviewed-by: Boris Ostrovsky Reviewed-by: Kevin Tian --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3111,7 +3111,7 @@ static enum hvm_copy_result __hvm_copy( if ( pfinfo ) { pfinfo->linear = addr; - pfinfo->ec = pfec; + pfinfo->ec = pfec & ~PFEC_implicit; } return HVMCOPY_bad_gva_to_gfn; } --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -269,13 +269,23 @@ static int svm_vmcb_restore(struct vcpu struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; struct p2m_domain *p2m = p2m_get_hostp2m(v->domain); - if ( c->pending_valid && - ((c->pending_type == 1) || (c->pending_type > 6) || - (c->pending_reserved != 0)) ) + if ( c->pending_valid ) { - gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n", - c->pending_event); - return -EINVAL; + if ( (c->pending_type == 1) || (c->pending_type > 6) || + (c->pending_reserved != 0) ) + { + dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32".\n", + v, c->pending_event); + return -EINVAL; + } + + if ( c->pending_error_valid && + c->error_code != (uint16_t)c->error_code ) + { + dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32".\n", + v, c->error_code); + return -EINVAL; + } } if ( !paging_mode_hap(v->domain) ) @@ -1288,6 +1298,8 @@ static void svm_inject_event(const struc vmcb->nextrip = (uint32_t)vmcb->nextrip; } + ASSERT(!eventinj.fields.ev || + eventinj.fields.errorcode == (uint16_t)eventinj.fields.errorcode); vmcb->eventinj = eventinj; if ( _event.vector == TRAP_page_fault ) --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -731,13 +731,23 @@ static int vmx_vmcs_restore(struct vcpu { int rc; - if ( c->pending_valid && - ((c->pending_type == 1) || (c->pending_type > 6) || - (c->pending_reserved != 0)) ) + if ( c->pending_valid ) { - gdprintk(XENLOG_ERR, "Invalid pending event %#"PRIx32".\n", - c->pending_event); - return -EINVAL; + if ( (c->pending_type == 1) || (c->pending_type > 6) || + (c->pending_reserved != 0) ) + { + dprintk(XENLOG_ERR, "%pv: Invalid pending event %#"PRIx32".\n", + v, c->pending_event); + return -EINVAL; + } + + if ( c->pending_error_valid && + c->error_code != (uint16_t)c->error_code ) + { + dprintk(XENLOG_ERR, "%pv: Invalid error code %#"PRIx32".\n", + v, c->error_code); + return -EINVAL; + } } rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3); @@ -1660,6 +1670,7 @@ static void __vmx_inject_exception(int t MASK_INSR(trap, INTR_INFO_VECTOR_MASK); if ( error_code != X86_EVENT_NO_EC ) { + ASSERT(error_code == (uint16_t)error_code); __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code); intr_fields |= INTR_INFO_DELIVER_CODE_MASK; }