Patch "tools/nolibc: restore mips branch ordering in the _start block" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tools/nolibc: restore mips branch ordering in the _start block

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     tools-nolibc-restore-mips-branch-ordering-in-the-_st.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 74c6ada39b016d83095dea69585ec5455f9e9fff
Author: Willy Tarreau <w@xxxxxx>
Date:   Mon Jan 9 08:54:39 2023 +0100

    tools/nolibc: restore mips branch ordering in the _start block
    
    [ Upstream commit 184177c3d6e023da934761e198c281344d7dd65b ]
    
    Depending on the compiler used and the optimization options, the sbrk()
    test was crashing, both on real hardware (mips-24kc) and in qemu. One
    such example is kernel.org toolchain in version 11.3 optimizing at -Os.
    
    Inspecting the sys_brk() call shows the following code:
    
      0040047c <sys_brk>:
        40047c:       24020fcd        li      v0,4045
        400480:       27bdffe0        addiu   sp,sp,-32
        400484:       0000000c        syscall
        400488:       27bd0020        addiu   sp,sp,32
        40048c:       10e00001        beqz    a3,400494 <sys_brk+0x18>
        400490:       00021023        negu    v0,v0
        400494:       03e00008        jr      ra
    
    It is obviously wrong, the "negu" instruction is placed in beqz's
    delayed slot, and worse, there's no nop nor instruction after the
    return, so the next function's first instruction (addiu sip,sip,-32)
    will also be executed as part of the delayed slot that follows the
    return.
    
    This is caused by the ".set noreorder" directive in the _start block,
    that applies to the whole program. The compiler emits code without the
    delayed slots and relies on the compiler to swap instructions when this
    option is not set. Removing the option would require to change the
    startup code in a way that wouldn't make it look like the resulting
    code, which would not be easy to debug. Instead let's just save the
    default ordering before changing it, and restore it at the end of the
    _start block. Now the code is correct:
    
      0040047c <sys_brk>:
        40047c:       24020fcd        li      v0,4045
        400480:       27bdffe0        addiu   sp,sp,-32
        400484:       0000000c        syscall
        400488:       10e00002        beqz    a3,400494 <sys_brk+0x18>
        40048c:       27bd0020        addiu   sp,sp,32
        400490:       00021023        negu    v0,v0
        400494:       03e00008        jr      ra
        400498:       00000000        nop
    
    Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") #5.0
    Signed-off-by: Willy Tarreau <w@xxxxxx>
    Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 5fc5b8029bff..7380093ba9e7 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -192,6 +192,7 @@ struct sys_stat_struct {
 __asm__ (".section .text\n"
     ".weak __start\n"
     ".set nomips16\n"
+    ".set push\n"
     ".set    noreorder\n"
     ".option pic0\n"
     ".ent __start\n"
@@ -210,6 +211,7 @@ __asm__ (".section .text\n"
     "li $v0, 4001\n"              // NR_exit == 4001
     "syscall\n"
     ".end __start\n"
+    ".set pop\n"
     "");
 
 #endif // _NOLIBC_ARCH_MIPS_H



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux