PERFORCE change 213130 for review

Robert Watson rwatson at FreeBSD.org
Tue Jun 19 10:22:03 UTC 2012


http://p4web.freebsd.org/@@213130?ac=10

Change 213130 by rwatson at rwatson_svr_ctsrd_mipsbuild on 2012/06/19 10:20:58

	Checkpoint CHERI CP2 userspace context management for
	FreeBSD/CHERI:
	
	1. Introduce two new header files, cp2asm.h and cp2reg.h,
	   appropriate for inclusion from both assembly and C files.
	
	2. Centralise previously distributed definitions of
	   CHERI_EXCEPTION_ENTER() and CHERI_EXCEPTION_RETURN() in
	   cp2asm.h.
	
	3. For now, maintain only a userspace cp2frame, not a kernel
	   one, so remove nascent kernel frame from struct pcb.
	
	4. Add new SAVE_CP2_CONTEXT() and RESTORE_CP2_CONTEXT() routines
	   to save and restore userspace CP2 registers in the pcb.
	
	5. Save and restore CP2 state for userspace-sourced system calls
	   and interrupts that fire during usersapce execution.  Also
	   restore userspace CP2 state when returning from
	   fork_trampoline().
	
	With this change, the skeleton is in place to support
	capability-aware userspace programs.  Refinement will
	undoubtably be required, and the object capability invocation
	exception handler is currently unimplemented in this cut.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#6 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#8 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2asm.h#1 add
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2reg.h#1 add
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#3 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#4 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#2 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#5 edit

Differences ...

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#6 (text+ko) ====

