From patchwork Wed Jun 21 08:57:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Liu X-Patchwork-Id: 9801233 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 7B6BD6038C for ; Wed, 21 Jun 2017 09:00:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3D0BB2859E for ; Wed, 21 Jun 2017 09:00:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39F6E28372; Wed, 21 Jun 2017 09:00:13 +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 AED1227F9A for ; Wed, 21 Jun 2017 09:00:08 +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 1dNbSI-00047Q-2H; Wed, 21 Jun 2017 08:57:42 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dNbSG-00047K-RU for xen-devel@lists.xenproject.org; Wed, 21 Jun 2017 08:57:40 +0000 Received: from [85.158.143.35] by server-3.bemta-6.messagelabs.com id F1/B7-03058-4053A495; Wed, 21 Jun 2017 08:57:40 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrOIsWRWlGSWpSXmKPExsXitHRDpC6zqVe kwb1JWhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8aRu8YFp7wqVu5pYmlg/GjdxcjJISHgL/F4 zk52EJtFQFViyvRfjCA2m4CyxM/OXjYQWwTI7v31mwXEZhaolNj3dw1YvbCAi8Tb5ptgNbwCF hI7PzcwdTFycQgJ/GGUOL19LwtEQlDi5MwnUM06Egt2fwJq4ACypSWW/+MACXMK2Et8u3UNbI 6ogIpE59I5YOVCAgoSHdOPMU1g5JuFZNIsJJNmIUxawMi8ilGjOLWoLLVI19BUL6koMz2jJDc xM0fX0MBMLze1uDgxPTUnMalYLzk/dxMjMNAYgGAH47dlAYcYJTmYlER5L8h6RQrxJeWnVGYk FmfEF5XmpBYfYpTh4FCS4L1rDJQTLEpNT61Iy8wBhjxMWoKDR0mE97kRUJq3uCAxtzgzHSJ1i lGXY0HPhi9MQix5+XmpUuK8C0FmCIAUZZTmwY2Axd8lRlkpYV5GoKOEeApSi3IzS1DlXzGKcz AqCfOGmwBN4cnMK4Hb9AroCCagI14c8QA5oiQRISXVwKhrHPy7eKKQlvUT+effP05Y8LPAhKF QweSCdnFI3TvJHdMSH0+prd3UXLbid/gcte3fNuevzl0Y1d1cr3yIfc3pBc0rfu3iV/yqxr9h VU++zbfFZTVZiluelKpOWK7w4qaeV7ZZgJyQUo+Wi6XZjKtKPdOqVk8QZTCdc3d6b8JEo8CFy z+vMFZiKc5INNRiLipOBADurnFAugIAAA== X-Env-Sender: prvs=3381a6b98=wei.liu2@citrix.com X-Msg-Ref: server-5.tower-21.messagelabs.com!1498035458!66934385!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.19; banners=-,-,- X-VirusChecked: Checked Received: (qmail 21001 invoked from network); 21 Jun 2017 08:57:39 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-5.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 21 Jun 2017 08:57:39 -0000 X-IronPort-AV: E=Sophos;i="5.39,368,1493683200"; d="scan'208";a="428772935" Date: Wed, 21 Jun 2017 09:57:31 +0100 From: Wei Liu To: Jan Beulich Message-ID: <20170621085731.xrmxq3lao4hd4od3@citrix.com> References: <20170608171203.20416-1-wei.liu2@citrix.com> <20170608171203.20416-5-wei.liu2@citrix.com> <594967A70200007800164D29@prv-mh.provo.novell.com> <20170620162529.j25maj5jud766n6i@citrix.com> <594A2B320200007800164F37@prv-mh.provo.novell.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <594A2B320200007800164F37@prv-mh.provo.novell.com> User-Agent: NeoMutt/20170113 (1.7.2) Cc: Andrew Cooper , Wei Liu , Xen-devel Subject: Re: [Xen-devel] [PATCH v4 04/27] x86: move PV invalid op emulation code 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 On Wed, Jun 21, 2017 at 12:15:46AM -0600, Jan Beulich wrote: > >>> On 20.06.17 at 18:25, wrote: > > On Tue, Jun 20, 2017 at 10:21:27AM -0600, Jan Beulich wrote: > >> >>> On 08.06.17 at 19:11, wrote: > >> > @@ -1053,8 +982,8 @@ void do_invalid_op(struct cpu_user_regs *regs) > >> > > >> > if ( likely(guest_mode(regs)) ) > >> > { > >> > - if ( !emulate_invalid_rdtscp(regs) && > >> > - !emulate_forced_invalid_op(regs) ) > >> > + if ( !pv_emulate_invalid_rdtscp(regs) && > >> > + !pv_emulate_forced_invalid_op(regs) ) > >> > >> I wonder if the first couldn't be called by the second, making it > >> unnecessary to export both. Or maybe have a wrapper > >> pv_emulate_invalid_op() around both. > >> > > > > Do you want me to refactor and move code in the same patch? Wouldn't > > that make it hard for you to review? > > Why - especially in the wrapper variant you'd move both functions > unchanged (perhaps even with the names left as they are), and > merely add the wrapper (and of course use it in the code fragment > above). That'll make review rather simple, as you'll still be able to > state that you left both existing functions unchanged. OK ---8<--- From 50dfe1fe116c28a3953f0b72acc7b1dee4136e2b Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Mon, 5 Jun 2017 13:07:16 +0100 Subject: [PATCH] x86: move PV invalid op emulation code Move the code to pv/emul-inv-op.c. Both functions are unchanged. Provide pv_emulate_invalid_op and use it in traps.c. Signed-off-by: Wei Liu --- xen/arch/x86/pv/Makefile | 1 + xen/arch/x86/pv/emul-inv-op.c | 128 +++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/traps.c | 74 +----------------------- xen/include/asm-x86/pv/traps.h | 2 + 4 files changed, 132 insertions(+), 73 deletions(-) create mode 100644 xen/arch/x86/pv/emul-inv-op.c diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile index 1f6fbd3f5c..42ca64dc9e 100644 --- a/xen/arch/x86/pv/Makefile +++ b/xen/arch/x86/pv/Makefile @@ -5,5 +5,6 @@ obj-bin-y += dom0_build.init.o obj-y += domain.o obj-y += emulate.o obj-y += emul-gate-op.o +obj-y += emul-inv-op.o obj-y += emul-priv-op.o obj-bin-y += gpr_switch.o diff --git a/xen/arch/x86/pv/emul-inv-op.c b/xen/arch/x86/pv/emul-inv-op.c new file mode 100644 index 0000000000..a1c56da171 --- /dev/null +++ b/xen/arch/x86/pv/emul-inv-op.c @@ -0,0 +1,128 @@ +/****************************************************************************** + * arch/x86/pv/emul-inv-op.c + * + * Emulate invalid op for PV guests + * + * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser + * + * 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "emulate.h" + +static int emulate_invalid_rdtscp(struct cpu_user_regs *regs) +{ + char opcode[3]; + unsigned long eip, rc; + struct vcpu *v = current; + + eip = regs->rip; + if ( (rc = copy_from_user(opcode, (char *)eip, sizeof(opcode))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(opcode) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(opcode, "\xf\x1\xf9", sizeof(opcode)) ) + return 0; + eip += sizeof(opcode); + pv_soft_rdtsc(v, regs, 1); + pv_emul_instruction_done(regs, eip); + return EXCRET_fault_fixed; +} + +static int emulate_forced_invalid_op(struct cpu_user_regs *regs) +{ + char sig[5], instr[2]; + unsigned long eip, rc; + struct cpuid_leaf res; + + eip = regs->rip; + + /* Check for forced emulation signature: ud2 ; .ascii "xen". */ + if ( (rc = copy_from_user(sig, (char *)eip, sizeof(sig))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(sig) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(sig, "\xf\xbxen", sizeof(sig)) ) + return 0; + eip += sizeof(sig); + + /* We only emulate CPUID. */ + if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(instr) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(instr, "\xf\xa2", sizeof(instr)) ) + return 0; + + /* If cpuid faulting is enabled and CPL>0 inject a #GP in place of #UD. */ + if ( current->arch.cpuid_faulting && !guest_kernel_mode(current, regs) ) + { + regs->rip = eip; + pv_inject_hw_exception(TRAP_gp_fault, regs->error_code); + return EXCRET_fault_fixed; + } + + eip += sizeof(instr); + + guest_cpuid(current, regs->eax, regs->ecx, &res); + + regs->rax = res.a; + regs->rbx = res.b; + regs->rcx = res.c; + regs->rdx = res.d; + + pv_emul_instruction_done(regs, eip); + + trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->rip); + + return EXCRET_fault_fixed; +} + +int pv_emulate_invalid_op(struct cpu_user_regs *regs) +{ + return !emulate_invalid_rdtscp(regs) && !emulate_forced_invalid_op(regs); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 7b781f17db..88dfd464e7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -968,77 +968,6 @@ void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, } } -static int emulate_invalid_rdtscp(struct cpu_user_regs *regs) -{ - char opcode[3]; - unsigned long eip, rc; - struct vcpu *v = current; - - eip = regs->rip; - if ( (rc = copy_from_user(opcode, (char *)eip, sizeof(opcode))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(opcode) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(opcode, "\xf\x1\xf9", sizeof(opcode)) ) - return 0; - eip += sizeof(opcode); - pv_soft_rdtsc(v, regs, 1); - pv_emul_instruction_done(regs, eip); - return EXCRET_fault_fixed; -} - -static int emulate_forced_invalid_op(struct cpu_user_regs *regs) -{ - char sig[5], instr[2]; - unsigned long eip, rc; - struct cpuid_leaf res; - - eip = regs->rip; - - /* Check for forced emulation signature: ud2 ; .ascii "xen". */ - if ( (rc = copy_from_user(sig, (char *)eip, sizeof(sig))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(sig) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(sig, "\xf\xbxen", sizeof(sig)) ) - return 0; - eip += sizeof(sig); - - /* We only emulate CPUID. */ - if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(instr) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(instr, "\xf\xa2", sizeof(instr)) ) - return 0; - - /* If cpuid faulting is enabled and CPL>0 inject a #GP in place of #UD. */ - if ( current->arch.cpuid_faulting && !guest_kernel_mode(current, regs) ) - { - regs->rip = eip; - pv_inject_hw_exception(TRAP_gp_fault, regs->error_code); - return EXCRET_fault_fixed; - } - - eip += sizeof(instr); - - guest_cpuid(current, regs->eax, regs->ecx, &res); - - regs->rax = res.a; - regs->rbx = res.b; - regs->rcx = res.c; - regs->rdx = res.d; - - pv_emul_instruction_done(regs, eip); - - trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->rip); - - return EXCRET_fault_fixed; -} - void do_invalid_op(struct cpu_user_regs *regs) { const struct bug_frame *bug = NULL; @@ -1053,8 +982,7 @@ void do_invalid_op(struct cpu_user_regs *regs) if ( likely(guest_mode(regs)) ) { - if ( !emulate_invalid_rdtscp(regs) && - !emulate_forced_invalid_op(regs) ) + if ( pv_emulate_invalid_op(regs) ) pv_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } diff --git a/xen/include/asm-x86/pv/traps.h b/xen/include/asm-x86/pv/traps.h index b1b6b1d0ad..458028a94b 100644 --- a/xen/include/asm-x86/pv/traps.h +++ b/xen/include/asm-x86/pv/traps.h @@ -27,11 +27,13 @@ int pv_emulate_privileged_op(struct cpu_user_regs *regs); void pv_emulate_gate_op(struct cpu_user_regs *regs); +int pv_emulate_invalid_op(struct cpu_user_regs *regs); #else /* !CONFIG_PV */ static inline int pv_emulate_privileged_op(struct cpu_user_regs *regs) { return 0; } static inline void pv_emulate_gate_op(struct cpu_user_regs *regs) {} +static int pv_emulate_invalid_op(struct cpu_user_regs *regs) { return 0; } #endif /* CONFIG_PV */