All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>,
	xen-devel <xen-devel@lists.xenproject.org>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: Re: [PATCH v2 08/16] SVM: use generic instruction decoding
Date: Thu, 29 Sep 2016 20:24:23 +0100	[thread overview]
Message-ID: <b609a86a-a954-79c2-0c81-9c180a4366ab@citrix.com> (raw)
In-Reply-To: <57EB97AD02000078001131CB@prv-mh.provo.novell.com>

On 28/09/16 09:13, Jan Beulich wrote:
> ... instead of custom handling. To facilitate this break out init code
> from _hvm_emulate_one() into the new hvm_emulate_init(), and make
> hvmemul_insn_fetch( globally available.

)

>  int __get_instruction_length_from_list(struct vcpu *v,
>          const enum instruction_index *list, unsigned int list_count)
>  {
>      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
> -    unsigned int i, j, inst_len = 0;
> -    enum instruction_index instr = 0;
> -    u8 buf[MAX_INST_LEN];
> -    const u8 *opcode = NULL;
> -    unsigned long fetch_addr, fetch_limit;
> -    unsigned int fetch_len, max_len;
> +    struct hvm_emulate_ctxt ctxt;
> +    struct x86_emulate_state *state;
> +    unsigned int inst_len, j, modrm_rm, modrm_reg;
> +    int modrm_mod;
>  

Despite knowing how this works, it is still confusing to read.  Do you
mind putting in a comment such as:

/* In a debug build, always use x86_decode_insn() and compare with
hardware. */

> +#ifdef NDEBUG
>      if ( (inst_len = svm_nextrip_insn_length(v)) != 0 )
>          return inst_len;
>  
>      if ( vmcb->exitcode == VMEXIT_IOIO )
>          return vmcb->exitinfo2 - vmcb->rip;
> +#endif
>  
> -    /* Fetch up to the next page break; we'll fetch from the next page
> -     * later if we have to. */
> -    fetch_addr = svm_rip2pointer(v, &fetch_limit);
> -    if ( vmcb->rip > fetch_limit )
> -        return 0;
> -    max_len = min(fetch_limit - vmcb->rip + 1, MAX_INST_LEN + 0UL);
> -    fetch_len = min_t(unsigned int, max_len,
> -                      PAGE_SIZE - (fetch_addr & ~PAGE_MASK));
> -    if ( !fetch(vmcb, buf, fetch_addr, fetch_len) )
> +    ASSERT(v == current);
> +    hvm_emulate_prepare(&ctxt, guest_cpu_user_regs());
> +    hvm_emulate_init(&ctxt, NULL, 0);
> +    state = x86_decode_insn(&ctxt.ctxt, hvmemul_insn_fetch);
> +    if ( IS_ERR_OR_NULL(state) )
>          return 0;
>  
> -    while ( (inst_len < max_len) && is_prefix(buf[inst_len]) )
> -    {
> -        inst_len++;
> -        if ( inst_len >= fetch_len )
> -        {
> -            if ( !fetch(vmcb, buf + fetch_len, fetch_addr + fetch_len,
> -                        max_len - fetch_len) )
> -                return 0;
> -            fetch_len = max_len;
> -        }
> +    inst_len = x86_insn_length(state, &ctxt.ctxt);
> +    modrm_mod = x86_insn_modrm(state, &modrm_rm, &modrm_reg);
> +    x86_emulate_free_state(state);
> +#ifndef NDEBUG
> +    if ( vmcb->exitcode == VMEXIT_IOIO )
> +        j = vmcb->exitinfo2 - vmcb->rip;
> +    else
> +        j = svm_nextrip_insn_length(v);
> +    if ( j && j != inst_len )
> +    {
> +        gprintk(XENLOG_WARNING, "insn-len[%02x]=%u (exp %u)\n",
> +                ctxt.ctxt.opcode, inst_len, j);
> +        return j;
>      }
> +#endif
>  
>      for ( j = 0; j < list_count; j++ )
>      {
> -        instr = list[j];
> -        opcode = opc_bytes[instr];
> +        enum instruction_index instr = list[j];
>  
> -        for ( i = 0; (i < opcode[0]) && ((inst_len + i) < max_len); i++ )
> +        ASSERT(instr >= 0 && instr < ARRAY_SIZE(opc_tab));

This is another ASSERT() used as a bounds check, and will suffer a build
failure on clang.

You need to use s/enum instruction_index/unsigned int/ to fix the build
issue.  Can I also request the use of

if ( instr >= ARRAY_SIZE(opc_tab) )
{
    ASSERT_UNREACHABLE();
    return 0;
}

instead?

> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -5200,3 +5214,89 @@ x86_emulate(
>  #undef vex
>  #undef override_seg
>  #undef ea
> +
> +#ifdef __XEN__
> +
> +#include <xen/err.h>
> +
> +struct x86_emulate_state *
> +x86_decode_insn(
> +    struct x86_emulate_ctxt *ctxt,
> +    int (*insn_fetch)(
> +        enum x86_segment seg, unsigned long offset,
> +        void *p_data, unsigned int bytes,
> +        struct x86_emulate_ctxt *ctxt))
> +{
> +    static DEFINE_PER_CPU(struct x86_emulate_state, state);
> +    struct x86_emulate_state *state = &this_cpu(state);
> +    const struct x86_emulate_ops ops = {

This can be static, to avoid having it reconstructed on the stack each
function call.

Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  reply	other threads:[~2016-09-29 19:24 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-28  7:59 [PATCH v2 00/16] x86: split insn emulator decode and execution Jan Beulich
2016-09-28  8:06 ` [PATCH v2 01/16] x86emul: split instruction decoding from execution Jan Beulich
2016-09-28 16:24   ` Andrew Cooper
2016-09-28  8:07 ` [PATCH v2 02/16] x86emul: fetch all insn bytes during the decode phase Jan Beulich
2016-09-28 16:37   ` Andrew Cooper
2016-09-28  8:08 ` [PATCH v2 03/16] x86emul: track only rIP in emulator state Jan Beulich
2016-09-28 16:41   ` Andrew Cooper
2016-09-28  8:08 ` [PATCH v2 04/16] x86emul: complete decoding of two-byte instructions Jan Beulich
2016-09-28 17:22   ` Andrew Cooper
2016-09-29  6:37     ` Jan Beulich
2016-09-28  8:09 ` [PATCH v2 05/16] x86emul: add XOP decoding Jan Beulich
2016-09-29  9:07   ` Andrew Cooper
2016-09-28  8:10 ` [PATCH v2 06/16] x86emul: add EVEX decoding Jan Beulich
2016-09-29  9:08   ` Andrew Cooper
2016-09-28  8:12 ` [PATCH v2 07/16] x86emul: generate and make use of a canonical opcode representation Jan Beulich
2016-09-29 10:11   ` Andrew Cooper
2016-09-28  8:13 ` [PATCH v2 08/16] SVM: use generic instruction decoding Jan Beulich
2016-09-29 19:24   ` Andrew Cooper [this message]
2016-09-29 19:30     ` Andrew Cooper
2016-09-30  8:32     ` Jan Beulich
2016-09-28  8:13 ` [PATCH v2 09/16] x86/32on64: use generic instruction decoding for call gate emulation Jan Beulich
2016-09-29 19:47   ` Andrew Cooper
2016-09-30  7:30     ` Jan Beulich
2016-09-28  8:14 ` [PATCH v2 10/16] x86/PV: split out dealing with CRn from privileged instruction handling Jan Beulich
2016-09-29 20:01   ` Andrew Cooper
2016-09-30  7:12     ` Jan Beulich
2016-09-28  8:15 ` [PATCH v2 11/16] x86/PV: split out dealing with DRn " Jan Beulich
2016-09-29 20:13   ` Andrew Cooper
2016-09-30  7:16     ` Jan Beulich
2016-09-28  8:16 ` [PATCH v2 12/16] x86/PV: split out dealing with MSRs " Jan Beulich
2016-09-29 20:44   ` Andrew Cooper
2016-09-28  8:17 ` [PATCH v2 13/16] x86emul: support XSETBV Jan Beulich
2016-09-29 20:45   ` Andrew Cooper
2016-09-30  8:05     ` Jan Beulich
2016-09-28  8:18 ` [PATCH v2 14/16] x86emul: sort opcode 0f01 special case switch() statement Jan Beulich
2016-09-29 20:46   ` Andrew Cooper
2016-09-28  8:18 ` [PATCH v2 15/16] x86/PV: use generic emulator for privileged instruction handling Jan Beulich
2016-09-29 21:06   ` Andrew Cooper
2016-09-30  8:55     ` Jan Beulich
2016-09-28  8:19 ` [PATCH v2 16/16] x86emul: don't assume a memory operand Jan Beulich
2016-09-29 21:12   ` Andrew Cooper
2016-09-30  8:25     ` Jan Beulich
2016-09-28  8:42 ` [PATCH v2 00/16] x86: split insn emulator decode and execution Jan Beulich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b609a86a-a954-79c2-0c81-9c180a4366ab@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.