SVM instructions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

SVM instructions

Mark Kettenis
Clang only accepts SVM instructions with explicit operands, for
example:

  vmload %rax

Unfortunately gas doesn't accept this form.  It does accept the
instruction without any operands:

  vmload

and the incorrect form:

  vmload (%rax)

The diff below fixes this.

Slight flaw with this diff is that it will also accept the incorrect

  vmload %rbx

which will be silently translated into

  vmload %rax

But I don't think that is a huge issue.

ok?


Index: gnu/usr.bin/binutils-2.17/include/opcode/i386.h
===================================================================
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/include/opcode/i386.h,v
retrieving revision 1.9
diff -u -p -r1.9 i386.h
--- gnu/usr.bin/binutils-2.17/include/opcode/i386.h 21 Dec 2015 20:56:22 -0000 1.9
+++ gnu/usr.bin/binutils-2.17/include/opcode/i386.h 15 Mar 2017 19:59:40 -0000
@@ -1464,17 +1464,21 @@ static const template i386_optab[] =
 {"clgi",     0, 0x0f01, 0xdd, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
 {"invlpga",  0, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
 /* Need to ensure only "invlpga ...,%ecx" is accepted.  */
-{"invlpga",  2, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { AnyMem, Reg32, 0 } },
+{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, Reg32, 0 } },
+{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, Reg32, 0 } },
 {"skinit",   0, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
-{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
+{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { Reg32, 0, 0 } },
 {"stgi",     0, 0x0f01, 0xdc, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
 {"vmload",   0, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
-{"vmload",   1, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
+{"vmload",   1, 0x0f01, 0xda, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
+{"vmload",   1, 0x0f01, 0xda, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
 {"vmmcall",  0, 0x0f01, 0xd9, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
 {"vmrun",    0, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
-{"vmrun",    1, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
+{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
+{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
 {"vmsave",   0, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
-{"vmsave",   1, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
+{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
+{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
 
 /* VIA PadLock extensions.  */
 {"xstore-rng",0, 0x000fa7, 0xc0, Cpu686|CpuPadLock, NoSuf|IsString|ImmExt, { 0, 0, 0} },



Reply | Threaded
Open this post in threaded view
|

Re: SVM instructions

Mike Larkin
On Wed, Mar 15, 2017 at 09:05:56PM +0100, Mark Kettenis wrote:

> Clang only accepts SVM instructions with explicit operands, for
> example:
>
>   vmload %rax
>
> Unfortunately gas doesn't accept this form.  It does accept the
> instruction without any operands:
>
>   vmload
>
> and the incorrect form:
>
>   vmload (%rax)
>
> The diff below fixes this.
>
> Slight flaw with this diff is that it will also accept the incorrect
>
>   vmload %rbx
>
> which will be silently translated into
>
>   vmload %rax
>
> But I don't think that is a huge issue.
>
> ok?
>

If the svm bits in the tree still build, sure.

I had planned to change this to a #define like other OSes do but
this fix is just as good. no complaints from me.

>
> Index: gnu/usr.bin/binutils-2.17/include/opcode/i386.h
> ===================================================================
> RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/include/opcode/i386.h,v
> retrieving revision 1.9
> diff -u -p -r1.9 i386.h
> --- gnu/usr.bin/binutils-2.17/include/opcode/i386.h 21 Dec 2015 20:56:22 -0000 1.9
> +++ gnu/usr.bin/binutils-2.17/include/opcode/i386.h 15 Mar 2017 19:59:40 -0000
> @@ -1464,17 +1464,21 @@ static const template i386_optab[] =
>  {"clgi",     0, 0x0f01, 0xdd, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
>  {"invlpga",  0, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
>  /* Need to ensure only "invlpga ...,%ecx" is accepted.  */
> -{"invlpga",  2, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { AnyMem, Reg32, 0 } },
> +{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, Reg32, 0 } },
> +{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, Reg32, 0 } },
>  {"skinit",   0, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> -{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> +{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { Reg32, 0, 0 } },
>  {"stgi",     0, 0x0f01, 0xdc, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
>  {"vmload",   0, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> -{"vmload",   1, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> +{"vmload",   1, 0x0f01, 0xda, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> +{"vmload",   1, 0x0f01, 0xda, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
>  {"vmmcall",  0, 0x0f01, 0xd9, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
>  {"vmrun",    0, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> -{"vmrun",    1, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> +{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> +{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
>  {"vmsave",   0, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> -{"vmsave",   1, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> +{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> +{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
>  
>  /* VIA PadLock extensions.  */
>  {"xstore-rng",0, 0x000fa7, 0xc0, Cpu686|CpuPadLock, NoSuf|IsString|ImmExt, { 0, 0, 0} },
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: SVM instructions

Mark Kettenis
> Date: Wed, 15 Mar 2017 16:23:33 -0700
> From: Mike Larkin <[hidden email]>
>
> On Wed, Mar 15, 2017 at 09:05:56PM +0100, Mark Kettenis wrote:
> > Clang only accepts SVM instructions with explicit operands, for
> > example:
> >
> >   vmload %rax
> >
> > Unfortunately gas doesn't accept this form.  It does accept the
> > instruction without any operands:
> >
> >   vmload
> >
> > and the incorrect form:
> >
> >   vmload (%rax)
> >
> > The diff below fixes this.
> >
> > Slight flaw with this diff is that it will also accept the incorrect
> >
> >   vmload %rbx
> >
> > which will be silently translated into
> >
> >   vmload %rax
> >
> > But I don't think that is a huge issue.
> >
> > ok?
> >
>
> If the svm bits in the tree still build, sure.
>
> I had planned to change this to a #define like other OSes do but
> this fix is just as good. no complaints from me.

Still builds and produces the same instructions.

> > Index: gnu/usr.bin/binutils-2.17/include/opcode/i386.h
> > ===================================================================
> > RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/include/opcode/i386.h,v
> > retrieving revision 1.9
> > diff -u -p -r1.9 i386.h
> > --- gnu/usr.bin/binutils-2.17/include/opcode/i386.h 21 Dec 2015 20:56:22 -0000 1.9
> > +++ gnu/usr.bin/binutils-2.17/include/opcode/i386.h 15 Mar 2017 19:59:40 -0000
> > @@ -1464,17 +1464,21 @@ static const template i386_optab[] =
> >  {"clgi",     0, 0x0f01, 0xdd, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> >  {"invlpga",  0, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> >  /* Need to ensure only "invlpga ...,%ecx" is accepted.  */
> > -{"invlpga",  2, 0x0f01, 0xdf, CpuSVME, NoSuf|ImmExt, { AnyMem, Reg32, 0 } },
> > +{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, Reg32, 0 } },
> > +{"invlpga",  2, 0x0f01, 0xdf, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, Reg32, 0 } },
> >  {"skinit",   0, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> > -{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> > +{"skinit",   1, 0x0f01, 0xde, CpuSVME, NoSuf|ImmExt, { Reg32, 0, 0 } },
> >  {"stgi",     0, 0x0f01, 0xdc, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> >  {"vmload",   0, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> > -{"vmload",   1, 0x0f01, 0xda, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> > +{"vmload",   1, 0x0f01, 0xda, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> > +{"vmload",   1, 0x0f01, 0xda, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
> >  {"vmmcall",  0, 0x0f01, 0xd9, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> >  {"vmrun",    0, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> > -{"vmrun",    1, 0x0f01, 0xd8, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> > +{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> > +{"vmrun",    1, 0x0f01, 0xd8, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
> >  {"vmsave",   0, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { 0, 0, 0 } },
> > -{"vmsave",   1, 0x0f01, 0xdb, CpuSVME, NoSuf|ImmExt, { AnyMem, 0, 0 } },
> > +{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|CpuNo64, NoSuf|ImmExt, { Reg32, 0, 0 } },
> > +{"vmsave",   1, 0x0f01, 0xdb, CpuSVME|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, 0, 0 } },
> >  
> >  /* VIA PadLock extensions.  */
> >  {"xstore-rng",0, 0x000fa7, 0xc0, Cpu686|CpuPadLock, NoSuf|IsString|ImmExt, { 0, 0, 0} },
> >
> >
> >
>

Reply | Threaded
Open this post in threaded view
|

Re: SVM instructions

Joerg Sonnenberger-2
In reply to this post by Mark Kettenis
On Wed, Mar 15, 2017 at 09:05:56PM +0100, Mark Kettenis wrote:
> Clang only accepts SVM instructions with explicit operands, for
> example:
>
>   vmload %rax

You might want to look at the aliases e.g. for monitor/mwait. Should be
pretty easy to extend as long as we are talkign about pure register
operands. Memory operands would be more tricky.

Joerg

Reply | Threaded
Open this post in threaded view
|

Re: SVM instructions

Mark Kettenis
> Date: Fri, 17 Mar 2017 07:00:08 +0100
> From: Joerg Sonnenberger <[hidden email]>
>
> On Wed, Mar 15, 2017 at 09:05:56PM +0100, Mark Kettenis wrote:
> > Clang only accepts SVM instructions with explicit operands, for
> > example:
> >
> >   vmload %rax
>
> You might want to look at the aliases e.g. for monitor/mwait. Should be
> pretty easy to extend as long as we are talkign about pure register
> operands. Memory operands would be more tricky.

To be honest, I think forcing people to use the explicit form as clang
does right now is a good idea.  It makes reading the code much easier.