Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Sep 2013 18:03:31 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 882542 for review
Message-ID:  <201309281803.r8SI3VkA080558@skunkworks.freebsd.org>

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

Change 882542 by rwatson@rwatson_zenith_cl_cam_ac_uk on 2013/09/28 18:03:04

	Various changes on the path to a (very experimental) software-path
	CCall/CReturn implementation:
	
	- Provide a temporary trusted stack implementation via a single
	  global frame entry, but lay some of the groundwork for a trust
	  per-thread trusted stack.
	
	- Pull more of the CCall implementation from test_cp2_ccall2.s:
	  push the old IDC, PCC, and PC+4 to the temporary trusted stack.
	  Unseal code and data capabilities into EPCC and IDC, and install
	  the new PC.
	
	- Pull more of the CReturn implementation from test_cp2_ccall2.s:
	  pop IDC, EPCC, and PC from the temporary trusted stack.
	
	Attempting to execute this path wedges the CPU, but it seems likely
	that even if it did not, this code would not [yet] work.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/ccall.S#6 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri.c#16 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#23 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheriasm.h#12 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#12 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#9 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#6 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#10 edit

Differences ...

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

@@ -1,6 +1,6 @@
 /*-
- * Copyright (c) 2013 Robert N. M. Watson
- * Copyright (c) 2013 Michael Roe
+ * Copyright (c) 2012-2013 Robert N. M. Watson
+ * Copyright (c) 2012-2013 Michael Roe
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -94,38 +94,101 @@
 
 /*
  * Software implementation of CCall; this code does not need to be position-
- * independent.
+ * independent as it is not relocated to an exception vector.
+ *
+ * XXXRW: This software implementation of CCall uses an alternative calling
+ * convention, in which the code capability to invoke is always placed in $c1,
+ * and the corresponding data capability is always placed in $c2.  This
+ * prevents software from having to copy in the faulting ccall instruction,
+ * decoding it, and then switch()ing on the register numbers to use the right
+ * instruction to extract the capabilities to fixed ones targetable in
+ * assembly and by the compiler.
+ *
+ * XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc.  We
+ * need a C error-handling path.
  *
- * XXXRW: Gubbins missing.
+ * XXXRW: Temporarily, store a one-entry trusted stack in a global.  k1 should
+ * eventually point to the next entry in td->td_pcb.pcb_cheristack, with an
+ * overflow check.
  */
 CHERICCall:
         .set push
         .set noat
 
-	/* XXXRW: For now, increment PC as though it were a no-op. */
-        MFC0	k0, MIPS_COP_0_EXC_PC
-	PTR_ADDU	k0, 4
-	MTC0	k0, MIPS_COP_0_EXC_PC
+	/* XXXRW: Change to PCB reference in the future. */
+	PTR_LA		k1, cheri_tsc_hack
+
+	/* Push IDC. */
+	csc		CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC)
+
+	/* Push PCC. */
+	csc		CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC)
+
+	/* Push PC + 4 */
+	MFC0		k0, MIPS_COP_0_EXC_PC
+	daddiu		k0, 4
+	csd		k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC)
+
+	/*
+	 * Temporarily set KDC type to allow unsealing.
+	 *
+	 * XXXRW: This is inefficient and (should be) unnecessary.
+	 */
+	cgettype	k0, CHERI_REG_CCALLCODE
+	csettype	CHERI_REG_KDC, CHERI_REG_KDC, k0
+
+	/* Unseal cs; install in PCC. */
+	cunseal		CHERI_REG_EPCC, CHERI_REG_CCALLCODE, CHERI_REG_KDC
+
+	/* Unseal cb; install in IDC. */
+	cunseal		CHERI_REG_IDC, CHERI_REG_CCALLDATA, CHERI_REG_KDC
+
+	/* Installe cs.otype - cs.base into PC; note clobbers k1. */
+	cgettype	k0, CHERI_REG_CCALLCODE
+	cgetbase	k1, CHERI_REG_CCALLCODE
+	dsub		k0, k0, k1
+	MTC0		k0, MIPS_COP_0_EXC_PC
 	COP0_SYNC
 
+	/*
+	 * Restore KDC type.
+	 *
+	 * XXXRW: This should also be unnecessary.
+	 */
+	PTR_LI		k0, 0
+	csettype	CHERI_REG_KDC, CHERI_REG_KDC, k0
+
 	CHERI_EXCEPTION_RETURN(k0)
 	eret
         .set pop
 
 /*
  * Software implementation of CReturn; this code does not need to be position-
- * independent.
+ * independent as it is not relocated to an exception vector.
+ *
+ * XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc.  We
+ * need a C error handling path.
  *
- * XXXRW: Gubbins missing.
+ * XXXRW: Temporarily, store a one-entry trusted stack in a global.  k1 should
+ * eventually point to the next entry in td->td_pcb.pcb_cheristack, with an
+ * underflow check.
  */
 CHERICReturn:
         .set push
         .set noat
 
-	/* XXXRW: For now, increment PC as though it were a no-op. */
-        MFC0	k0, MIPS_COP_0_EXC_PC
-	PTR_ADDU	k0, 4
-	MTC0	k0, MIPS_COP_0_EXC_PC
+	/* XXXRW: Change to PCB reference in the future. */
+	PTR_LA		k1, cheri_tsc_hack
+
+	/* Pop IDC. */
+	clc		CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC)
+
+	/* Pop PCC. */
+	csc		CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC)
+
+	/* Pop PC + padding; +4 increment already done. */
+	cld		k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC)
+	MTC0		k0, MIPS_COP_0_EXC_PC
 	COP0_SYNC
 
 	CHERI_EXCEPTION_RETURN(k0)

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

