PERFORCE change 213491 for review

Robert Watson rwatson at FreeBSD.org
Tue Jun 26 14:18:18 UTC 2012


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

Change 213491 by rwatson at rwatson_svr_ctsrd_mipsbuild on 2012/06/26 14:17:55

	Refine and generally improve kernel CP2 management:
	
	Don't maintain a PCB CP2 frame entry for udc (user data
	capability), as that's actually just the kernel's register for
	temporarily holding userspace's c0, which we already have a field
	for.  
	
	Fix a bug in which PCC isn't properly saved and restored for 
	capability-aware processes -- no symptoms yet, but they would have
	turned up in due course.
	
	Add DDB functions to print the current CP0 register file, and also 
	preserved CP2 state for a thread (by default, the current thread).
	
	Fix a mistranscription of various capability permissions, and
	define a more refined set of rights for user processes.
	
	With these changes, capability registers appear to be properly
	initialised by execve(), maintained across a variety of context
	switches, conventional programs work properly, and programs that
	manipulate capabilities are able to do so successfully.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#9 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#4 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheriasm.h#3 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#4 edit

Differences ...

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

@@ -28,10 +28,14 @@
  * SUCH DAMAGE.
  */
 
+#include "opt_ddb.h"
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/proc.h>
 
+#include <ddb/ddb.h>
+
 #include <machine/cheri.h>
 #include <machine/pcb.h>
 
@@ -153,7 +157,6 @@
 	cp2_capability_copy(&cf_destp->cf_c22, &cf_srcp->cf_c22);
 	cp2_capability_copy(&cf_destp->cf_c23, &cf_srcp->cf_c23);
 	cp2_capability_copy(&cf_destp->cf_c24, &cf_srcp->cf_c24);
-	cp2_capability_copy(&cf_destp->cf_udc, &cf_srcp->cf_udc);
 	cp2_capability_copy(&cf_destp->cf_tsc, &cf_srcp->cf_tsc);
 	cp2_capability_copy(&cf_destp->cf_pcc, &cf_srcp->cf_pcc);
 }
@@ -479,7 +482,94 @@
 	cp2_capability_set_null(&cfp->cf_c22);
 	cp2_capability_set_null(&cfp->cf_c23);
 	cp2_capability_set_null(&cfp->cf_c24);
-	cp2_capability_set_null(&cfp->cf_udc);
 	cp2_capability_set_null(&cfp->cf_tsc);
 	cp2_capability_set_null(&cfp->cf_pcc);
 }
