All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Yang Weijiang <weijiang.yang@intel.com>
Cc: kvm@vger.kernel.org, pbonzini@redhat.com, shuah@kernel.org,
	peterx@redhat.com, linux-kselftest@vger.kernel.org
Subject: Re: [PATCH] selftests: kvm: Fix an unexpected failure with newer gcc compiler
Date: Mon, 17 Aug 2020 09:42:38 -0700	[thread overview]
Message-ID: <20200817164238.GD22407@linux.intel.com> (raw)
In-Reply-To: <20200814132105.5122-1-weijiang.yang@intel.com>

On Fri, Aug 14, 2020 at 09:21:05PM +0800, Yang Weijiang wrote:
> If debug_regs.c is built with newer gcc, e.g., 8.3.1 on my side, then the generated
> binary looks like over-optimized by gcc:
> 
> asm volatile("ss_start: "
>              "xor %%rax,%%rax\n\t"
>              "cpuid\n\t"
>              "movl $0x1a0,%%ecx\n\t"
>              "rdmsr\n\t"
>              : : : "rax", "ecx");
> 
> is translated to :
> 
>   000000000040194e <ss_start>:
>   40194e:       31 c0                   xor    %eax,%eax     <----- rax->eax?
>   401950:       0f a2                   cpuid
>   401952:       b9 a0 01 00 00          mov    $0x1a0,%ecx
>   401957:       0f 32                   rdmsr
> 
> As you can see rax is replaced with eax in taret binary code.

It's an optimization.  `xor rax, rax` and `xor eax, eax` yield the exact
same result, as writing the lower 32 bits of a GPR in 64-bit mode clears
the upper 32 bits.  Using the eax variant avoids the REX prefix and saves
a byte of code.

> But if I replace %%rax with %%r8 or any GPR from r8~15, then I get below
> expected binary:
> 
> 0000000000401950 <ss_start>:
>   401950:       45 31 ff                xor    %r15d,%r15d

This is not replacing %rax with %r15, it's replacing it with %r15d, which
is the equivalent of %eax.  But that's beside the point.  Encoding GPRs
r8-r15 requires a REX prefix, so even though you avoid REX.W you still need
REX.R, and thus end up with a 3 byte instruction.

>   401953:       0f a2                   cpuid

Note, CPUID consumes EAX.  It doesn't look like the code actually consumes
the CPUID output, but switching to r15 is at best bizarre.

>   401955:       b9 a0 01 00 00          mov    $0x1a0,%ecx
>   40195a:       0f 32                   rdmsr
> 
> The difference is the length of xor instruction(2 Byte vs 3 Byte),
> so this makes below hard-coded instruction length cannot pass runtime check:
> 
>         /* Instruction lengths starting at ss_start */
>         int ss_size[4] = {
>                 3,              /* xor */   <-------- 2 or 3?
>                 2,              /* cpuid */
>                 5,              /* mov */
>                 2,              /* rdmsr */
>         };
> Note:
> Use 8.2.1 or older gcc, it generates expected 3 bytes xor target code.
> 
> I use the default Makefile to build the binaries, and I cannot figure out why this
> happens, so it comes this patch, maybe you have better solution to resolve the
> issue. If you know how things work in this way, please let me know, thanks!

Use `xor %%eax, %%eax`.  That should always generate a 2 byte instruction.
Encoding a 64-bit operation would technically be legal, but I doubt any
compiler would do that in practice.

  reply	other threads:[~2020-08-17 16:44 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-14 13:21 [PATCH] selftests: kvm: Fix an unexpected failure with newer gcc compiler Yang Weijiang
2020-08-17 16:42 ` Sean Christopherson [this message]
2020-08-17 17:19   ` Paolo Bonzini
2020-08-18 13:25     ` Yang Weijiang

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=20200817164238.GD22407@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=shuah@kernel.org \
    --cc=weijiang.yang@intel.com \
    /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.