Re: [tip: x86/cpu] x86/cpu: Use INVPCID mnemonic in invpcid.h

From: Uros Bizjak
Date: Tue May 12 2020 - 11:55:04 EST


On Tue, May 12, 2020 at 5:15 PM Borislav Petkov <bp@xxxxxxxxx> wrote:
>
> On Tue, May 12, 2020 at 04:26:37PM +0200, Uros Bizjak wrote:
> > Actually, the order was correct for AT&T syntax in the original patch.
> >
> > The insn template for AT&T syntax goes:
> >
> > insn arg2, arg1, arg0
> >
> > where rightmost arguments are output operands.
> >
> > The operands in asm template go
> >
> > asm ("insn template" : output0, output1 : input0, input1 : clobbers)
> >
> > so, in effect:
> >
> > asm ("insn template" : arg0, arg1 : arg2, arg3: clobbers)
> >
> > As you can see, the operand order in insn tempate is reversed for AT&T
> > syntax. I didn't notice the reversal of operands in your improvement.
>
> Your version had:
>
> + asm volatile ("invpcid %1, %0"
> + : : "r" (type), "m" (desc) : "memory");
>
> with "type" being the 0th operand and "desc" being the 1st operand in
> the input operands list.

Correct.

> The order of the operands after the "invpcid" mnemonic are the other way
> around though: you first have %1 which is "desc" and then %0 which is
> the type.

Also correct. Because AT&T has right-to-left operand order, while asm
statement has left-to-right operand order.

> I simply swapped the arguments order in the input operands list, after
> the second ':'
>
> + asm volatile("invpcid %[desc], %[type]"
> + :: [desc] "m" (desc), [type] "r" (type) : "memory");
>
> so that "desc" comes first and "type" second when reading from
> left-to-right in both

But this is not correct, AT&T insn template should have right-to-left order.

> 1. *after* the "invpcid" mnemonic and
> 2. in the input operands list, after the second ':'.

This is not the case throughout the kernel source. Please see for
example sync_bitops, where:

asm volatile("lock; " __ASM_SIZE(bts) " %1,%0"
: "+m" (ADDR)
: "Ir" (nr)
: "memory");

(to support my claim, I tried to find instruction with two input
operands; there are some in KVM, but these were also written by
myself).

> And since I'm using the symbolic operand names, then the order just
> works because looking at a before-and-after thing doesn't show any
> opcode differences:

Symbolic operands are agnostic to the position in the asm clause, so
it really doesn't matter much. It just doesn't feel right, when other
cases follow different order.

> $ diff -suprN /tmp/before /tmp/after
> Files /tmp/before and /tmp/after are identical

Sure, otherwise assembler would complain.

> Makes sense?

Well, I don't want to bikeshed around this anymore, so any way is good.

Uros.