PERFORCE change 971766 for review
Robert Watson
rwatson at FreeBSD.org
Sat Oct 5 18:40:28 UTC 2013
http://p4web.freebsd.org/@@971766?ac=10
Change 971766 by rwatson at rwatson_zenith_cl_cam_ac_uk on 2013/10/05 18:40:20
Continue implementation of software CCall/CReturn:
- Implement support for per-thread trusted stacks in the
CCall/CReturn exception handlers, with tests for
overflow/underflow.
- Use correct branch instructions when testing code and
data-capability seals, target PC.
We now get successfully into and out of sandboxes using
CCall/CReturn under CheriBSD, but there remains only limited
error handling.
Affected files ...
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/ccall.S#9 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri_stack.c#2 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#26 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#7 edit
Differences ...
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/ccall.S#9 (text+ko) ====
@@ -107,10 +107,6 @@
* XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc. We
* need a C error-handling path.
*
- * 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.
- *
* XXXRW: We'd like a CSetCause so that we can jump to the general CP2
* exception handler from here after setting its state appropriately.
*
@@ -129,11 +125,11 @@
/* Second, check for the sealed bit on both arguments. */
cgetunsealed k0, CHERI_REG_CCALLCODE
- beqz k0, CCall_c1_unsealed
+ bnez k0, CCall_c1_unsealed
nop
cgetunsealed k0, CHERI_REG_CCALLDATA
- beqz k0, CCall_c2_unsealed
+ bnez k0, CCall_c2_unsealed
nop
/* Third, check for type equality. */
@@ -146,14 +142,14 @@
cgetperm k0, CHERI_REG_CCALLCODE
REG_LI k1, CHERI_PERM_SEAL | CHERI_PERM_EXECUTE
and k0, k0, k1
- beq k0, k1, CCall_c1_perms
+ bne k0, k1, CCall_c1_perms
nop
/* Fifth, check proposed PC is not lower than base. */
cgetbase k0, CHERI_REG_CCALLCODE
cgettype k1, CHERI_REG_CCALLCODE
sltu k1, k1, k0
- bne k1, zero, CCall_c1_range
+ bnez k1, CCall_c1_range
nop
/*
@@ -170,22 +166,43 @@
PTR_SUBIU k0, 4
cgettype k1, CHERI_REG_CCALLCODE
sltu k1, k1, k0
- bne k1, zero, CCall_c1_range
+ bnez k1, CCall_c1_range
+ nop
+
+ /*
+ * Now prepare to push IDC, PCC, PC+4 onto the trusted stack. Begin
+ * by retrieving the current PCB pointer to reach the trusted stack.
+ */
+ GET_CPU_PCPU(k1)
+ PTR_L k1, PC_CURPCB(k1)
+
+ /* Retrieve current trusted stack pointer. */
+ PTR_L k0, U_PCB_CHERISTACK_SP(k1)
+
+ /* If at bottom (byte offset 0), then overflow. */
+ beqz k0, CCall_stack_overflow
nop
- /* XXXRW: Change to PCB reference in the future. */
- PTR_LA k1, cheri_tsc_hack
+ /* Decrement stack pointer. */
+ PTR_SUBIU k0, k0, CHERI_FRAME_SIZE
+
+ /* Write back stack pointer. */
+ PTR_S k0, U_PCB_CHERISTACK_SP(k1)
+
+ /* Convert stack-relative offset to global pointer. */
+ PTR_ADDU k0, k1, k0 /* Add PCB pointer. */
+ PTR_ADDIU k0, k0, U_PCB_CHERISTACK_FRAMES /* Add PCB offset. */
/* Push IDC. */
- csc CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC)
+ csc CHERI_REG_IDC, k0, CHERI_STACKFRAME_IDC(CHERI_REG_KDC)
/* Push PCC. */
- csc CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC)
+ csc CHERI_REG_EPCC, k0, CHERI_STACKFRAME_PCC(CHERI_REG_KDC)
- /* Push PC + 4 */
- MFC0 k0, MIPS_COP_0_EXC_PC
- PTR_ADDU k0, k0, 4
- csd k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC)
+ /* Push PC + 4; k1 is overwritten, so no longer PCB pointer. */
+ MFC0 k1, MIPS_COP_0_EXC_PC
+ PTR_ADDU k1, k1, 4
+ csd k1, k0, CHERI_STACKFRAME_PC(CHERI_REG_KDC)
/*
* Temporarily set KDC type to allow unsealing.
@@ -201,7 +218,7 @@
/* 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. */
+ /* Installe cs.otype. */
cgettype k0, CHERI_REG_CCALLCODE
cgetbase k1, CHERI_REG_CCALLCODE
dsub k0, k0, k1
@@ -226,6 +243,7 @@
CCall_c1_c2_type_mismatch:
CCall_c1_perms:
CCall_c1_range:
+CCall_stack_overflow:
/* XXXRW: For now, treat as a NOP. */
MFC0 k0, MIPS_COP_0_EXC_PC
PTR_ADDIU k0, 4
@@ -243,10 +261,6 @@
* XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc. We
* need a C error handling path.
*
- * 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.
- *
* XXXRW: We'd like a CSetCause so that we can jump to the general CP2
* exception handler from here after setting its state appropriately.
*
@@ -258,24 +272,46 @@
.set push
.set noat
- /* XXXRW: Change to PCB reference in the future. */
- PTR_LA k1, cheri_tsc_hack
+ /* Retrieve current PCB pointer. */
+ GET_CPU_PCPU(k1)
+ PTR_L k1, PC_CURPCB(k1)
+
+ /*
+ * The only currently defined check in CReturn is stack underflow;
+ * perform that check.
+ */
+ PTR_L k0, U_PCB_CHERISTACK_SP(k1)
+ sltiu k0, CHERI_STACK_SIZE
+ beqz k0, CReturn_stack_underflow
+ nop
+
+ /* Reload stack pointer. */
+ PTR_L k0, U_PCB_CHERISTACK_SP(k1)
+
+ /* Convert stack-relative offset to global pointer. */
+ PTR_ADDU k0, k1, k0 /* Add PCB pointer. */
+ PTR_ADDIU k0, k0, U_PCB_CHERISTACK_FRAMES /* Add PCB offset. */
/* Pop IDC. */
- clc CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC)
+ clc CHERI_REG_IDC, k0, CHERI_STACKFRAME_IDC(CHERI_REG_KDC)
/* Pop PCC. */
- clc CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC)
+ clc CHERI_REG_EPCC, k0, CHERI_STACKFRAME_PCC(CHERI_REG_KDC)
- /* Pop PC + padding; +4 increment already done. */
- cld k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC)
+ /* Pop PC + padding; +4 already done; toasts k0; k1 still PCB. */
+ cld k0, k0, CHERI_STACKFRAME_PC(CHERI_REG_KDC)
MTC0 k0, MIPS_COP_0_EXC_PC
COP0_SYNC
+ /* Update stack pointer. */
+ PTR_L k0, U_PCB_CHERISTACK_SP(k1)
+ PTR_ADDIU k0, CHERI_FRAME_SIZE
+ PTR_S k0, U_PCB_CHERISTACK_SP(k1)
+
CHERI_EXCEPTION_RETURN(k0)
eret
-CReturn_error:
+CReturn_stack_underflow:
/* XXXRW: For now, treat as a NOP. */
MFC0 k0, MIPS_COP_0_EXC_PC
PTR_ADDIU k0, 4
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri_stack.c#2 (text+ko) ====
@@ -82,7 +82,7 @@
{
bzero(&pcb->pcb_cheristack, sizeof(pcb->pcb_cheristack));
- pcb->pcb_cheristack.cs_max = CHERI_STACK_DEPTH;
+ pcb->pcb_cheristack.cs_sp = CHERI_STACK_SIZE;
}
/*
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#26 (text+ko) ====
@@ -120,13 +120,16 @@
#define CHERI_STACK_DEPTH 2 /* XXXRW: 2 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_sp; /* Byte offset, not frame index. */
register_t _cs_pad0;
register_t _cs_pad1;
register_t _cs_pad2;
+ register_t _cs_pad3;
struct cheri_stack_frame cs_frames[CHERI_STACK_DEPTH];
} __aligned(CHERICAP_SIZE);
+
+#define CHERI_FRAME_SIZE sizeof(struct cheri_stack_frame)
+#define CHERI_STACK_SIZE (CHERI_STACK_DEPTH * CHERI_FRAME_SIZE)
#endif
/*
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#7 (text+ko) ====
@@ -106,10 +106,14 @@
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));
+ASSYM(CHERI_FRAME_SIZE, sizeof(struct cheri_stack_frame) * CHERI_STACK_DEPTH);
+ASSYM(CHERI_STACK_SIZE, sizeof(struct cheri_stack_frame));
+ASSYM(U_PCB_CHERIFRAME, offsetof(struct pcb, pcb_cheriframe));
+ASSYM(U_PCB_CHERISTACK_SP, offsetof(struct pcb, pcb_cheristack.cs_sp));
+ASSYM(U_PCB_CHERISTACK_FRAMES, offsetof(struct pcb, pcb_cheristack.cs_frames));
+ASSYM(CHERI_STACKFRAME_PC, offsetof(struct cheri_stack_frame, csf_pc));
+ASSYM(CHERI_STACKFRAME_PCC, offsetof(struct cheri_stack_frame, csf_pcc));
+ASSYM(CHERI_STACKFRAME_IDC, offsetof(struct cheri_stack_frame, csf_idc));
#endif
#ifdef CPU_CNMIPS
More information about the p4-projects
mailing list