[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190823075933.GY2369@hirez.programming.kicks-ass.net>
Date: Fri, 23 Aug 2019 09:59:33 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Sean Christopherson <sean.j.christopherson@...el.com>
Cc: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
x86@...nel.org, "H. Peter Anvin" <hpa@...or.com>,
linux-kernel@...r.kernel.org, Paolo Bonzini <pbonzini@...hat.com>,
kvm@...r.kernel.org
Subject: Re: [PATCH] x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC
on i386
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@...radead.org>
> Cc: Paolo Bonzini <pbonzini@...hat.com>
> Cc: <kvm@...r.kernel.org>
> Cc: <stable@...r.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@...radead.org>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@...el.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
>
Powered by blists - more mailing lists