@@ -73,6 +73,13 @@
     "Run debugger on CHERI exception");
 
 /*
+ * XXXRW: Temporary hack -- single global trusted stack used by any instance
+ * of CCall or CReturn in any thread of any process.  This won't last long,
+ * but is enough to test things a little.
+ */
+struct cheri_stack_frame	cheri_tsc_hack;
+
+/*
  * Given an existing more privileged capability (fromcrn), build a new
  * capability in tocrn with the contents of the passed flattened
  * representation.
@@ -224,6 +231,8 @@
 	bzero(cfp, sizeof(*cfp));
 	cheri_capability_set_user(&cfp->cf_c0);
 	cheri_capability_set_user(&cfp->cf_pcc);
+
+	/* XXXRW: Trusted stack initialisation here? */
 }
 
 #define	CHERI_REG_PRINT(c, ctag, num) do {				\

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

@@ -99,6 +99,34 @@
 	struct chericap	cf_pcc;
 };
 CTASSERT(sizeof(struct cheri_frame) == (28 * CHERICAP_SIZE));
+
+/*
+ * Per-thread CHERI CCall/CReturn stack, which preserves the calling PC/PCC/
+ * IDC across CCall so that CReturn can restore them.
+ *
+ * XXXRW: This is a very early experiment -- it's not clear if this idea will
+ * persist in its current form, or at all.  For more complex userspace
+ * language, there's a reasonable expectation that it, rather than the kernel,
+ * will want to manage the idea of a "trusted stack".
+ */
+struct cheri_stack_frame {
+	register_t	csf_pc;
+	register_t	_csf_pad0;
+	register_t	_csf_pad1;
+	register_t	_csf_pad2;
+	struct chericap	csf_pcc;
+	struct chericap	csf_idc;
+};
+
+#define	CHERI_STACK_DEPTH	10	/* XXXRW: 10 is a nice round number. */
+struct cheri_stack {
+	u_int		cs_max;		/* Maximum frame depth. */
+	u_int		cs_pointer;	/* Current frame index. */
+	register_t	_cs_pad0;
+	register_t	_cs_pad1;
+	register_t	_cs_pad2;
+	struct cheri_stack_frame	cs_frames[CHERI_STACK_DEPTH];
+} __aligned(CHERICAP_SIZE);
 #endif
 
 /*

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

@@ -87,6 +87,13 @@
 #define	CHERI_REG_SEC0	CHERI_REG_KR2C	/* Saved $c0 in exception handling. */
 
 /*
+ * (Possibly) temporary ABI in which $c1 is the code argument to CCall, and
+ * $c2 is the data argument.
+ */
+#define	CHERI_REG_CCALLCODE	$c1
+#define	CHERI_REG_CCALLDATA	$c2
+
+/*
  * Assembly code to be used in CHERI exception handling and context switching.
  *
  * When entering an exception handler from userspace, conditionally save the

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


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

@@ -73,7 +73,8 @@
 {
 	struct trapframe pcb_regs;	/* saved CPU and registers */
 #ifdef CPU_CHERI
-        struct cheri_frame pcb_cheriframe;	/* Userspace capabilities. */
+	struct cheri_frame pcb_cheriframe;	/* Userspace capabilities. */
+	struct cheri_stack pcb_cheristack;	/* CCall/CReturn stack. */
 #endif
 	__register_t pcb_context[14];	/* kernel context for resume */
 	void *pcb_onfault;		/* for copyin/copyout faults */

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

@@ -74,9 +74,6 @@
 ASSYM(TD_MDFLAGS, offsetof(struct thread, td_md.md_flags));
 
 ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero));
-#ifdef CPU_CHERI
-ASSYM(U_PCB_CHERIFRAME, offsetof(struct pcb, pcb_cheriframe.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));
@@ -108,6 +105,13 @@
 ASSYM(MIPS_KSEG2_START, MIPS_KSEG2_START);
 ASSYM(MIPS_XKSEG_START, MIPS_XKSEG_START);
 
+#ifdef	CPU_CHERI
+ASSYM(U_PCB_CHERIFRAME, offsetof(struct pcb, pcb_cheriframe.cf_c0));
+ASSYM(U_CHERI_STACK_PC, offsetof(struct cheri_stack_frame, csf_pc));
+ASSYM(U_CHERI_STACK_PCC, offsetof(struct cheri_stack_frame, csf_pcc));
+ASSYM(U_CHERI_STACK_IDC, offsetof(struct cheri_stack_frame, csf_idc));
+#endif
+
 #ifdef	CPU_CNMIPS
 ASSYM(TD_COP2OWNER, offsetof(struct thread, td_md.md_cop2owner));
 ASSYM(TD_COP2, offsetof(struct thread, td_md.md_cop2));

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

@@ -151,6 +151,8 @@
 	 */
 	cheri_context_copy(&pcb2->pcb_cheriframe,
 	    &td1->td_pcb->pcb_cheriframe);
+
+	/* XXXRW: Trusted stack initialisation here? */
 #endif
 
 	/* Point mdproc and then copy over td1's contents
@@ -432,6 +434,8 @@
 	 */
 	cheri_context_copy(&pcb2->pcb_cheriframe,
 	    &td0->td_pcb->pcb_cheriframe);
+
+	/* XXXRW: Trusted stack initialisation here? */
 #endif
 
 	/*



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