svn commit: r361296 - in head/sys/mips: include mips

John Baldwin jhb at FreeBSD.org
Wed May 20 21:15:44 UTC 2020


Author: jhb
Date: Wed May 20 21:15:43 2020
New Revision: 361296
URL: https://svnweb.freebsd.org/changeset/base/361296

Log:
  Simplify hot-patching cpu_switch() for lack of UserLocal register.
  
  Rather than walking all of cpu_switch looking for the sequence of
  instructions to patch, add a global label at the location that needs
  the patch applied.
  
  Reviewed by:	brooks, Alfredo Mazzinghi <alfredo.mazzinghi_cl.cam.ac.uk>
  Sponsored by:	DARPA
  Differential Revision:	https://reviews.freebsd.org/D24931

Modified:
  head/sys/mips/include/md_var.h
  head/sys/mips/mips/cpu.c
  head/sys/mips/mips/swtch.S

Modified: head/sys/mips/include/md_var.h
==============================================================================
--- head/sys/mips/include/md_var.h	Wed May 20 21:02:08 2020	(r361295)
+++ head/sys/mips/include/md_var.h	Wed May 20 21:15:43 2020	(r361296)
@@ -75,6 +75,7 @@ void	mips_cpu_init(void);
 void	mips_pcpu0_init(void);
 void	mips_proc0_init(void);
 void	mips_postboot_fixup(void);
+void	cpu_switch_set_userlocal(void) __asm(__STRING(cpu_switch_set_userlocal));
 
 extern int busdma_swi_pending;
 void	busdma_swi(void);

Modified: head/sys/mips/mips/cpu.c
==============================================================================
--- head/sys/mips/mips/cpu.c	Wed May 20 21:02:08 2020	(r361295)
+++ head/sys/mips/mips/cpu.c	Wed May 20 21:15:43 2020	(r361296)
@@ -68,44 +68,6 @@ struct mips_cpuinfo cpuinfo;
 #define _ENCODE_INSN(a,b,c,d,e) \
     ((uint32_t)(((a) << 26)|((b) << 21)|((c) << 16)|((d) << 11)|(e)))
 
-#if defined(__mips_n64)
-
-#   define	_LOAD_T0_MDTLS_A1 \
-    _ENCODE_INSN(OP_LD, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
-
-#   define	_LOAD_T0_MDTLS_TCV_OFFSET_A1 \
-    _ENCODE_INSN(OP_LD, A1, T1, 0, \
-    offsetof(struct thread, td_md.md_tls_tcb_offset))
-
-#   define	_ADDU_V0_T0_T1 \
-    _ENCODE_INSN(0, T0, T1, V0, OP_DADDU)
-
-#else /* mips 32 */
-
-#   define	_LOAD_T0_MDTLS_A1 \
-    _ENCODE_INSN(OP_LW, A1, T0, 0, offsetof(struct thread, td_md.md_tls))
-
-#   define	_LOAD_T0_MDTLS_TCV_OFFSET_A1 \
-    _ENCODE_INSN(OP_LW, A1, T1, 0, \
-    offsetof(struct thread, td_md.md_tls_tcb_offset))
-
-#   define	_ADDU_V0_T0_T1 \
-    _ENCODE_INSN(0, T0, T1, V0, OP_ADDU)
-
-#endif /* ! __mips_n64 */
-
-#if defined(__mips_n64) || defined(__mips_n32)
-
-#   define _MTC0_V0_USERLOCAL \
-    _ENCODE_INSN(OP_COP0, OP_DMT, V0, 4, 2)
-
-#else /* mips o32 */
-
-#   define _MTC0_V0_USERLOCAL \
-    _ENCODE_INSN(OP_COP0, OP_MT, V0, 4, 2)
-
-#endif /* ! (__mips_n64 || __mipsn32) */
-
 #define	_JR_RA	_ENCODE_INSN(OP_SPECIAL, RA, 0, 0, OP_JR)
 #define	_NOP	0
 
@@ -120,18 +82,9 @@ remove_userlocal_code(uint32_t *cpu_switch_code)
 {
 	uint32_t *instructp;
 
-	for (instructp = cpu_switch_code;; instructp++) {
-		if (instructp[0] == _JR_RA)
-			panic("%s: Unable to patch cpu_switch().", __func__);
-		if (instructp[0] == _LOAD_T0_MDTLS_A1 &&
-		    instructp[1] == _LOAD_T0_MDTLS_TCV_OFFSET_A1 &&
-		    instructp[2] == _ADDU_V0_T0_T1 &&
-		    instructp[3] == _MTC0_V0_USERLOCAL) {
-			instructp[0] = _JR_RA;
-			instructp[1] = _NOP;
-			break;
-		}
-	}
+	instructp = cpu_switch_code;
+	instructp[0] = _JR_RA;
+	instructp[1] = _NOP;
 }
 
 /*
@@ -202,7 +155,7 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
 		 * cpu_switch() and remove unsupported code.
 		 */
 		cpuinfo->userlocal_reg = false;
-		remove_userlocal_code((uint32_t *)cpu_switch);
+		remove_userlocal_code((uint32_t *)cpu_switch_set_userlocal);
 	}
 
 

Modified: head/sys/mips/mips/swtch.S
==============================================================================
--- head/sys/mips/mips/swtch.S	Wed May 20 21:02:08 2020	(r361295)
+++ head/sys/mips/mips/swtch.S	Wed May 20 21:15:43 2020	(r361296)
@@ -383,6 +383,8 @@ sw2:
  * Note that this code is removed if the CPU doesn't support ULRI by
  * remove_userlocal_code() in cpu.c.
  */
+	.globl	cpu_switch_set_userlocal
+cpu_switch_set_userlocal:
 	PTR_L	t0, TD_MDTLS(a1)		# Get TLS pointer
 	PTR_L	t1, TD_MDTLS_TCB_OFFSET(a1)	# Get TLS/TCB offset
 	PTR_ADDU v0, t0, t1


More information about the svn-src-all mailing list