[llvm-dev] retpoline mitigation and 6.0

Hans Wennborg via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 19 07:18:03 PST 2018

Reid, is this what you fixed with r325049 that's also merged to 6.0?

If so, do we have everything that's needed, or is there anything else
I should wait for?

Chandler, do you have anything else? Also, release notes please :-)

On Fri, Feb 9, 2018 at 11:23 PM, Reid Kleckner via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> I think I see what's going on, and I agree it looks like a bug. It was too
> much to hope that later passes weren't going to mess with the PUSH
> instruction. :(
> While I was trying to reproduce your problem, I think I found another one
> that looks like this:
> $ clang -S -O2 -m32 -mregparm=3 -mretpoline spill_across_rp.cpp -o - | grep
> _retpoline_push -B2
> ...
>         movl    %eax, 8(%esp)           # 4-byte Spill
> ...
>         pushl   %edi
>         movl    8(%esp), %edi           # 4-byte Reload
>         calll   __llvm_retpoline_push
> That's obviously broken, it doesn't account for the SP adjustment in the
> push.
> It's weird, because it's basically the opposite of the problem you're
> having, which looks like LLVM *is* accounting for the push and is trying to
> adjust its offsets accordingly.
> Can you send along the full command line used to compile io_apic_b.i?
> On Fri, Feb 9, 2018 at 11:38 AM, David Woodhouse <dwmw2 at infradead.org>
> wrote:
>> On Fri, 2018-02-09 at 11:24 -0800, Reid Kleckner wrote:
>> > I haven't read the all the emails in full detail, but it seems pretty
>> > clear that  __x86_indirect_thunk and __llvm_retpoline_push do not do
>> > the same things. It sounds like __llvm_retpoline_push is equivalent
>> > to __x86_indirect_thunk except first it swaps the two words on the
>> > top of the stack.
>> >
>> > I arranged it this way because the x86 call instruction puts the
>> > intended return address on the top of the stack, and there's no easy
>> > way to put it anywhere else. We use this thunk when we want to make
>> > an indirect call and there are no available scratch registers, i.e.
>> > 32-bit -mregparm=3 and the call has three or more arguments, which
>> > happens in Linux. One way to avoid this would be to compile with
>> > -mregparm=2, but that would pessimize direct calls unnecessarily.
>> >
>> > It sounds like Linux is already providing its own thunks, so it might
>> > be better to for us to go back to the __llvm_retpoline_push external
>> > thunk name and then get Linux to provide that thunk ifdef __clang__.
>> Yes, the thunks are different in this case. That one should indeed be
>> renamed, and I'll provide the correct one in the kernel.
>> However, even if I let LLVM emit the thunk for itself, code generation
>> seems hosed. It looks like after a call to __llvm_retpoline_push (or
>> perhaps more to the point after pushing the target address in
>> preparation for the call?) we're losing track of where %esp points, and
>> thus everything else that was spilled to the stack.
>> Please let me know if you need any more detail on that, than I provided
>> in my last email. You should have everything you need there to follow
>> along with my analysis and reproduce it for yourself. Except perhaps
>> the Grandma-suck-eggs command lines like
>> $ qemu-system-i386  -display none -serial stdio -kernel
>> arch/x86/boot/bzImage  -append earlyprintk=ttyS0,keep -s -S
>> $ gdb vmlinux
>> (gdb) tar rem localhost:1234
>> (gdb) break mp_register_ioapic
>> (gdb) c
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

More information about the llvm-dev mailing list