Re: [PATCH] mips: vdso: conditionalize 32-bit time functions on COMPAT_32BIT_TIME

From: Arnd Bergmann
Date: Mon Dec 30 2019 - 12:33:36 EST


On Mon, Dec 30, 2019 at 4:58 PM Jason A. Donenfeld <Jason@xxxxxxxxx> wrote:
>
> Makes sense w.r.t. time32 situation.
>
> I still think that in spite of that there's still something weird
> happening with the mips VDSO.

Agreed.

> Here's a register dump before the call:
>
> $ 0 : 0000000000000000 0000000000000001 0000000010000000 fffffffffffffffc
> $ 4 : 0000000000000002 000000007fff2e40 0000000000000000 0000000000000001
> $ 8 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> $12 : 0000000000000000 000000000000000a ffffffff80000000 000000007fffffda
> $16 : 0000000010001ba8 0000005800000015 0000000010000000 0000000010000000
> $20 : 0000000010000000 0000000010000000 0000000000000000 0000000077ff2ae8
> $24 : 0000000000000005 0000000077fa1d18
> $28 : 0000000010019cf0 000000007fff2e40 0000000000000000 0000000010000c30
> Hi : 0000000000000000
> Lo : 0000000000000000
> epc : 0000000077fa1d18 0x77fa1d18
> ra : 0000000010000c30 0x10000c30
>
> And here it is immediately after:
>
> $ 0 : 0000000000000000 0000000000000001 ffffffffffffffa7 000000007fff5000
> $ 4 : 0000000000000002 000000007fff2e40 0000000077ff2000 0000000000000001
> $ 8 : 0000000000000006 0000000000000020 0000000000000002 0000000000000000
> $12 : 0000000000000000 0000000000001852 ffffffff80156160 000000007fffffda
> $16 : 0000000010001ba8 0000005800000015 0000000010000000 0000000010000000
> $20 : 0000000010000000 0000000010000000 0000000000000000 0000000077ff2b00
> $24 : 0000000000000005 0000000000000000
> $28 : 000000007fff5000 000000007fff2e30 0000000000000000 0000000077fa1e00
> Hi : 0000000000000000
> Lo : 0000000000000000
> epc : 0000000077fa1e00 0x77fa1e00
> ra : 0000000077fa1e00 0x77fa1e00

Is this immediately before/after the syscall instruction or the
indirect function call?

> I wonder if a toolchain option or compiler bug or something is causing
> the vdso to not restore certain registers (gp? ra?).

Here is the assembler output I see for the o32 vdso, hopefully I got all
the relevant bits:

# /git/arm-soc/lib/vdso/gettimeofday.c:130: if (unlikely(ret))
.set noreorder
.set nomacro
beqz $2,$L86 #,,
lw $28,16($sp) #,
.set macro
.set reorder

$L46:
# /git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h:118:
register struct old_timespec32 *ts asm("a1") = _ts;
move $5,$16 # ts, ts
# /git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h:119:
register clockid_t clkid asm("a0") = _clkid;
move $4,$17 # clkid, clock
# /git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h:121:
register long nr asm("v0") = __NR_clock_gettime;
li $2,4263 # 0x10a7 # nr,
# /git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h:124: asm volatile(
#APP
# 124 "/git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h" 1
syscall

# 0 "" 2
# /git/arm-soc/arch/mips/vdso/vgettimeofday.c:18: }
#NO_APP
lw $31,60($sp) #,
lw $19,56($sp) #,
# /git/arm-soc/arch/mips/include/asm/vdso/gettimeofday.h:131: return
error ? -ret : ret;
subu $3,$0,$2 # <retval>, ret
selnez $3,$3,$7 # tmp406, <retval>, error
seleqz $2,$2,$7 # tmp407, ret, error
or $3,$3,$2 # <retval>, tmp406, tmp407
# /git/arm-soc/arch/mips/vdso/vgettimeofday.c:18: }
lw $18,52($sp) #,
lw $17,48($sp) #,
lw $16,44($sp) #,
move $2,$3 #, <retval>
.set noreorder
.set nomacro
jr $31 #
addiu $sp,$sp,64 #,,
.set macro
.set reorder

gp ($28) and ra ($31) sound like good guesses to me,

SP ($r29) changed from 000000007fff2e40
to 000000007fff2e30, if that is not the intention, it would clearly explain why
anything afterwards crashes, but that seems unlikely.

r3 contains the error code -ENOSYS on mips, so that's good.

$23 is supposed to be preserved across function calls and is
consequently not part of the clobber list but is modified.

$25 is part of the clobber list and is also modified, but there
is no code to save/restore it in the assembler output.

Arnd