PERFORCE change 211581 for review
Robert Watson
rwatson at FreeBSD.org
Wed May 23 14:19:17 UTC 2012
http://p4web.freebsd.org/@@211581?ac=10
Change 211581 by rwatson at 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)
More information about the p4-projects
mailing list