Hi, Sergey, thanks for the patch! LGTM Sergey On 3/12/26 11:50, Sergey Kaplun wrote: > From: Mike Pall > > Thanks to Sergey Kaplun. > > (cherry picked from commit 2aec641e01ab80e86ea75d944c0919fa6c03c37c) > > MIPS processors originally required all memory accesses to be naturally > aligned. If we use ld instruction to load a double-word from the address > which is word-aligned, MIPS raises the exception SIGBUS. When exiting > the interpreter, if the current function is a fast function, the code in > the `lj_vm_exit_interp()` throws SIGBUS. The pc field for the fast > function points to the word-aligned bytecodes for ASM fast functions, > and PC2PROTO offset is double-word-aligned. The resulting address is > somewhere in the dispatch table. Hence, some (odd-indexed) fast function > access leads to the BUS error. For other architectures the load from > unaligned access is not a problem so there are no exceptions. > > This patch prevents unaligned memory access by address loading only > after fast-function checks. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#12134 > --- > > Branch:https://github.com/tarantool/luajit/tree/skaplun/lj-1428-mips64-bus-error-stitch > Related issues: > *https://github.com/LuaJIT/LuaJIT/issues/1428 > *https://github.com/tarantool/tarantool/issues/12134 > > How to reproduce locally: > > | make -j HOST_CC="gcc " CROSS=mips64el-unknown-linux-gnu- -f Makefile.original CCDEBUG=" -g -ggdb3" CFLAGS=" -O0" XCFLAGS=" -DLUA_USE_APICHECK -DLUA_USE_ASSERT " > | LUA_PATH="src/?.lua;test/tarantool-tests/?.lua;;" LD_LIBRARY_PATH="/usr/lib/gcc/mips64el-unknown-linux-gnu/15/" qemu-mips64el -L /usr/mips64el-unknown-linux-gnu/ src/luajit test/tarantool-tests/lj-1428-mips64-bus-error-stitch.test.lua > > src/vm_mips64.dasc | 8 ++--- > .../lj-1428-mips64-bus-error-stitch.test.lua | 33 +++++++++++++++++++ > 2 files changed, 37 insertions(+), 4 deletions(-) > create mode 100644 test/tarantool-tests/lj-1428-mips64-bus-error-stitch.test.lua > > diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc > index 34da6473..36250ab3 100644 > --- a/src/vm_mips64.dasc > +++ b/src/vm_mips64.dasc > @@ -2575,9 +2575,8 @@ static void build_subroutines(BuildCtx *ctx) > | li TISNIL, LJ_TNIL > | li TISNUM, LJ_TISNUM // Setup type comparison constants. > | .FPU mtc1 TMP3, TOBIT > - | ld TMP1,LFUNC:RB->pc > + | ld TMP3,LFUNC:RB->pc > | sd r0, DISPATCH_GL(jit_base)(DISPATCH) > - | ld KBASE, PC2PROTO(k)(TMP1) > | .FPU cvt.d.s TOBIT, TOBIT > | // Modified copy of ins_next which handles function header dispatch, too. > | lw INS, 0(PC) > @@ -2593,6 +2592,7 @@ static void build_subroutines(BuildCtx *ctx) > | decode_RA8a RA, INS > | beqz TMP2, >2 > |. decode_RA8b RA > + | ld KBASE, PC2PROTO(k)(TMP3) > | jr AT > |. decode_RD8b RD > |2: > @@ -2610,8 +2610,8 @@ static void build_subroutines(BuildCtx *ctx) > | dsubu TMP1, BASE, TMP0 > | ldLFUNC:TMP2, -32(TMP1) > | cleartpLFUNC:TMP2 > - | ld TMP1,LFUNC:TMP2->pc > - | ld KBASE, PC2PROTO(k)(TMP1) > + | ld TMP3,LFUNC:TMP2->pc > + | ld KBASE, PC2PROTO(k)(TMP3) > |3: > | daddiu RC, MULTRES, -8 > | jr AT > diff --git a/test/tarantool-tests/lj-1428-mips64-bus-error-stitch.test.lua b/test/tarantool-tests/lj-1428-mips64-bus-error-stitch.test.lua > new file mode 100644 > index 00000000..a81051c6 > --- /dev/null > +++ b/test/tarantool-tests/lj-1428-mips64-bus-error-stitch.test.lua > @@ -0,0 +1,33 @@ > +local tap = require('tap') > + > +-- The test file to demonstrate the incorrect exit to the > +-- interpreter into fast functions on mips64. > +-- See alsohttps://github.com/LuaJIT/LuaJIT/issues/1428. > + > +local test = tap.test('lj-1428-mips64-bus-error-stitch'):skipcond({ > + ['Test requires JIT enabled'] = not jit.status(), > +}) > + > +test:plan(1) > + > +local function always_number(val) > + return tonumber(val) or 1 > +end > + > +jit.opt.start('hotloop=1') > + > +-- `tonumber()` with a string argument produces stitching and > +-- exits to the interpreter after that. > +-- On mips64 the `PC2PROTO` offset leads to an unaligned address > +-- for this fast function. > + > +always_number('') > +always_number('') > + > +-- Start the stitched trace and exit to the interpreter. > +-- Leads to the Bus error on mips64 before the patch. > +always_number('') > + > +test:ok(true, 'no bus error') > + > +test:done(true)