public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	linux-kernel@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
	kvm@vger.kernel.org
Subject: Re: [PATCH] x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386
Date: Fri, 23 Aug 2019 09:59:33 +0200	[thread overview]
Message-ID: <20190823075933.GY2369@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20190822211122.27579-1-sean.j.christopherson@intel.com>

On Thu, Aug 22, 2019 at 02:11:22PM -0700, Sean Christopherson wrote:
> Use 'lea' instead of 'add' when adjusting %rsp in CALL_NOSPEC so as to
> avoid clobbering flags.
> 
> KVM's emulator makes indirect calls into a jump table of sorts, where
> the destination of the CALL_NOSPEC is a small blob of code that performs
> fast emulation by executing the target instruction with fixed operands.
> 
>   adcb_al_dl:
>      0x000339f8 <+0>:   adc    %dl,%al
>      0x000339fa <+2>:   ret
> 
> A major motiviation for doing fast emulation is to leverage the CPU to
> handle consumption and manipulation of arithmetic flags, i.e. RFLAGS is
> both an input and output to the target of CALL_NOSPEC.  Clobbering flags
> results in all sorts of incorrect emulation, e.g. Jcc instructions often
> take the wrong path.  Sans the nops...
> 
>   asm("push %[flags]; popf; " CALL_NOSPEC " ; pushf; pop %[flags]\n"
>      0x0003595a <+58>:  mov    0xc0(%ebx),%eax
>      0x00035960 <+64>:  mov    0x60(%ebx),%edx
>      0x00035963 <+67>:  mov    0x90(%ebx),%ecx
>      0x00035969 <+73>:  push   %edi
>      0x0003596a <+74>:  popf
>      0x0003596b <+75>:  call   *%esi
>      0x000359a0 <+128>: pushf
>      0x000359a1 <+129>: pop    %edi
>      0x000359a2 <+130>: mov    %eax,0xc0(%ebx)
>      0x000359b1 <+145>: mov    %edx,0x60(%ebx)
> 
>   ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
>      0x000359a8 <+136>: mov    -0x10(%ebp),%eax
>      0x000359ab <+139>: and    $0x8d5,%edi
>      0x000359b4 <+148>: and    $0xfffff72a,%eax
>      0x000359b9 <+153>: or     %eax,%edi
>      0x000359bd <+157>: mov    %edi,0x4(%ebx)
> 
> For the most part this has gone unnoticed as emulation of guest code
> that can trigger fast emulation is effectively limited to MMIO when
> running on modern hardware, and MMIO is rarely, if ever, accessed by
> instructions that affect or consume flags.

Also, because nobody every uses 32bit anymore, I suspect ;-)

> Breakage is almost instantaneous when running with unrestricted guest
> disabled, in which case KVM must emulate all instructions when the guest
> has invalid state, e.g. when the guest is in Big Real Mode during early
> BIOS.
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: <kvm@vger.kernel.org>
> Cc: <stable@vger.kernel.org>
> Fixes: 1a29b5b7f347a ("KVM: x86: Make indirect calls in emulator speculation safe")

Cute; arguably this is a fix for:

776b043848fd2 ("x86/retpoline: Add initial retpoline support")

The patch you quote just happens to trigger it in KVM, but you're right
to note that CALL shouldn't frob EFLAGS, and who knows what possible
other sites care.

Anyway,

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> ---
>  arch/x86/include/asm/nospec-branch.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index 109f974f9835..80bc209c0708 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -192,7 +192,7 @@
>  	"    	lfence;\n"					\
>  	"       jmp    902b;\n"					\
>  	"       .align 16\n"					\
> -	"903:	addl   $4, %%esp;\n"				\
> +	"903:	lea    4(%%esp), %%esp;\n"			\
>  	"       pushl  %[thunk_target];\n"			\
>  	"       ret;\n"						\
>  	"       .align 16\n"					\
> -- 
> 2.22.0
> 

      reply	other threads:[~2019-08-23  7:59 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22 21:11 [PATCH] x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386 Sean Christopherson
2019-08-23  7:59 ` Peter Zijlstra [this message]

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=20190823075933.GY2369@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox