NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-mips/60664: mips: rdhwr emulation corrupts v0 on nested TLB miss, random userland SIGSEGV
The following reply was made to PR port-mips/60664; it has been noted by GNATS.
From: Nick Hudson <nick.hudson%gmx.co.uk@localhost>
To: gnats-bugs%netbsd.org@localhost,
port-mips-maintainer%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost,
netbsd-bugs%netbsd.org@localhost
Cc:
Subject: Re: port-mips/60664: mips: rdhwr emulation corrupts v0 on nested TLB
miss, random userland SIGSEGV
Date: Tue, 22 Sep 2026 18:58:42 +0100
--Apple-Mail=_1E0D089D-F651-40AE-98A7-C6C6B197948D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=us-ascii
Thanks for the PR.
I changed the patch a little to improve register usage in both the fast =
and slow paths.
--Apple-Mail=_1E0D089D-F651-40AE-98A7-C6C6B197948D
Content-Disposition: attachment;
filename=mipsX_subr.S.diff
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="mipsX_subr.S.diff"
Content-Transfer-Encoding: quoted-printable
Index: sys/arch/mips/mips/mipsX_subr.S
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/arch/mips/mips/mipsX_subr.S,v
retrieving revision 1.118
diff -u -p -r1.118 mipsX_subr.S
=2D-- sys/arch/mips/mips/mipsX_subr.S 27 Jun 2026 07:44:56 -0000 1.118
+++ sys/arch/mips/mips/mipsX_subr.S 22 Sep 2026 15:52:31 -0000
@@ -1320,32 +1320,63 @@ NESTED_NOPROFILE(MIPSX(user_reserved_ins
nop
=20
/*
- * Get exception PC and fetch the instruction. We know we can do
- * this since the instruction actually got read.
+ * Get exception PC and fetch the instruction.
+ *
+ * Probe the page with TLBP first, and take the slow path if the
+ * entry isn't there. A nested miss on the inline read below would
+ * otherwise land in user_gen_exception and clobber this routine's
+ * own v0, since the exception PC isn't saved again while EXL is set.
*/
_MFC0 v0, MIPS_COP_0_EXC_PC
MFC0_HAZARD
+
+ /* Need v1 and a0 too */
+ REG_S v1, CALLFRAME_SIZ+TF_REG_V1(k0)
+ REG_S a0, CALLFRAME_SIZ+TF_REG_A0(k0)
+
+ _MFC0 v1, MIPS_COP_0_TLB_HI # grab current ASID
+ MFC0_HAZARD
+ andi a0, v1, MIPS3_PG_ASID
+ move AT, v0
+#ifdef MIPSNNR2
+ _INS AT, a0, 0, V_MIPS3_PG_HVPN
+#else
+ _SRA AT, V_MIPS3_PG_HVPN # clear bottom bits of VA
+ _SLL AT, V_MIPS3_PG_HVPN # clear bottom bits of VA
+ or AT, AT, a0
+#endif
+ _MTC0 AT, MIPS_COP_0_TLB_HI # look for the vaddr & ASID
+ COP0_SYNC
+ tlbp # probe the entry in question
+ COP0_SYNC
+ mfc0 AT, MIPS_COP_0_TLB_INDEX # see what we got
+ MFC0_HAZARD
+ _MTC0 v1, MIPS_COP_0_TLB_HI # restore HI
+ COP0_SYNC
+ bltz AT, MIPSX(user_gen_exception_common2) # index < 0 =3D> !found
+ nop
+
+ // Load instruction
INT_L AT, 0(v0)
=20
/*
* Was this rdhwr $3,$29?
*/
- lui v0, %hi(0x7c03e83b) # 0x7c03e83b =3D> rdhwr $3,$29
- addiu v0, %lo(0x7c03e83b) # or ... rdhwr v1,ulr
- bne AT, v0, MIPSX(user_gen_exception_common)
+ lui v1, %hi(0x7c03e83b) # 0x7c03e83b =3D> rdhwr $3,$29
+ addiu v1, %lo(0x7c03e83b) # or ... rdhwr v1,ulr
+ bne AT, v1, MIPSX(user_gen_exception_common2)
nop
=20
/*
* Advance the PC (don't want to restart at the rdhwr).
*/
- _MFC0 v0, MIPS_COP_0_EXC_PC
- MFC0_HAZARD
PTR_ADDIU v0, 4
_MTC0 v0, MIPS_COP_0_EXC_PC
COP0_SYNC
=20
PTR_L v1, L_PRIVATE(k1) # rdhwr $3,$29 updates v1
=20
+ REG_L a0, CALLFRAME_SIZ+TF_REG_A0(k0) # restore reg
REG_L AT, CALLFRAME_SIZ+TF_REG_AST(k0)# restore reg
REG_L v0, CALLFRAME_SIZ+TF_REG_V0(k0) # restore reg
eret
@@ -1374,34 +1405,35 @@ NESTED_NOPROFILE(MIPSX(user_gen_exceptio
REG_S v0, CALLFRAME_SIZ+TF_REG_V0(k0)
MIPSX(user_gen_exception_common):
REG_S v1, CALLFRAME_SIZ+TF_REG_V1(k0)
- mflo v0
REG_S a0, CALLFRAME_SIZ+TF_REG_A0(k0)
+MIPSX(user_gen_exception_common2):
REG_S a1, CALLFRAME_SIZ+TF_REG_A1(k0)
+ mflo v0
REG_S a2, CALLFRAME_SIZ+TF_REG_A2(k0)
REG_S a3, CALLFRAME_SIZ+TF_REG_A3(k0)
- mfhi v1
REG_S t0, CALLFRAME_SIZ+TF_REG_T0(k0)
REG_S t1, CALLFRAME_SIZ+TF_REG_T1(k0)
+ mfhi v1
REG_S t2, CALLFRAME_SIZ+TF_REG_T2(k0)
REG_S t3, CALLFRAME_SIZ+TF_REG_T3(k0)
- mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS
REG_S ta0, CALLFRAME_SIZ+TF_REG_TA0(k0)
REG_S ta1, CALLFRAME_SIZ+TF_REG_TA1(k0)
+ mfc0 a0, MIPS_COP_0_STATUS # 1st arg is STATUS
REG_S ta2, CALLFRAME_SIZ+TF_REG_TA2(k0)
REG_S ta3, CALLFRAME_SIZ+TF_REG_TA3(k0)
- mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE
REG_S s0, CALLFRAME_SIZ+TF_REG_S0(k0)
REG_S s1, CALLFRAME_SIZ+TF_REG_S1(k0)
+ mfc0 a1, MIPS_COP_0_CAUSE # 2nd arg is CAUSE
REG_S s2, CALLFRAME_SIZ+TF_REG_S2(k0)
REG_S s3, CALLFRAME_SIZ+TF_REG_S3(k0)
- _MFC0 a2, MIPS_COP_0_BAD_VADDR # 3rd arg is fault address
REG_S s4, CALLFRAME_SIZ+TF_REG_S4(k0)
REG_S s5, CALLFRAME_SIZ+TF_REG_S5(k0)
+ _MFC0 a2, MIPS_COP_0_BAD_VADDR # 3rd arg is fault address
REG_S s6, CALLFRAME_SIZ+TF_REG_S6(k0)
REG_S s7, CALLFRAME_SIZ+TF_REG_S7(k0)
- _MFC0 a3, MIPS_COP_0_EXC_PC # 4th arg is exception PC
REG_S t8, CALLFRAME_SIZ+TF_REG_T8(k0) # will be MIPS_CURLWP
REG_S t9, CALLFRAME_SIZ+TF_REG_T9(k0)
+ _MFC0 a3, MIPS_COP_0_EXC_PC # 4th arg is exception PC
REG_S v0, CALLFRAME_SIZ+TF_REG_MULLO(k0)
REG_S v1, CALLFRAME_SIZ+TF_REG_MULHI(k0)
REG_S gp, CALLFRAME_SIZ+TF_REG_GP(k0)
--Apple-Mail=_1E0D089D-F651-40AE-98A7-C6C6B197948D--
Home |
Main Index |
Thread Index |
Old Index