+
+#ifdef DDB
+#define	DB_CP2_REG_PRINT_NUM(crn, num) do {				\
+	struct capability c;						\
+									\
+	CP2_CR_GET((crn), c);						\
+	db_printf("C%u perms %08jx otype %016jx\n", num,		\
+	    (uintmax_t)c.c_uperms, (uintmax_t)c.u.c_otype);		\
+	db_printf("\tbase %016jx length %016jx\n", (uintmax_t)c.c_base,	\
+	    (uintmax_t)c.c_length);					\
+} while (0)
+
+#define	DB_CP2_REG_PRINT(crn)	 DB_CP2_REG_PRINT_NUM(crn, crn)
+
+/*
+ * Variation that prints live register state from CP2.
+ */
+DB_SHOW_COMMAND(cp0, ddb_dump_cp0)
+{
+
+	db_printf("CP0 registers\n");
+	DB_CP2_REG_PRINT(0);
+	DB_CP2_REG_PRINT(1);
+	DB_CP2_REG_PRINT(2);
+	DB_CP2_REG_PRINT(3);
+	DB_CP2_REG_PRINT(4);
+	DB_CP2_REG_PRINT(5);
+	DB_CP2_REG_PRINT(6);
+	DB_CP2_REG_PRINT(7);
+	DB_CP2_REG_PRINT(8);
+	DB_CP2_REG_PRINT(9);
+	DB_CP2_REG_PRINT(10);
+	DB_CP2_REG_PRINT(11);
+	DB_CP2_REG_PRINT(12);
+	DB_CP2_REG_PRINT(13);
+	DB_CP2_REG_PRINT(14);
+	DB_CP2_REG_PRINT(15);
+	DB_CP2_REG_PRINT(16);
+	DB_CP2_REG_PRINT(17);
+	DB_CP2_REG_PRINT(18);
+	DB_CP2_REG_PRINT(19);
+	DB_CP2_REG_PRINT(20);
+	DB_CP2_REG_PRINT(21);
+	DB_CP2_REG_PRINT(22);
+	DB_CP2_REG_PRINT(23);
+	DB_CP2_REG_PRINT(24);
+	DB_CP2_REG_PRINT(25);
+	DB_CP2_REG_PRINT(26);
+	DB_CP2_REG_PRINT(27);
+	DB_CP2_REG_PRINT(28);
+	DB_CP2_REG_PRINT(29);
+	DB_CP2_REG_PRINT(30);
+	DB_CP2_REG_PRINT(31);
+}
+
+/*
+ * Variation that prints the saved userspace CP2 register frame for a thread.
+ */
+DB_SHOW_COMMAND(cp0frame, ddb_dump_cp0frame)
+{
+	struct thread *td;
+	struct cp2_frame *cfp;
+	u_int i;
+
+	if (have_addr)
+		td = db_lookup_thread(addr, TRUE);
+	else
+		td = curthread;
+
+	cfp = &td->td_pcb->pcb_cp2frame;
+	db_printf("Thread %d at %p\n", td->td_tid, td);
+	db_printf("CP2 frame at %p\n", cfp);
+
+	/* Laboriously load and print each capability. */
+	for (i = 0; i < 25; i++) {
+		cp2_capability_load(CHERI_CR_CT0,
+		(struct capability *)&cfp->cf_c0 + i);
+		DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, i);
+	}
+	db_printf("\nTSC and PCC:\n");
+	cp2_capability_load(CHERI_CR_CT0, (struct capability *)&cfp->cf_c0 +
+	    CHERI_CR_TSC_OFF);
+	DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, CHERI_CR_TSC);
+	cp2_capability_load(CHERI_CR_CT0, (struct capability *)&cfp->cf_c0 +
+	    CHERI_CR_PCC_OFF);
+	DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, CHERI_CR_EPCC);
+}
+#endif

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

@@ -84,13 +84,12 @@
 	 * Special-purpose capability registers that must be preserved on a
 	 * user context switch.  Note that KT0, KT1, KCC, and KDC are omitted.
 	 */
-	struct capability	cf_udc;
 	struct capability	cf_tsc;
 
 	/* Program counter capability. */
 	struct capability	cf_pcc;
 };
-CTASSERT(sizeof(struct cp2_frame) == (28 * CAPABILITY_SIZE));
+CTASSERT(sizeof(struct cp2_frame) == (27 * CAPABILITY_SIZE));
 #endif
 
 /*

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

@@ -119,8 +119,8 @@
 	SAVE_U_PCB_CP2REG(treg, $c22, CHERI_CR_C22_OFF, base);		\
 	SAVE_U_PCB_CP2REG(treg, $c23, CHERI_CR_C23_OFF, base);		\
 	SAVE_U_PCB_CP2REG(treg, $c24, CHERI_CR_C24_OFF, base);		\
-	SAVE_U_PCB_CP2REG(treg, $c25, CHERI_CR_UDC_OFF, base);		\
-	SAVE_U_PCB_CP2REG(treg, $c28, CHERI_CR_TSC_OFF, base)
+	SAVE_U_PCB_CP2REG(treg, $c28, CHERI_CR_TSC_OFF, base);		\
+	SAVE_U_PCB_CP2REG(treg, $c31, CHERI_CR_PCC_OFF, base)
 
 #define	RESTORE_CP2_CONTEXT(treg, base)					\
 	RESTORE_U_PCB_CP2REG(treg, $c25, CHERI_CR_C0_OFF, base);	\
@@ -148,7 +148,7 @@
 	RESTORE_U_PCB_CP2REG(treg, $c22, CHERI_CR_C22_OFF, base);	\
 	RESTORE_U_PCB_CP2REG(treg, $c23, CHERI_CR_C23_OFF, base);	\
 	RESTORE_U_PCB_CP2REG(treg, $c24, CHERI_CR_C24_OFF, base);	\
-	RESTORE_U_PCB_CP2REG(treg, $c25, CHERI_CR_UDC_OFF, base);	\
-	RESTORE_U_PCB_CP2REG(treg, $c28, CHERI_CR_TSC_OFF, base)
+	RESTORE_U_PCB_CP2REG(treg, $c28, CHERI_CR_TSC_OFF, base);	\
+	RESTORE_U_PCB_CP2REG(treg, $c31, CHERI_CR_PCC_OFF, base)
 
 #endif /* _MIPS_INCLUDE_CHERIASM_H_ */

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