@@ -465,7 +465,7 @@
 {
 	struct cp2_frame *cfp;
 
-	cfp = &td->td_pcb->pcb_ucp2frame;
+	cfp = &td->td_pcb->pcb_cp2frame;
 	cp2_capability_load(CHERI_CR_CT0, &cp2_user_template);
 	cp2_capability_store(CHERI_CR_CT0, &cfp->cf_c0);
 	cp2_capability_store(CHERI_CR_CT0, &cfp->cf_c1);

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#8 (text+ko) ====

@@ -33,55 +33,9 @@
 
 #include <sys/systm.h>		/* CTASSERT */
 
-/*
- * CHERI ISA-defined constants for capabilities.
- *
- * XXXRW: CHERI_UNSEALED is not currently considered part of the perms word,
- * but perhaps it should be.
- */
-#define	CHERI_PERM_EXECUTE			0x0001
-#define	CHERI_PERM_STORE_CAPABILITY		0x0002
-#define	CHERI_PERM_LOAD_CAPABILITY		0x0004
-#define	CHERI_PERM_STORE			0x0008
-#define	CHERI_PERM_LOAD				0x0010
-#define	CHERI_PERM_STORE_EPHEMERAL_CAPABILITY	0x0020
-#define	CHERI_PERM_SEAL				0x0040
-#define	CHERI_PERM_SET_TYPE			0x0080
-#define	CHERI_PERM_RESERVED0			0x0100
-#define	CHERI_PERM_RESERVED1			0x0200
-#define	CHERI_PERM_ACCESS_TSC			0x0400
-#define	CHERI_PERM_ACCESS_KCC			0x0800
-#define	CHERI_PERM_ACCESS_KDC			0x1000
-#define	CHERI_PERM_ACCESS_EPCC			0x2000
-#define	CHERI_PERM_NON_EPHEMERAL		0x4000
-#define	CHERI_UNSEALED				0x8000
-
-/*
- * XXXRW: Should this include CHERI_UNSEALED?
- */
-#define	CHERI_PERM_ALL							\
-	(CHERI_PERM_EXECUTE | CHERI_PERM_STORE_CAPABILITY |		\
-	CHERI_PERM_LOAD_CAPABILITY | CHERI_PERM_STORE |			\
-	CHERI_PERM_STORE_EPHEMERAL_CAPABILITY | CHERI_PERM_SEAL |	\
-	CHERI_PERM_SET_TYPE | CHERI_PERM_RESERVED0 |			\
-	CHERI_PERM_RESERVED1 | CHERI_PERM_ACCESS_TSC |			\
-	CHERI_PERM_ACCESS_KCC | CHERI_PERM_ACCESS_KDC |			\
-	CHERI_PERM_ACCESS_EPCC | CHERI_PERM_NON_EPHEMERAL)
+#include <mips/cheri/cp2reg.h>
 
 /*
- * A blend of hardware and software allocation of capability registers.
- */
-#define	CHERI_CR_C0	0	/*   MIPS fetch/load/store capability. */
-#define	CHERI_CR_CT0	10	/*   CT0: temporary capability. */
-#define	CHERI_CR_UDC	25	/*   SC0: user data capability. */
-#define	CHERI_CR_KT0	26	/*   KT0: temporary kernel capability. */
-#define	CHERI_CR_KT1	27	/*   KT1: temporary kernel capability. */
-#define	CHERI_CR_TSC	28	/*   TSC: trusted stack capability. */
-#define	CHERI_CR_KCC	29	/*   KCC: kernel code capability. */
-#define	CHERI_CR_KDC	30	/*   KDC: kernel data capability. */
-#define	CHERI_CR_EPCC	31	/*   EPCC: exception program counter cap. */
-
-/*
  * Canonical C-language representation of a capability.
  */
 #define	CAPABILITY_SIZE	32
@@ -101,6 +55,8 @@
  * Register frame to be preserved on context switching -- very similar to
  * struct mips_frame.  As with mips_frame, the order of save/restore is very
  * important for both reasons of correctness and security.
+ *
+ * Must match the register offset definitions (CHERI_*_OFF) in cp2reg.h.
  */
 struct cp2_frame {
 	/* c0 has special properties for MIPS load/store instructions. */

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#3 (text+ko) ====

@@ -55,12 +55,9 @@
 {
 	struct trapframe pcb_regs;	/* saved CPU and registers */
 #ifdef CPU_CHERI
-        struct cp2_frame        pcb_ucp2frame;
+        struct cp2_frame pcb_cp2frame;	/* Userspace capabilities. */
 #endif
 	__register_t pcb_context[14];	/* kernel context for resume */
-#ifdef CPU_CHERI
-        struct cp2_frame        pcb_cp2frame;
-#endif
 	void *pcb_onfault;		/* for copyin/copyout faults */
 	register_t pcb_tpc;
 };

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

@@ -62,6 +62,11 @@
 #include <machine/cpuregs.h>
 #include <machine/pte.h>
 
+#ifdef CPU_CHERI
+#include <mips/cheri/cp2asm.h>
+#include <mips/cheri/cp2reg.h>
+#endif
+
 #include "opt_cputype.h"
 
 #include "assym.s"
@@ -73,42 +78,8 @@
  */
 #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
-
-
-/*
  *----------------------------------------------------------------------------
  *
  * MipsTLBMiss --
@@ -124,7 +95,9 @@
 VECTOR(MipsTLBMiss, unknown)
 	.set push
 	.set noat
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_ENTER(k0)
+#endif
 	j	MipsDoTLBMiss
 	MFC0	k0, MIPS_COP_0_BAD_VADDR	# get the fault address
 	.set pop
@@ -178,7 +151,9 @@
 	COP0_SYNC
 	tlbwr						#1a: write to tlb
 	HAZARD_DELAY
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret						#1f: retUrn from exception
 
 1:	j		MipsTLBMissException		#20: kernel exception
@@ -197,7 +172,9 @@
  * Find out what mode we came from and jump to the proper handler.
  */
 	.set	noat
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_ENTER(k0)
+#endif
 	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
@@ -427,7 +404,9 @@
 	RESTORE_CPU			# v0 contains the return address.
 	sync
 
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	.set	at
 END(MipsKernGenException)
@@ -504,6 +483,9 @@
 	SAVE_U_PCB_REG(a1, CAUSE, k1)
 	SAVE_U_PCB_REG(a2, BADVADDR, k1)
 	SAVE_U_PCB_REG(a3, PC, k1)
+#ifdef CPU_CHERI
+	SAVE_CP2_CONTEXT(t0, k1)
+#endif
 	REG_S	a3, CALLFRAME_RA(sp)	# for debugging
 	PTR_LA	gp, _C_LABEL(_gp)	# switch to kernel GP
 # Turn off fpu and enter kernel mode
@@ -553,6 +535,9 @@
 	or	a1, a1, a0
 	SAVE_U_PCB_REG(a1, SR, k1)
 
+#ifdef CPU_CHERI
+	RESTORE_CP2_CONTEXT(t0, k1)
+#endif
 	RESTORE_U_PCB_REG(t0, MULLO, k1)
 	RESTORE_U_PCB_REG(t1, MULHI, k1)
 	mtlo	t0
@@ -594,7 +579,9 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# still exception level
 	ITLBNOPFIX
 	sync
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	.set	at
 END(MipsUserGenException)
@@ -687,7 +674,9 @@
 	REG_L	v0, CALLFRAME_RA + KERN_REG_SIZE(sp)
 	RESTORE_CPU			# v0 contains the return address.
 	sync
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	.set	at
 END(MipsKernIntr)
@@ -764,6 +753,9 @@
 	SAVE_U_PCB_REG(a0, SR, k1)
 	SAVE_U_PCB_REG(a1, CAUSE, k1)
 	SAVE_U_PCB_REG(a3, PC, k1)	# PC in a3, note used later!
+#ifdef CPU_CHERI
+	SAVE_CP2_CONTEXT(t0, k1)
+#endif
 	PTR_SUBU	sp, k1, CALLFRAME_SIZ  # switch to kernel SP
 	PTR_LA	gp, _C_LABEL(_gp)	# switch to kernel GP
 
@@ -822,6 +814,9 @@
 	or	a1, a1, a0
 	SAVE_U_PCB_REG(a1, SR, k1)
 
+#ifdef CPU_CHERI
+	RESTORE_CP2_CONTEXT(t0, k1)
+#endif
 	RESTORE_U_PCB_REG(s0, S0, k1)
 	RESTORE_U_PCB_REG(s1, S1, k1)
 	RESTORE_U_PCB_REG(s2, S2, k1)
@@ -863,7 +858,9 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# SR with EXL set. 
 	ITLBNOPFIX
 	sync
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	.set	at
 END(MipsUserIntr)
@@ -959,13 +956,17 @@
 	bltz		k0, tlb_insert_random
 	nop
 	tlbwi
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	ssnop
 
 tlb_insert_random:
 	tlbwr
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	ssnop
 
@@ -1097,7 +1098,9 @@
 	COP0_SYNC
 	tlbwr					# write to tlb
 	HAZARD_DELAY
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret					# return from exception
 	.set	at
 END(MipsTLBMissException)
@@ -1250,7 +1253,9 @@
  */
 	.text
 VECTOR(MipsCache, unknown)
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_ENTER(k0)
+#endif
 	PTR_LA	k0, _C_LABEL(MipsCacheException)
 	li	k1, MIPS_KSEG0_PHYS_MASK
 	and	k0, k1
@@ -1283,7 +1288,9 @@
 	mtc0	k0, MIPS_COP_0_STATUS		# restore status
 	COP0_SYNC
 
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 
 	MSG("cache error @ EPC 0x%x CachErr 0x%x");

==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#2 (text+ko) ====

@@ -78,6 +78,9 @@
 ASSYM(TF_REG_SR, offsetof(struct trapframe, sr));
 
 ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero));
