From patchwork Fri Oct 14 09:37:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9376315 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 A18A460779 for ; Fri, 14 Oct 2016 09:39:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9067D2A594 for ; Fri, 14 Oct 2016 09:39:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 850652A596; Fri, 14 Oct 2016 09:39:25 +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 872042A594 for ; Fri, 14 Oct 2016 09:39:24 +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 1buyvQ-0001Qd-R7; Fri, 14 Oct 2016 09:37:12 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1buyvP-0001QX-GA for xen-devel@lists.xenproject.org; Fri, 14 Oct 2016 09:37:11 +0000 Received: from [85.158.137.68] by server-1.bemta-3.messagelabs.com id 7D/70-12967-647A0085; Fri, 14 Oct 2016 09:37:10 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrEIsWRWlGSWpSXmKPExsXS6fjDS9d1OUO EwYJ7+hbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8an7qmsBS2uFU+nLmdqYJyg18XIySEkkCdx Zt4ZNhCbV8BOYs2aRmYQW0LAUOLp++tAcQ4OFgFViXcX7UDCbALqEm3PtrOChEUEDCTOHU0CM ZkF9CW2rWMBqRAWsJa433wWrIJXQFDi7w5hkDAz0OwHMzrZJzByzULIzEKSgbC1JB7+usUCYW tLLFv4mnkW2HxpieX/OCDCNhKLez+jKQGx3SWuPHvFtICRYxWjenFqUVlqka6hXlJRZnpGSW5 iZo6uoYGxXm5qcXFiempOYlKxXnJ+7iZGYNgxAMEOxuUfnQ4xSnIwKYny1uoxRAjxJeWnVGYk FmfEF5XmpBYfYpTh4FCS4I1YBpQTLEpNT61Iy8wBRgBMWoKDR0mEd8pSoDRvcUFibnFmOkTqF KOilDjvMpA+AZBERmkeXBss6i4xykoJ8zICHSLEU5BalJtZgir/ilGcg1FJmHcJyHiezLwSuO mvgBYzAS3+0Aa2uCQRISXVwHjSdOO/9XsKuJNMl9TbzPCafOj04soA5/I62YNOSRMy1a5ZvHb bIvfk9bn6V5HJIg9/CCWkhq9jDViw6xzj6UrHFYWrtkZdiIm6pOT8d/uKHzuk1Oc6T37o9uQ1 g/tSxbOaAS9YP3qIBp3KLO4qveh8uvzau+RjlQscyxvk5k5sTphz6vmTD1pKLMUZiYZazEXFi QDB78iTtQIAAA== X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-14.tower-31.messagelabs.com!1476437827!66131600!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.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23348 invoked from network); 14 Oct 2016 09:37:09 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-14.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 14 Oct 2016 09:37:09 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Fri, 14 Oct 2016 03:37:06 -0600 Message-Id: <5800C36302000078001174EF@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Fri, 14 Oct 2016 03:37:07 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper Subject: [Xen-devel] [PATCH] x86emul: fix pushing of selector registers 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 Both explicit PUSH and far CALL currently push unrelated data (the segment attributes word) in the high half (attributes and limit in the 64-bit case in the high 48 bits) instead of zero. To avoid having to apply this and further changes in multiple places, also fold the two (respectively) far call/jmp instances into one. Signed-off-by: Jan Beulich x86emul: fix pushing of selector registers Both explicit PUSH and far CALL currently push unrelated data (the segment attributes word) in the high half (attributes and limit in the 64-bit case in the high 48 bits) instead of zero. To avoid having to apply this and further changes in multiple places, also fold the two (respectively) far call/jmp instances into one. Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2636,13 +2636,8 @@ x86_emulate( fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(src.val, &sreg, ctxt)) != 0 ) goto done; - /* 64-bit mode: PUSH defaults to a 64-bit operand. */ - if ( mode_64bit() && (op_bytes == 4) ) - op_bytes = 8; - if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) != 0 ) - goto done; - break; + src.val = sreg.sel; + goto push; case 0x07: /* pop %%es */ src.val = x86_seg_es; @@ -3057,13 +3052,15 @@ x86_emulate( case 0x9a: /* call (far, absolute) */ ASSERT(!mode_64bit()); + far_call: fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (validate_far_branch(&cs, imm1), + src.val = sreg.sel, rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || + &src.val, op_bytes, ctxt)) || (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), &_regs.eip, op_bytes, ctxt)) || (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) @@ -4018,6 +4015,7 @@ x86_emulate( case 0xea: /* jmp (far, absolute) */ ASSERT(!mode_64bit()); + far_jmp: if ( (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, imm1)) ) goto done; @@ -4281,36 +4279,16 @@ x86_emulate( dst.type = OP_NONE; break; case 3: /* call (far, absolute indirect) */ - case 5: /* jmp (far, absolute indirect) */ { - unsigned long sel; - + case 5: /* jmp (far, absolute indirect) */ generate_exception_if(src.type != OP_MEM, EXC_UD, -1); if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes, - &sel, 2, ctxt, ops)) ) + &imm2, 2, ctxt, ops)) ) goto done; - - if ( (modrm_reg & 7) == 3 ) /* call */ - { - fail_if(ops->read_segment == NULL); - if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || - (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || - (validate_far_branch(&cs, src.val), - rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || - (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &_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; - - dst.type = OP_NONE; - break; - } + imm1 = src.val; + if ( !(modrm_reg & 4) ) + goto far_call; + goto far_jmp; case 6: /* push */ goto push; case 7: Reviewed-by: Andrew Cooper --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2636,13 +2636,8 @@ x86_emulate( fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(src.val, &sreg, ctxt)) != 0 ) goto done; - /* 64-bit mode: PUSH defaults to a 64-bit operand. */ - if ( mode_64bit() && (op_bytes == 4) ) - op_bytes = 8; - if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) != 0 ) - goto done; - break; + src.val = sreg.sel; + goto push; case 0x07: /* pop %%es */ src.val = x86_seg_es; @@ -3057,13 +3052,15 @@ x86_emulate( case 0x9a: /* call (far, absolute) */ ASSERT(!mode_64bit()); + far_call: fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (validate_far_branch(&cs, imm1), + src.val = sreg.sel, rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || + &src.val, op_bytes, ctxt)) || (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), &_regs.eip, op_bytes, ctxt)) || (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) @@ -4018,6 +4015,7 @@ x86_emulate( case 0xea: /* jmp (far, absolute) */ ASSERT(!mode_64bit()); + far_jmp: if ( (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, imm1)) ) goto done; @@ -4281,36 +4279,16 @@ x86_emulate( dst.type = OP_NONE; break; case 3: /* call (far, absolute indirect) */ - case 5: /* jmp (far, absolute indirect) */ { - unsigned long sel; - + case 5: /* jmp (far, absolute indirect) */ generate_exception_if(src.type != OP_MEM, EXC_UD, -1); if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes, - &sel, 2, ctxt, ops)) ) + &imm2, 2, ctxt, ops)) ) goto done; - - if ( (modrm_reg & 7) == 3 ) /* call */ - { - fail_if(ops->read_segment == NULL); - if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || - (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || - (validate_far_branch(&cs, src.val), - rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || - (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &_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; - - dst.type = OP_NONE; - break; - } + imm1 = src.val; + if ( !(modrm_reg & 4) ) + goto far_call; + goto far_jmp; case 6: /* push */ goto push; case 7: