Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 May 2012 14:19:16 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 211581 for review
Message-ID:  <201205231419.q4NEJGf8042245@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@211581?ac=10

Change 211581 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/05/23 14:18:42

	Continue to refine use of the capability coprocessor in MIPS
	exception handlers, providing two common chunks of assembly,
	CHERI_EXCEPTION_ENTER and CHERI_EXCEPTION_RETURN, that know
	how to check whether the source of an exception, or the context
	it will eret to, is kernel or userspace for the purposes of
	reconfiguring C0 at the beginning or end of the exception
	handler.  Use the new UDC register for this purpose.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#3 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#5 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#4 edit

Differences ...

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#3 (text+ko) ====

@@ -73,7 +73,41 @@
  */
 #define	INTRCNT_COUNT	128
 
+#ifdef CPU_CHERI
+/*
+ * When entering an exception handler, conditionally save the default user
+ * data capability.  Then install the kernel's default data capability.  The
+ * caller provides a temporary register to use for the purposes of querying
+ * CP0 SR to determine whether the target is userspace or the kernel.
+ */
+#define	CHERI_EXCEPTION_ENTER(reg)					\
+	mfc0	reg, MIPS_COP_0_STATUS;					\
+	andi	reg, reg, SR_KSU_USER;					\
+	beq	reg, $0, 64f;						\
+	nop;								\
+	cmove	$c25, $c0;						\
+64:									\
+	cmove	$c0, $c30;
+
+/*
+ * When returning from an exception, conditionally restore the default user
+ * data capability.  The caller provides a temporary register to use for the
+ * purposes of querying CP0 SR to determine whether the target is userspace
+ * or the kernel.
+ */
+#define	CHERI_EXCEPTION_RETURN(reg)					\
+	mfc0	reg, MIPS_COP_0_STATUS;					\
+	andi	reg, reg, SR_KSU_USER;					\
+	beq	reg, $0, 65f;						\
+	nop;								\
+	cmove	$c0, $c25;						\
+65:
+#else
+#define	CHERI_EXCEPTION_ENTER(reg)
+#define	CHERI_EXCEPTION_RETURN(reg)
+#endif
 
+
 /*
  *----------------------------------------------------------------------------
  *
@@ -90,10 +124,7 @@
 VECTOR(MipsTLBMiss, unknown)
 	.set push
 	.set noat
-#ifdef CPU_CHERI
-	cmove	$c27, $c0	# Preserve user data segment in $kt1
-	cmove	$c0, $c30	# Restore kernel data segment from $kdc
-#endif
+	CHERI_EXCEPTION_ENTER(k0)
 	j	MipsDoTLBMiss
 	MFC0	k0, MIPS_COP_0_BAD_VADDR	# get the fault address
 	.set pop
@@ -147,10 +178,9 @@
 	COP0_SYNC
 	tlbwr						#1a: write to tlb
 	HAZARD_DELAY
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret						#1f: retUrn from exception
+
 1:	j		MipsTLBMissException		#20: kernel exception
 	nop						#21: branch delay slot
 2:	j		SlowFault			#22: no page table present
@@ -167,10 +197,7 @@
  * Find out what mode we came from and jump to the proper handler.
  */
 	.set	noat
-#ifdef CPU_CHERI
-	cmove	$c27, $c0	# Preserve user data segment in $kt1
-	cmove	$c0, $c30	# Restore kernel data segment from $kdc
-#endif
+	CHERI_EXCEPTION_ENTER(k0)
 	mfc0	k0, MIPS_COP_0_STATUS		# Get the status register
 	mfc0	k1, MIPS_COP_0_CAUSE		# Get the cause register value.
 	and	k0, k0, SR_KSU_USER		# test for user mode
@@ -399,9 +426,8 @@
 	SAVE_REG(a1, SR, sp)
 	RESTORE_CPU			# v0 contains the return address.
 	sync
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	.set	at
 END(MipsKernGenException)
@@ -568,9 +594,7 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# still exception level
 	ITLBNOPFIX
 	sync
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	.set	at
 END(MipsUserGenException)
@@ -663,9 +687,7 @@
 	REG_L	v0, CALLFRAME_RA + KERN_REG_SIZE(sp)
 	RESTORE_CPU			# v0 contains the return address.
 	sync
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	.set	at
 END(MipsKernIntr)
@@ -841,9 +863,7 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# SR with EXL set. 
 	ITLBNOPFIX
 	sync
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	.set	at
 END(MipsUserIntr)
@@ -939,17 +959,13 @@
 	bltz		k0, tlb_insert_random
 	nop
 	tlbwi
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	ssnop
 
 tlb_insert_random:
 	tlbwr
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	ssnop
 
@@ -1081,9 +1097,7 @@
 	COP0_SYNC
 	tlbwr					# write to tlb
 	HAZARD_DELAY
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret					# return from exception
 	.set	at
 END(MipsTLBMissException)
@@ -1236,10 +1250,7 @@
  */
 	.text
 VECTOR(MipsCache, unknown)
-#ifdef CPU_CHERI
-	cmove	$c27, $c0	# Preserve user data segment in $kt1
-	cmove	$c0, $c30	# Restore kernel data segment from $kdc
-#endif
+	CHERI_EXCEPTION_ENTER(k0)
 	PTR_LA	k0, _C_LABEL(MipsCacheException)
 	li	k1, MIPS_KSEG0_PHYS_MASK
 	and	k0, k1
@@ -1272,9 +1283,7 @@
 	mtc0	k0, MIPS_COP_0_STATUS		# restore status
 	COP0_SYNC
 
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 
 	MSG("cache error @ EPC 0x%x CachErr 0x%x");

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#5 (text+ko) ====

@@ -145,9 +145,13 @@
 #if defined(CPU_CHERI)
 	/*
 	 * On CHERI MIPS, preserve the kernel's data segment context for use
-	 * in exception handlers.  $kcc will be preserved by the first eret.
+	 * in exception handlers.
+	 *
+	 * XXXRW: Do we want to rely on default initialisation of all CP2
+	 * registers here?
 	 */
 	cmove	$c30, $c0		# Preserve $kdc
+	cmove	$c29, $c0		# Preserve $kcc	
 
 	/*
 	 * Initialise saved user $c0 so we can later restore it.
@@ -155,7 +159,7 @@
 	 * XXXRW: This will be removed once we more explicitly manage user
 	 * thread capabilities.
 	 */
-	cmove	$c27, $c0		#
+	cmove	$c25, $c0		# Global $udc for now
 #endif
 
 	/*xxximp

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#4 (text+ko) ====

@@ -92,8 +92,41 @@
 #define	RESTORE_U_PCB_CONTEXT(reg, offs, base) \
 	REG_L	reg, U_PCB_CONTEXT + (SZREG * offs) (base)
 
+#ifdef CPU_CHERI
+/*
+ * When entering an exception handler, conditionally save the default user
+ * data capability.  Then install the kernel's default data capability.  The
+ * caller provides a temporary register to use for the purposes of querying
+ * CP0 SR to determine whether the target is userspace or the kernel.
+ */
+#define	CHERI_EXCEPTION_ENTER(reg)					\
+	mfc0	reg, MIPS_COP_0_STATUS;					\
+	andi	reg, reg, SR_KSU_USER;					\
+	beq	reg, $0, 64f;						\
+	nop;								\
+	cmove	$c25, $c0;						\
+64:									\
+	cmove	$c0, $c30;
 
 /*
+ * When returning from an exception, conditionally restore the default user
+ * data capability.  The caller provides a temporary register to use for the
+ * purposes of querying CP0 SR to determine whether the target is userspace
+ * or the kernel.
+ */
+#define	CHERI_EXCEPTION_RETURN(reg)					\
+	mfc0	reg, MIPS_COP_0_STATUS;					\
+	andi	reg, reg, SR_KSU_USER;					\
+	beq	reg, $0, 65f;						\
+	nop;								\
+	cmove	$c0, $c25;						\
+65:
+#else
+#define	CHERI_EXCEPTION_ENTER(reg)
+#define	CHERI_EXCEPTION_RETURN(reg)
+#endif
+
+/*
  * Setup for and return to user.
  */
 LEAF(fork_trampoline)
@@ -162,9 +195,7 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# switch to user mode (when eret...)
 	HAZARD_DELAY
 	sync
-#ifdef CPU_CHERI
-	cmove		$c0, $c27	# Restore user data segment
-#endif
+	CHERI_EXCEPTION_RETURN(k0)
 	eret
 	.set	at
 END(fork_trampoline)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205231419.q4NEJGf8042245>