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