+#ifdef CPU_CHERI
+ASSYM(U_PCB_CP2FRAME, offsetof(struct pcb, pcb_cp2frame.cf_c0));
+#endif
 ASSYM(U_PCB_CONTEXT, offsetof(struct pcb, pcb_context));
 ASSYM(U_PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
 ASSYM(U_PCB_FPREGS, offsetof(struct pcb, pcb_regs.f0));

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

@@ -64,6 +64,11 @@
 #include <machine/regnum.h>
 #include <machine/pte.h>
 
+#ifdef CPU_CHERI
+#include <mips/cheri/cp2asm.h>
+#include <mips/cheri/cp2reg.h>
+#endif
+
 #include "assym.s"
 
 	.set	noreorder			# Noreorder is default style!
@@ -92,40 +97,6 @@
 #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.
  */
@@ -150,6 +121,9 @@
 	GET_CPU_PCPU(k1)
 	PTR_L	k1, PC_CURPCB(k1)
 
+#ifdef CPU_CHERI
+	RESTORE_CP2_CONTEXT(t0, k1)
+#endif
 	RESTORE_U_PCB_REG(t0, MULLO, k1)
 	RESTORE_U_PCB_REG(t1, MULHI, k1)
 	mtlo	t0
@@ -195,7 +169,9 @@
 	mtc0	k0, MIPS_COP_0_STATUS	# switch to user mode (when eret...)
 	HAZARD_DELAY
 	sync
+#ifdef CPU_CHERI
 	CHERI_EXCEPTION_RETURN(k0)
+#endif
 	eret
 	.set	at
 END(fork_trampoline)


More information about the p4-projects mailing list