• Peter Zijlstra's avatar
    x86: Fix FILL_RETURN_BUFFER · 6ea17e84
    Peter Zijlstra authored
    With overlapping alternative validation fixed, objtool promptly
    complains:
    
    vmlinux.o: warning: objtool: __switch_to_asm+0x2c: stack layout conflict in alternatives: .altinstr_replacement+0x47
    
    .rela.altinstructions:
    
    000000000000009c  0000000200000002 R_X86_64_PC32          0000000000000000 .text + 16dc
    00000000000000a0  0000000600000002 R_X86_64_PC32          0000000000000000 .altinstr_replacement + 3a
    00000000000000a8  0000000200000002 R_X86_64_PC32          0000000000000000 .text + 16dc
    00000000000000ac  0000000600000002 R_X86_64_PC32          0000000000000000 .altinstr_replacement + 66
    
    .text:
    
    00000000000016b0 <__switch_to_asm>:
        16b0:       f3 0f 1e fa             endbr64
        16b4:       55                      push   %rbp
        16b5:       53                      push   %rbx
        16b6:       41 54                   push   %r12
        16b8:       41 55                   push   %r13
        16ba:       41 56                   push   %r14
        16bc:       41 57                   push   %r15
        16be:       48 89 a7 18 0b 00 00    mov    %rsp,0xb18(%rdi)
        16c5:       48 8b a6 18 0b 00 00    mov    0xb18(%rsi),%rsp
        16cc:       48 8b 9e 28 05 00 00    mov    0x528(%rsi),%rbx
        16d3:       65 48 89 1c 25 00 00 00 00      mov    %rbx,%gs:0x0     16d8: R_X86_64_32S      fixed_percpu_data+0x28
        16dc:       eb 2a                   jmp    1708 <__switch_to_asm+0x58>
        16de:       90                      nop
        16df:       90                      nop
        16e0:       90                      nop
        16e1:       90                      nop
        16e2:       90                      nop
        16e3:       90                      nop
        16e4:       90                      nop
        16e5:       90                      nop
        16e6:       90                      nop
        16e7:       90                      nop
        16e8:       90                      nop
        16e9:       90                      nop
        16ea:       90                      nop
        16eb:       90                      nop
        16ec:       90                      nop
        16ed:       90                      nop
        16ee:       90                      nop
        16ef:       90                      nop
        16f0:       90                      nop
        16f1:       90                      nop
        16f2:       90                      nop
        16f3:       90                      nop
        16f4:       90                      nop
        16f5:       90                      nop
        16f6:       90                      nop
        16f7:       90                      nop
        16f8:       90                      nop
        16f9:       90                      nop
        16fa:       90                      nop
        16fb:       90                      nop
        16fc:       90                      nop
        16fd:       90                      nop
        16fe:       90                      nop
        16ff:       90                      nop
        1700:       90                      nop
        1701:       90                      nop
        1702:       90                      nop
        1703:       90                      nop
        1704:       90                      nop
        1705:       90                      nop
        1706:       90                      nop
        1707:       90                      nop
        1708:       41 5f                   pop    %r15
        170a:       41 5e                   pop    %r14
        170c:       41 5d                   pop    %r13
        170e:       41 5c                   pop    %r12
        1710:       5b                      pop    %rbx
        1711:       5d                      pop    %rbp
        1712:       e9 00 00 00 00          jmp    1717 <__switch_to_asm+0x67>      1713: R_X86_64_PLT32    __switch_to-0x4
    
    .altinstr_replacement:
    
          3a:       49 c7 c4 10 00 00 00    mov    $0x10,%r12
          41:       e8 01 00 00 00          call   47 <.altinstr_replacement+0x47>
          46:       cc                      int3
          47:       e8 01 00 00 00          call   4d <.altinstr_replacement+0x4d>
          4c:       cc                      int3
          4d:       48 83 c4 10             add    $0x10,%rsp
          51:       49 ff cc                dec    %r12
          54:       75 eb                   jne    41 <.altinstr_replacement+0x41>
          56:       0f ae e8                lfence
          59:       65 48 c7 04 25 00 00 00 00 ff ff ff ff  movq   $0xffffffffffffffff,%gs:0x0      5e: R_X86_64_32S        pcpu_hot+0x10
    
          66:       e8 01 00 00 00          call   6c <.altinstr_replacement+0x6c>
          6b:       cc                      int3
          6c:       48 83 c4 08             add    $0x8,%rsp
          70:       0f ae e8                lfence
    
    As can be seen from the two alternatives, when overlaid, the NOP after
    the shorter (starting at 66) coinsides with the call at 47, leading to
    conflicting CFI state for that instruction.
    
    By offsetting the shorter alternative by 2 bytes, this alignment is
    undone.
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    Acked-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
    Tested-by: Nathan Chancellor <nathan@kernel.org> # build only
    Tested-by: Thomas Weißschuh <linux@weissschuh.net> # compile and run
    Link: https://lore.kernel.org/r/20230208172245.783099843@infradead.org
    6ea17e84
nospec-branch.h 15.4 KB