From patchwork Fri Mar 11 16:01:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 8567181 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 95C3E9F1C0 for ; Fri, 11 Mar 2016 16:04:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 974F72022A for ; Fri, 11 Mar 2016 16:04:12 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id 8396B2026F for ; Fri, 11 Mar 2016 16:04:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1aePVG-0003hU-Hy; Fri, 11 Mar 2016 16:01:26 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1aePVF-0003hM-1d for xen-devel@lists.xenproject.org; Fri, 11 Mar 2016 16:01:25 +0000 Received: from [193.109.254.147] by server-8.bemta-14.messagelabs.com id 00/05-03645-4DBE2E65; Fri, 11 Mar 2016 16:01:24 +0000 X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-2.tower-27.messagelabs.com!1457712081!28573192!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 58031 invoked from network); 11 Mar 2016 16:01:23 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-2.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Mar 2016 16:01:23 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Fri, 11 Mar 2016 09:01:21 -0700 Message-Id: <56E2F9E102000078000DBAD6@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.0 Date: Fri, 11 Mar 2016 09:01:21 -0700 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper , Keir Fraser Subject: [Xen-devel] [PATCH] x86emul: special case far branch validation outside of long mode 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-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, 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 In that case (with the new value being held in, or now in one case cast to, a 32-bit variable) there's no need to go through the long mode part of the checks. Primarily this was meant to hopefully address Coverity ID 1355278, but since the change produces smaller code as well I think we should use it even if it doesn't help that (benign) warning. Also it's more in line with jmp_rel() for commit_far_branch() to do the _regs.eip update, so adjust that at once. Signed-off-by: Jan Beulich x86emul: special case far branch validation outside of long mode In that case (with the new value being held in, or now in one case cast to, a 32-bit variable) there's no need to go through the long mode part of the checks. Primarily this was meant to hopefully address Coverity ID 1355278, but since the change produces smaller code as well I think we should use it even if it doesn't help that (benign) warning. Also it's more in line with jmp_rel() for commit_far_branch() to do the _regs.eip update, so adjust that at once. Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -652,13 +652,20 @@ do { _regs.eip = ip; \ } while (0) -#define validate_far_branch(cs, ip) \ - generate_exception_if(in_longmode(ctxt, ops) && (cs)->attr.fields.l \ - ? !is_canonical_address(ip) \ - : (ip) > (cs)->limit, EXC_GP, 0) +#define validate_far_branch(cs, ip) ({ \ + if ( sizeof(ip) <= 4 ) { \ + ASSERT(in_longmode(ctxt, ops) <= 0); \ + generate_exception_if((ip) > (cs)->limit, EXC_GP, 0); \ + } else \ + generate_exception_if(in_longmode(ctxt, ops) && \ + (cs)->attr.fields.l \ + ? !is_canonical_address(ip) \ + : (ip) > (cs)->limit, EXC_GP, 0); \ +}) #define commit_far_branch(cs, ip) ({ \ validate_far_branch(cs, ip); \ + _regs.eip = (ip); \ ops->write_segment(x86_seg_cs, cs, ctxt); \ }) @@ -2787,7 +2794,6 @@ x86_emulate( (rc = load_seg(x86_seg_cs, src.val, 1, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, dst.val)) ) goto done; - _regs.eip = dst.val; break; } @@ -2830,9 +2836,8 @@ x86_emulate( eflags &= 0x257fd5; _regs.eflags &= mask; _regs.eflags |= (eflags & ~mask) | 0x02; - _regs.eip = eip; if ( (rc = load_seg(x86_seg_cs, sel, 1, &cs, ctxt, ops)) || - (rc = commit_far_branch(&cs, eip)) ) + (rc = commit_far_branch(&cs, (uint32_t)eip)) ) goto done; break; } @@ -3465,7 +3470,6 @@ x86_emulate( if ( (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, eip)) ) goto done; - _regs.eip = eip; break; } @@ -3767,11 +3771,11 @@ x86_emulate( &_regs.eip, op_bytes, ctxt)) || (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) goto done; + _regs.eip = src.val; } else if ( (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, src.val)) ) goto done; - _regs.eip = src.val; dst.type = OP_NONE; break; Reviewed-by: Andrew Cooper --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -652,13 +652,20 @@ do { _regs.eip = ip; \ } while (0) -#define validate_far_branch(cs, ip) \ - generate_exception_if(in_longmode(ctxt, ops) && (cs)->attr.fields.l \ - ? !is_canonical_address(ip) \ - : (ip) > (cs)->limit, EXC_GP, 0) +#define validate_far_branch(cs, ip) ({ \ + if ( sizeof(ip) <= 4 ) { \ + ASSERT(in_longmode(ctxt, ops) <= 0); \ + generate_exception_if((ip) > (cs)->limit, EXC_GP, 0); \ + } else \ + generate_exception_if(in_longmode(ctxt, ops) && \ + (cs)->attr.fields.l \ + ? !is_canonical_address(ip) \ + : (ip) > (cs)->limit, EXC_GP, 0); \ +}) #define commit_far_branch(cs, ip) ({ \ validate_far_branch(cs, ip); \ + _regs.eip = (ip); \ ops->write_segment(x86_seg_cs, cs, ctxt); \ }) @@ -2787,7 +2794,6 @@ x86_emulate( (rc = load_seg(x86_seg_cs, src.val, 1, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, dst.val)) ) goto done; - _regs.eip = dst.val; break; } @@ -2830,9 +2836,8 @@ x86_emulate( eflags &= 0x257fd5; _regs.eflags &= mask; _regs.eflags |= (eflags & ~mask) | 0x02; - _regs.eip = eip; if ( (rc = load_seg(x86_seg_cs, sel, 1, &cs, ctxt, ops)) || - (rc = commit_far_branch(&cs, eip)) ) + (rc = commit_far_branch(&cs, (uint32_t)eip)) ) goto done; break; } @@ -3465,7 +3470,6 @@ x86_emulate( if ( (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, eip)) ) goto done; - _regs.eip = eip; break; } @@ -3767,11 +3771,11 @@ x86_emulate( &_regs.eip, op_bytes, ctxt)) || (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) goto done; + _regs.eip = src.val; } else if ( (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, src.val)) ) goto done; - _regs.eip = src.val; dst.type = OP_NONE; break;