Date: Sat, 5 Oct 2013 18:40:25 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 971766 for review Message-ID: <201310051840.r95IePYU046295@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@971766?ac=10 Change 971766 by rwatson@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310051840.r95IePYU046295>