@@ -38,34 +38,38 @@
  * 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
+#define	CHERI_PERM_NON_EPHEMERAL		0x0001
+#define	CHERI_PERM_ACCESS_CR31			0x0002
+#define	CHERI_PERM_ACCESS_CR30			0x0004
+#define	CHERI_PERM_ACCESS_CR29			0x0008
+#define	CHERI_PERM_ACCESS_CR28			0x0010
+#define	CHERI_PERM_RESERVED1			0x0020
+#define	CHERI_PERM_RESERVED2			0x0040
+#define	CHERI_PERM_RESERVED3			0x0080
+#define	CHERI_PERM_SEAL				0x0100
+#define	CHERI_PERM_STORE_EPHEMERAL_CAPABILITY	0x0200
+#define	CHERI_PERM_LOAD				0x0400
+#define	CHERI_PERM_STORE			0x0800
+#define	CHERI_PERM_LOAD_CAP			0x1000
+#define	CHERI_PERM_STORE_CAP			0x2000
+#define	CHEIR_PERM_EXECUTE			0x4000
 
 /*
  * 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)
+#define	CHERI_PERM_PRIV							\
+	(CHERI_PERM_NON_EPHEMERAL | CHERI_PERM_ACCESS_CR31 |		\
+	CHERI_PERM_ACCESS_CR30 | CHERI_PERM_ACCESS_CR29 |		\
+	CHERI_PERM_ACCESS_CR28 | CHERI_PERM_SEAL |			\
+	CHERI_PERM_STORE_EPHEMERAL_CAPABILITY | CHERI_PERM_LOAD |	\
+	CHERI_PERM_STORE | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE_CAP |	\
+	CHEIR_PERM_EXECUTE)
+
+#define	CHERI_PERM_USER							\
+	(CHERI_PERM_NON_EPHEMERAL | CHERI_PERM_SEAL |			\
+	CHERI_PERM_STORE_EPHEMERAL_CAPABILITY | CHERI_PERM_LOAD |	\
+	CHERI_PERM_STORE | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE_CAP |	\
+	CHEIR_PERM_EXECUTE)
 
 /*
  * Definition for kernel "privileged" capability able to name the entire
@@ -73,7 +77,7 @@
  *
  * XXXRW: Perhaps CHERI_UCAP_UNPRIV_LENGTH should actually just cover useg.
  */
-#define	CHERI_CAP_PRIV_UPERMS		CHERI_PERM_ALL
+#define	CHERI_CAP_PRIV_UPERMS		CHERI_PERM_PRIV
 #define	CHERI_CAP_PRIV_OTYPE		0x0
 #define	CHERI_CAP_PRIV_BASE		0x0
 #define	CHERI_CAP_PRIV_LENGTH		0xffffffffffffffff
@@ -82,7 +86,7 @@
  * Definition for userspace "unprivileged" capability able to name the user
  * portion of the address space.
  */
-#define	CHERI_CAP_USER_UPERMS		CHERI_PERM_ALL
+#define	CHERI_CAP_USER_UPERMS		CHERI_PERM_USER
 #define	CHERI_CAP_USER_OTYPE		0x0
 #define	CHERI_CAP_USER_BASE		MIPS_XUSEG_START
 #define	CHERI_CAP_USER_LENGTH		(MIPS_XUSEG_END - MIPS_XUSEG_START)
@@ -125,7 +129,7 @@
 #define	CHERI_CR_C22	22
 #define	CHERI_CR_C23	23
 #define	CHERI_CR_C24	24
-#define	CHERI_CR_UDC	25	/*   SC0: user data capability. */
+#define	CHERI_CR_UDC	25	/*   UDC: user data capability (saved C0). */
 #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. */
@@ -164,8 +168,7 @@
 #define	CHERI_CR_C22_OFF	22
 #define	CHERI_CR_C23_OFF	23
 #define	CHERI_CR_C24_OFF	24
-#define	CHERI_CR_UDC_OFF	25
-#define	CHERI_CR_TSC_OFF	26
-#define	CHERI_CR_PC_OFF		27
+#define	CHERI_CR_TSC_OFF	25
+#define	CHERI_CR_PCC_OFF	26
 
 #endif /* _MIPS_INCLUDE_CHERIREG_H_ */


More information about the p4-projects mailing list