Date: Wed, 2 Oct 2013 21:20:54 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 935213 for review Message-ID: <201310022120.r92LKsur058015@skunkworks.freebsd.org>
index | next in thread | raw e-mail
http://p4web.freebsd.org/@@935213?ac=10 Change 935213 by rwatson@rwatson_zenith_cl_cam_ac_uk on 2013/10/02 21:20:34 Various steps on the path to a per-thread trusted stack: - Introduce cheri_memcpy(), a memory-copy utility function for the CheriBSD kernel, which is capable of preserving tag bits. This is not as good as a real tag-aware memcpy() as it only handles strong (32-byte) alignment, but useful for our purposes. Use this in copying CHER capability contexts rather than manual capability copies. - Add a new cheri_stack.c that implements two new functions: cheri_stack_init() and cheri_stack_copy() to be used in thread state reset (e.g., execve()) and thread fork. - For consistency with cheri_stack() routines, make cheri_context() routines accept pcb pointers rather than cheri_frame pointers. The now-initialised/maintained per-thread trusted stack is not yet used by CCall/CReturn, however. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/sys/mips/beri/files.beri#17 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri.c#17 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri_stack.c#1 add .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#25 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/pm_machdep.c#7 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#11 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/beri/files.beri#17 (text+ko) ==== @@ -26,7 +26,8 @@ mips/beri/beri_machdep.c standard mips/beri/beri_mp.c optional smp mips/beri/beri_pic.c optional fdt +mips/cheri/ccall.S optional cpu_cheri mips/cheri/cheri.c optional cpu_cheri -mips/cheri/ccall.S optional cpu_cheri +mips/cheri/cheri_stack.c optional cpu_cheri mips/mips/intr_machdep.c standard mips/mips/tick.c standard ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri.c#17 (text+ko) ==== @@ -80,6 +80,42 @@ struct cheri_stack_frame cheri_tsc_hack; /* + * Capability memcpy() routine -- not a general-purpose memcpy() as it has + * much stronger alignment and size requirements. + * + * XXXRW: Eventually, true memcpy() will support capabilities, and this will + * go away. We hope. + */ +void * +cheri_memcpy(void *dst, void *src, size_t len) +{ + register_t s; + u_int i; + + /* NB: Assumes CHERICAP_SIZE is a power of two. */ + KASSERT(((uintptr_t)dst & (CHERICAP_SIZE - 1)) == 0, + ("%s: unaligned dst", __func__)); + KASSERT(((uintptr_t)src & (CHERICAP_SIZE - 1)) == 0, + ("%s: unaligned src", __func__)); + KASSERT((len % CHERICAP_SIZE) == 0, + ("%s: copy size not a multiple of capability size", __func__)); + + /* + * XXXRW: Prevent preemption during memory copy, as we're using an + * exception handling temporary register. + */ + s = intr_disable(); + for (i = 0; i < (len / CHERICAP_SIZE); i++) { + cheri_capability_load(CHERI_CR_CTEMP, + (struct chericap *)src + i); + cheri_capability_store(CHERI_CR_CTEMP, + (struct chericap *)dst + i); + } + intr_restore(s); + return (dst); +} + +/* * Given an existing more privileged capability (fromcrn), build a new * capability in tocrn with the contents of the passed flattened * representation. @@ -182,38 +218,11 @@ } void -cheri_context_copy(struct cheri_frame *cf_destp, struct cheri_frame *cf_srcp) +cheri_context_copy(struct pcb *dst, struct pcb *src) { - /* XXXRW: Use a capability-aware memcpy here instead. */ - cheri_capability_copy(&cf_destp->cf_c0, &cf_srcp->cf_c0); - cheri_capability_copy(&cf_destp->cf_c1, &cf_srcp->cf_c1); - cheri_capability_copy(&cf_destp->cf_c2, &cf_srcp->cf_c2); - cheri_capability_copy(&cf_destp->cf_c3, &cf_srcp->cf_c3); - cheri_capability_copy(&cf_destp->cf_c4, &cf_srcp->cf_c4); - cheri_capability_copy(&cf_destp->cf_c5, &cf_srcp->cf_c5); - cheri_capability_copy(&cf_destp->cf_c6, &cf_srcp->cf_c6); - cheri_capability_copy(&cf_destp->cf_c7, &cf_srcp->cf_c7); - cheri_capability_copy(&cf_destp->cf_c8, &cf_srcp->cf_c8); - cheri_capability_copy(&cf_destp->cf_c9, &cf_srcp->cf_c9); - cheri_capability_copy(&cf_destp->cf_c10, &cf_srcp->cf_c10); - cheri_capability_copy(&cf_destp->cf_c11, &cf_srcp->cf_c11); - cheri_capability_copy(&cf_destp->cf_c12, &cf_srcp->cf_c12); - cheri_capability_copy(&cf_destp->cf_c13, &cf_srcp->cf_c13); - cheri_capability_copy(&cf_destp->cf_c14, &cf_srcp->cf_c14); - cheri_capability_copy(&cf_destp->cf_c15, &cf_srcp->cf_c15); - cheri_capability_copy(&cf_destp->cf_c16, &cf_srcp->cf_c16); - cheri_capability_copy(&cf_destp->cf_c17, &cf_srcp->cf_c17); - cheri_capability_copy(&cf_destp->cf_c18, &cf_srcp->cf_c18); - cheri_capability_copy(&cf_destp->cf_c19, &cf_srcp->cf_c19); - cheri_capability_copy(&cf_destp->cf_c20, &cf_srcp->cf_c20); - cheri_capability_copy(&cf_destp->cf_c21, &cf_srcp->cf_c21); - cheri_capability_copy(&cf_destp->cf_c22, &cf_srcp->cf_c22); - cheri_capability_copy(&cf_destp->cf_c23, &cf_srcp->cf_c23); - cheri_capability_copy(&cf_destp->cf_rcc, &cf_srcp->cf_rcc); - cheri_capability_copy(&cf_destp->cf_c25, &cf_srcp->cf_c25); - cheri_capability_copy(&cf_destp->cf_idc, &cf_srcp->cf_idc); - cheri_capability_copy(&cf_destp->cf_pcc, &cf_srcp->cf_pcc); + cheri_memcpy(&dst->pcb_cheriframe, &src->pcb_cheriframe, + sizeof(dst->pcb_cheriframe)); } void ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#25 (text+ko) ==== @@ -390,6 +390,7 @@ CHERI_CGETLEN((c).c_length, (crn)); \ } while (0) +#ifdef _KERNEL /* * APIs that act on C language representations of capabilities -- but not * capabilities themselves. @@ -402,16 +403,26 @@ void cheri_capability_set_user(struct chericap *cp); void cheri_capability_set_null(struct chericap *cp); -#ifdef _KERNEL +/* + * CHERI capability utility functions. + */ +void *cheri_memcpy(void *dst, void *src, size_t len); + /* - * Kernel-specific CHERI context management functions. + * CHERI context management functions. */ -void cheri_context_copy(struct cheri_frame *cf_destp, - struct cheri_frame *cf_srcp); void cheri_exec_setregs(struct thread *td); void cheri_log_exception(struct trapframe *frame, int trap_type); int cheri_syscall_authorize(struct thread *td, u_int code, int nargs, register_t *args); + +/* + * Functions to set up and manipulate CHERI contexts and stacks. + */ +struct pcb; +void cheri_context_copy(struct pcb *dst, struct pcb *src); +void cheri_stack_copy(struct pcb *dst, struct pcb *src); +void cheri_stack_init(struct pcb *pcb); #endif #endif /* _MIPS_INCLUDE_CHERI_H_ */ ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/pm_machdep.c#7 (text+ko) ==== @@ -497,6 +497,7 @@ #if defined(CPU_CHERI) td->td_frame->sr |= MIPS_SR_COP_2_BIT; cheri_exec_setregs(td); + cheri_stack_init(td->td_pcb); #endif /* * FREEBSD_DEVELOPERS_FIXME: ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#11 (text+ko) ==== @@ -149,10 +149,8 @@ * above, and once here using capabilities. Once bcopy() is * capability-oblivious, we can lose this. */ - cheri_context_copy(&pcb2->pcb_cheriframe, - &td1->td_pcb->pcb_cheriframe); - - /* XXXRW: Trusted stack initialisation here? */ + cheri_context_copy(pcb2, td1->td_pcb); + cheri_stack_copy(pcb2, td1->td_pcb); #endif /* Point mdproc and then copy over td1's contents @@ -432,10 +430,8 @@ * above, and once here using capabilities. Once bcopy() is * capability-oblivious, we can lose this. */ - cheri_context_copy(&pcb2->pcb_cheriframe, - &td0->td_pcb->pcb_cheriframe); - - /* XXXRW: Trusted stack initialisation here? */ + cheri_context_copy(pcb2, td0->td_pcb); + cheri_stack_copy(pcb2, td0->td_pcb); #endif /*help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310022120.r92LKsur058015>
