From patchwork Mon Nov 28 11:13:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 9449345 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 A539260235 for ; Mon, 28 Nov 2016 11:16:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9575220410 for ; Mon, 28 Nov 2016 11:16:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A2FB2675C; Mon, 28 Nov 2016 11:16:20 +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 0142020410 for ; Mon, 28 Nov 2016 11:16:20 +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 1cBJsd-0005PW-6e; Mon, 28 Nov 2016 11:13:51 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cBJsb-0005Od-Jj for xen-devel@lists.xen.org; Mon, 28 Nov 2016 11:13:49 +0000 Received: from [193.109.254.147] by server-7.bemta-6.messagelabs.com id 66/69-29519-C611C385; Mon, 28 Nov 2016 11:13:48 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmphkeJIrShJLcpLzFFi42JxWrrBXjdH0Cb CoGGzqsWSj4tZHBg9ju7+zRTAGMWamZeUX5HAmtE17wd7wV6zip97VrM2MD7W7mLk5JAQ8JeY teEuI4jNJqAvsfvFJyYQW0RAXeJ0x0XWLkYuDmaBZkaJdTt6gYo4OIQFHCWuNdqA1LAIqEr8m 3CZDcTmFfCQ+LP1MTvETDmJ88d/MoPYnAKeEkcmvWcCaRUCqun85wUSFhJQk7jWf4kdolVQ4u TMJywgNrOAhMTBFy+YJzDyzkKSmoUktYCRaRWjRnFqUVlqka6RuV5SUWZ6RkluYmaOrqGBmV5 uanFxYnpqTmJSsV5yfu4mRmDoMADBDsbFawMPMUpyMCmJ8t5+bB0hxJeUn1KZkVicEV9UmpNa fIhRhoNDSYI3QMAmQkiwKDU9tSItMwcYxDBpCQ4eJRHeb3xAad7igsTc4sx0iNQpRkUpcd7NI H0CIImM0jy4NljkXGKUlRLmZQQ6RIinILUoN7MEVf4VozgHo5IwLwfIFJ7MvBK46a+AFjMBLX 772hpkcUkiQkqqgXHHo0Nl7pdlOsSbOY6+rvTvqoqc7Pmy0+GfRW5i753T72XutafuL5SxSQz n2f6cfb7k08lfleXjJCexttj73dgu+qtr9/z9BpIJBk7V7ioRyVW9My6Vqsrv3NUb+i/35PmE jvne833/Zt2uuPpkRUjIO7ULdTqKhvdfR0ZYrbJVy9p/fofAASWW4oxEQy3mouJEADCyT2mXA gAA X-Env-Sender: prvs=1334ebad9=Andrew.Cooper3@citrix.com X-Msg-Ref: server-16.tower-27.messagelabs.com!1480331623!74060701!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.0.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 24835 invoked from network); 28 Nov 2016 11:13:48 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-16.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 28 Nov 2016 11:13:48 -0000 X-IronPort-AV: E=Sophos;i="5.31,563,1473120000"; d="scan'208";a="400418848" From: Andrew Cooper To: Xen-devel Date: Mon, 28 Nov 2016 11:13:20 +0000 Message-ID: <1480331616-6165-4-git-send-email-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1480331616-6165-1-git-send-email-andrew.cooper3@citrix.com> References: <1480331616-6165-1-git-send-email-andrew.cooper3@citrix.com> MIME-Version: 1.0 Cc: George Dunlap , Andrew Cooper , Paul Durrant Subject: [Xen-devel] [PATCH v2 03/19] x86/emul: Simplfy emulation state setup 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 The current code to set up emulation state is ad-hoc and error prone. * Consistently zero all emulation state structures. * Avoid explicitly initialising some state to 0. * Explicitly identify all input and output state in x86_emulate_ctxt. This involves rearanging some fields. * Have x86_decode() explicitly initalise all output state at its start. While making the above changes, two minor tweaks: * Move the calculation of hvmemul_ctxt->ctxt.swint_emulate from _hvm_emulate_one() to hvm_emulate_init_once(). It doesn't need recalculating for each instruction. * Change force_writeback to being a boolean, to match its use. Signed-off-by: Andrew Cooper Acked-by: Tim Deegan Reviewed-by: Jan Beulich Reviewed-by: Paul Durrant Reviewed-by: Paul Durrant --- CC: George Dunlap CC: Paul Durrant v2: * Split x86_emulate_ctxt into three sections --- xen/arch/x86/hvm/emulate.c | 28 +++++++++++++++------------- xen/arch/x86/mm.c | 14 ++++++++------ xen/arch/x86/mm/shadow/common.c | 4 ++-- xen/arch/x86/x86_emulate/x86_emulate.c | 1 + xen/arch/x86/x86_emulate/x86_emulate.h | 32 ++++++++++++++++++++++---------- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index f1f6e2f..3efeead 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -1770,13 +1770,6 @@ static int _hvm_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt, vio->mmio_retry = 0; - if ( cpu_has_vmx ) - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_none; - else if ( cpu_has_svm_nrips ) - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_icebp; - else - hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_all; - rc = x86_emulate(&hvmemul_ctxt->ctxt, ops); if ( rc == X86EMUL_OKAY && vio->mmio_retry ) @@ -1947,14 +1940,23 @@ void hvm_emulate_init_once( struct hvm_emulate_ctxt *hvmemul_ctxt, struct cpu_user_regs *regs) { - hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(current); - hvmemul_ctxt->ctxt.regs = regs; - hvmemul_ctxt->ctxt.force_writeback = 1; - hvmemul_ctxt->seg_reg_accessed = 0; - hvmemul_ctxt->seg_reg_dirty = 0; - hvmemul_ctxt->set_context = 0; + struct vcpu *curr = current; + + memset(hvmemul_ctxt, 0, sizeof(*hvmemul_ctxt)); + + hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(curr); hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt); hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt); + + hvmemul_ctxt->ctxt.regs = regs; + hvmemul_ctxt->ctxt.force_writeback = true; + + if ( cpu_has_vmx ) + hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_none; + else if ( cpu_has_svm_nrips ) + hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_icebp; + else + hvmemul_ctxt->ctxt.swint_emulate = x86_swint_emulate_all; } void hvm_emulate_init_per_insn( diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 5b0e9f3..d365f59 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5337,7 +5337,14 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, struct domain *d = v->domain; struct page_info *page; l1_pgentry_t pte; - struct ptwr_emulate_ctxt ptwr_ctxt; + struct ptwr_emulate_ctxt ptwr_ctxt = { + .ctxt = { + .regs = regs, + .addr_size = is_pv_32bit_domain(d) ? 32 : BITS_PER_LONG, + .sp_size = is_pv_32bit_domain(d) ? 32 : BITS_PER_LONG, + .swint_emulate = x86_swint_emulate_none, + }, + }; int rc; /* Attempt to read the PTE that maps the VA being accessed. */ @@ -5363,11 +5370,6 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, goto bail; } - ptwr_ctxt.ctxt.regs = regs; - ptwr_ctxt.ctxt.force_writeback = 0; - ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size = - is_pv_32bit_domain(d) ? 32 : BITS_PER_LONG; - ptwr_ctxt.ctxt.swint_emulate = x86_swint_emulate_none; ptwr_ctxt.cr2 = addr; ptwr_ctxt.pte = pte; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 7e5b8b0..a4a3c4b 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -385,8 +385,9 @@ const struct x86_emulate_ops *shadow_init_emulation( struct vcpu *v = current; unsigned long addr; + memset(sh_ctxt, 0, sizeof(*sh_ctxt)); + sh_ctxt->ctxt.regs = regs; - sh_ctxt->ctxt.force_writeback = 0; sh_ctxt->ctxt.swint_emulate = x86_swint_emulate_none; if ( is_pv_vcpu(v) ) @@ -396,7 +397,6 @@ const struct x86_emulate_ops *shadow_init_emulation( } /* Segment cache initialisation. Primed with CS. */ - sh_ctxt->valid_seg_regs = 0; creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt); /* Work out the emulation mode. */ diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index d82e85d..532bd32 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1904,6 +1904,7 @@ x86_decode( state->regs = ctxt->regs; state->eip = ctxt->regs->eip; + /* Initialise output state in x86_emulate_ctxt */ ctxt->retire.byte = 0; op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8; diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h b/xen/arch/x86/x86_emulate/x86_emulate.h index ec824ce..ab566c0 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.h +++ b/xen/arch/x86/x86_emulate/x86_emulate.h @@ -410,6 +410,23 @@ struct cpu_user_regs; struct x86_emulate_ctxt { + /* + * Input-only state: + */ + + /* Software event injection support. */ + enum x86_swint_emulation swint_emulate; + + /* Set this if writes may have side effects. */ + bool force_writeback; + + /* Caller data that can be used by x86_emulate_ops' routines. */ + void *data; + + /* + * Input/output state: + */ + /* Register state before/after emulation. */ struct cpu_user_regs *regs; @@ -419,14 +436,12 @@ struct x86_emulate_ctxt /* Stack pointer width in bits (16, 32 or 64). */ unsigned int sp_size; - /* Canonical opcode (see below). */ - unsigned int opcode; - - /* Software event injection support. */ - enum x86_swint_emulation swint_emulate; + /* + * Output-only state: + */ - /* Set this if writes may have side effects. */ - uint8_t force_writeback; + /* Canonical opcode (see below) (valid only on X86EMUL_OKAY). */ + unsigned int opcode; /* Retirement state, set by the emulator (valid only on X86EMUL_OKAY). */ union { @@ -437,9 +452,6 @@ struct x86_emulate_ctxt } flags; uint8_t byte; } retire; - - /* Caller data that can be used by x86_emulate_ops' routines. */ - void *data; }; /*