All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sergey Dyasli <sergey.dyasli@citrix.com>
To: "JBeulich@suse.com" <JBeulich@suse.com>
Cc: Sergey Dyasli <sergey.dyasli@citrix.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Andrew Cooper <Andrew.Cooper3@citrix.com>,
	"jun.nakajima@intel.com" <jun.nakajima@intel.com>,
	"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: [PATCH v2 1/4] x86/vmx: introduce vmwrite_safe()
Date: Tue, 7 Feb 2017 15:06:46 +0000	[thread overview]
Message-ID: <1486480006.3301.3.camel@citrix.com> (raw)
In-Reply-To: <5899B9060200007800137312@prv-mh.provo.novell.com>

On Tue, 2017-02-07 at 04:09 -0700, Jan Beulich wrote:
> > > > On 06.02.17 at 15:57, <sergey.dyasli@citrix.com> wrote:
> > 
> > Any fail during the original __vmwrite() leads to BUG() which can be
> > easily exploited from a guest in the nested vmx mode.
> > 
> > The new function returns error code depending on the outcome:
> > 
> >           VMsucceed: 0
> >         VMfailValid: VM Instruction Error Number
> >       VMfailInvalid: a new VMX_INSN_FAIL_INVALID
> > 
> > A new macro GAS_VMX_OP is introduced in order to improve the
> > readability of asm.  Existing ASM_FLAG_OUT macro is reused and copied
> > into asm_defns.h
> > 
> > Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
> > ---
> 
> Please can you have the revision info for the individual patches
> here. I know you've put it in the overview mail, but for reviewers
> it's far more useful to (also) be here.
> 
> > --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
> > +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
> > @@ -526,6 +526,7 @@ enum vmx_insn_errno
> >      VMX_INSN_VMPTRLD_INVALID_PHYADDR       = 9,
> >      VMX_INSN_UNSUPPORTED_VMCS_COMPONENT    = 12,
> >      VMX_INSN_VMXON_IN_VMX_ROOT             = 15,
> > +    VMX_INSN_FAIL_INVALID                  = ~0,
> >  };
> 
> The main reason for me to ask for the type change here was to ...
> 
> > @@ -423,6 +429,29 @@ static inline bool_t __vmread_safe(unsigned long field, unsigned long *value)
> >      return okay;
> >  }
> >  
> > +static always_inline unsigned long vmwrite_safe(unsigned long field,
> > +                                                unsigned long value)
> > +{
> > +    unsigned long ret = 0;
> > +    bool fail_invalid, fail_valid;
> > +
> > +    asm volatile ( GAS_VMX_OP("vmwrite %[value], %[field]\n\t",
> > +                              VMWRITE_OPCODE MODRM_EAX_ECX)
> > +                   ASM_FLAG_OUT(, "setc %[invalid]\n\t")
> > +                   ASM_FLAG_OUT(, "setz %[valid]\n\t")
> > +                   : ASM_FLAG_OUT("=@ccc", [invalid] "=rm") (fail_invalid),
> > +                     ASM_FLAG_OUT("=@ccz", [valid] "=rm") (fail_valid)
> > +                   : [field] GAS_VMX_OP("r", "a") (field),
> > +                     [value] GAS_VMX_OP("rm", "c") (value));
> > +
> > +    if ( unlikely(fail_invalid) )
> > +        ret = VMX_INSN_FAIL_INVALID;
> > +    else if ( unlikely(fail_valid) )
> > +        __vmread(VM_INSTRUCTION_ERROR, &ret);
> > +
> > +    return ret;
> > +}
> 
> ... allow the function to return enum vmx_insn_errno, and that
> to not be a 64-bit quantity. As you're presumably aware, dealing
> with 32-bit quantities is on the average slightly more efficient than
> dealing with 64-bit ones. The code above should imo still BUG() if
> the value read from VM_INSTRUCTION_ERROR doesn't fit in 32
> bits (as it's a 32-bit field only anyway).

If I understood correctly, you are suggesting the following change:

diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 24fbbd4..f9b3bf1 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -424,8 +424,8 @@ static inline unsigned long vmread_safe(unsigned long field,
     return ret;
 }
 
-static always_inline unsigned long vmwrite_safe(unsigned long field,
-                                                unsigned long value)
+static always_inline enum vmx_insn_errno vmwrite_safe(unsigned long field,
+                                                      unsigned long value)
 {
     unsigned long ret = 0;
     bool fail_invalid, fail_valid;
@@ -440,11 +440,16 @@ static always_inline unsigned long vmwrite_safe(unsigned long field,
                      [value] GAS_VMX_OP("rm", "c") (value));
 
     if ( unlikely(fail_invalid) )
+    {
         ret = VMX_INSN_FAIL_INVALID;
+    }
     else if ( unlikely(fail_valid) )
+    {
         __vmread(VM_INSTRUCTION_ERROR, &ret);
+        BUG_ON(ret >= ~0U);
+    }
 
-    return ret;
+    return (enum vmx_insn_errno) ret;
 }

And I have noticed one inconsistency: vmwrite_safe() is "always_inline"
while vmread_safe() is plain "inline". I believe that plain inline is
enough here, what do you think?

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

  parent reply	other threads:[~2017-02-07 15:06 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-06 14:57 [PATCH v2 0/4] x86/vvmx: correctly emulate VMREAD and VMWRITE Sergey Dyasli
2017-02-06 14:57 ` [PATCH v2 1/4] x86/vmx: introduce vmwrite_safe() Sergey Dyasli
2017-02-07  6:31   ` Tian, Kevin
2017-02-07 11:09   ` Jan Beulich
2017-02-07 11:59     ` Andrew Cooper
2017-02-07 13:18       ` Jan Beulich
2017-02-07 15:06     ` Sergey Dyasli [this message]
2017-02-07 15:22       ` Andrew Cooper
2017-02-07 16:22       ` Jan Beulich
2017-02-07 16:34         ` Andrew Cooper
2017-02-07 16:47           ` Jan Beulich
2017-02-06 14:57 ` [PATCH v2 2/4] x86/vmx: improve vmread_safe() Sergey Dyasli
2017-02-07  6:32   ` Tian, Kevin
2017-02-06 14:57 ` [PATCH v2 3/4] x86/vvmx: correctly emulate VMWRITE Sergey Dyasli
2017-02-07  6:37   ` Tian, Kevin
2017-02-06 14:57 ` [PATCH v2 4/4] x86/vvmx: correctly emulate VMREAD Sergey Dyasli
2017-02-07  6:52   ` Tian, Kevin
2017-02-07 15:56     ` Sergey Dyasli
2017-02-06 15:19 ` [PATCH v2 0/4] x86/vvmx: correctly emulate VMREAD and VMWRITE Andrew Cooper

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=1486480006.3301.3.camel@citrix.com \
    --to=sergey.dyasli@citrix.com \
    --cc=Andrew.Cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=jun.nakajima@intel.com \
    --cc=kevin.tian@intel.com \
    --cc=xen-devel@lists.xen.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.