All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: xen-devel <xen-devel@lists.xenproject.org>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: Re: [PATCH 09/17] SVM: use generic instruction decoding
Date: Thu, 15 Sep 2016 00:55:19 -0600	[thread overview]
Message-ID: <57DA61F7020000780010F124@prv-mh.provo.novell.com> (raw)
In-Reply-To: <c0d3de11-25d8-2df9-cde2-ea08385813a3@citrix.com>

>>> On 14.09.16 at 19:56, <andrew.cooper3@citrix.com> wrote:
> On 08/09/16 14:14, Jan Beulich wrote:
>>  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;
>>  
>> +#ifdef NDEBUG
> 
> Presumably this is just for your testing?

No, I actually meant it to stay that way. Along the lines of the extra
debugging code we have in map_domain_page().

>>      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);
> 
> From an API point of view, it is weird to have x86_emulate_free_state()
> without a matching allocation function.  Perhaps that is just me.

With x86_decode_insn() returning the state, that to me _is_ the
allocation function.

> However, the x86_insn_modrm() API is definitely more weird.  Wouldn't it
> be more natural to take optional pointers for the mod, rm and reg parts
> individually?

I could change it to that, but I did it this way because without mod
at least rm is meaningless. Or said differently, I can't really see there
being a caller not caring about mod.

>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
>> @@ -382,7 +382,7 @@ struct operand {
>>      } mem;
>>  };
>>  #ifdef __x86_64__
>> -#define REG_POISON ((unsigned long *) 0x8086000000008086UL) /* non-canonical */
>> +#define REG_POISON ((void *)0x8086000000008086UL) /* non-canonical */
>>  #else
>>  #define REG_POISON NULL /* 32-bit builds are for user-space, so NULL is OK. */
>>  #endif
> 
> Given that these are now used for general pointer poisoning, they should
> be renamed.  There are only 3 instances.

Okay. I'll make the PTR_POISON then.

>> @@ -1658,6 +1662,11 @@ x86_decode_base(
>>  
>>      switch ( ctxt->opcode )
>>      {
>> +    case 0x90: /* nop / pause */
>> +        if ( repe_prefix() )
>> +            ctxt->opcode |= X86EMUL_OPC_F3(0, 0);
>> +        break;
> 
> Why is it necessary to special case the rep prefix handling in this case?

Because SVM's pause intercept should not mistakenly also accept a
plain NOP.

>> +unsigned int
>> +x86_insn_length(const struct x86_emulate_state *state,
>> +                const struct x86_emulate_ctxt *ctxt)
>> +{
>> +    check_state(state);
>> +
>> +    return state->eip - ctxt->regs->eip;
> 
> Is it worth stashing a starting eip?  This calculation will go wrong
> after the emulated state has been committed.

This function (taking a state parameter) can't be called by users of
x86_emulate(), and I don't think we need to cater for callers
committing state themselves - they should clearly use the result of
this function for what to commit in the first place.

Jan

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

  reply	other threads:[~2016-09-15  6:55 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-08 12:58 [PATCH 00/17] x86: split insn emulator decode and execution Jan Beulich
2016-09-08 13:04 ` [PATCH 01/17] x86emul: split instruction decoding from execution Jan Beulich
2016-09-09 18:35   ` Andrew Cooper
2016-09-12  7:20     ` Jan Beulich
2016-09-08 13:07 ` [PATCH 02/17] x86emul: fetch all insn bytes during the decode phase Jan Beulich
2016-09-13 18:44   ` Andrew Cooper
2016-09-14  9:55     ` Jan Beulich
2016-09-23 14:48       ` Andrew Cooper
2016-09-23 15:04         ` Jan Beulich
2016-09-08 13:08 ` [PATCH 04/17] x86emul: track only rIP in emulator state Jan Beulich
2016-09-08 13:23   ` Jan Beulich
2016-09-08 13:09 ` [PATCH 03/17] " Jan Beulich
2016-09-13 19:09   ` Andrew Cooper
2016-09-14  9:58     ` Jan Beulich
2016-09-08 13:10 ` [PATCH 04/17] x86emul: complete decoding of two-byte instructions Jan Beulich
2016-09-14 14:22   ` Andrew Cooper
2016-09-14 15:05     ` Jan Beulich
2016-09-23 16:34       ` Andrew Cooper
2016-09-26  7:34         ` Jan Beulich
2016-09-27 13:28           ` Andrew Cooper
2016-09-27 13:51             ` Jan Beulich
2016-09-08 13:11 ` [PATCH 05/17] x86emul: add XOP decoding Jan Beulich
2016-09-14 16:11   ` Andrew Cooper
2016-09-14 16:21     ` Jan Beulich
2016-09-23 17:01       ` Andrew Cooper
2016-09-08 13:12 ` [PATCH 06/17] x86emul: add EVEX decoding Jan Beulich
2016-09-14 17:05   ` Andrew Cooper
2016-09-15  6:26     ` Jan Beulich
2016-09-08 13:13 ` [PATCH 07/17] x86emul: move x86_execute() common epilogue code Jan Beulich
2016-09-08 13:28   ` Jan Beulich
2016-09-14 17:13   ` Andrew Cooper
2016-09-08 13:14 ` [PATCH 08/17] x86emul: generate and make use of canonical opcode representation Jan Beulich
2016-09-14 17:30   ` Andrew Cooper
2016-09-15  6:43     ` Jan Beulich
2016-09-27 14:03       ` Andrew Cooper
2016-09-28  7:24         ` Jan Beulich
2016-09-08 13:14 ` [PATCH 09/17] SVM: use generic instruction decoding Jan Beulich
2016-09-14 17:56   ` Andrew Cooper
2016-09-15  6:55     ` Jan Beulich [this message]
2016-09-27 13:42       ` Andrew Cooper
2016-09-27 13:56         ` Jan Beulich
2016-09-27 15:53           ` Andrew Cooper
2016-09-08 13:16 ` [PATCH 10/17] x86/32on64: use generic instruction decoding for call gate emulation Jan Beulich
2016-09-08 13:17 ` [PATCH 11/17] x86/PV: split out dealing with CRn from privileged instruction handling Jan Beulich
2016-09-08 13:17 ` [PATCH 12/17] x86/PV: split out dealing with DRn " Jan Beulich
2016-09-08 13:18 ` [PATCH 13/17] x86/PV: split out dealing with MSRs " Jan Beulich
2016-09-08 13:18 ` [PATCH 14/17] x86emul: support XSETBV Jan Beulich
2016-09-08 13:19 ` [PATCH 15/17] x86emul: sort opcode 0f01 special case switch() statement Jan Beulich
2016-09-08 13:20 ` [PATCH 16/17] x86/PV: use generic emulator for privileged instruction handling Jan Beulich
2016-09-08 13:21 ` [PATCH 17/17] x86emul: don't assume a memory operand 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=57DA61F7020000780010F124@prv-mh.provo.novell.com \
    --to=jbeulich@suse.com \
    --cc=andrew.cooper3@citrix.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.