Date: Sun, 20 May 2012 04:17:27 GMT From: Robert Watson <rwatson@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 211412 for review Message-ID: <201205200417.q4K4HRlb040901@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@211412?ac=10 Change 211412 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/05/20 04:16:38 Continue early proddings at FreeBSD/cheri support for CP2-enabled user processes: - Remove non-permitted anonymous union in cp2.h; OK in Deimos but not in FreeBSD. - Use FreeBSD-style packing and alignment directives, and employ CTASSERT to check struct capability size. - Add struct cp2_frame to the FreeBSD machine-dependent thread state structure. - During CPU initialisation, enable CP2 and save $c0 to $kdc for exception-time use. For now we will assume the entire kernel runs with all privilege at all times; something to revisit another day. - In all exception handlers, save the user $c0 in $c27 for the duration of the exception, then restore it just before eret. We will want to do something more mature and interesting in the future. - Tag a few places where we'll likely want to do more in the future, taking the Octeon crypto coprocessor support as examplar. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#3 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/proc.h#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/trap.c#2 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#2 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#2 (text+ko) ==== ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#3 (text+ko) ==== @@ -31,6 +31,8 @@ #ifndef _MIPS_CHERI_CP2_H_ #define _MIPS_CHERI_CP2_H_ +#include <sys/systm.h> /* CTASSERT */ + /* * CHERI ISA-defined constants for capabilities. * @@ -80,16 +82,18 @@ /* * Canonical C-language representation of a capability. */ +#define CAPABILITY_SIZE 32 struct capability { uint32_t c_uperms; uint32_t c_reserved; union { uint64_t c_otype; uint64_t c_eaddr; - }; + } u; uint64_t c_base; uint64_t c_length; -} __packed__ __aligned__(32); +} __packed __aligned(CAPABILITY_SIZE); +CTASSERT(sizeof(struct capability) == CAPABILITY_SIZE); /* * Register frame to be preserved on context switching -- very similar to @@ -267,7 +271,7 @@ #define CP2_CR_SET(crn_to, crn_from, c) do { \ /* XXXRW: How about the unsealed bit? */ \ - CP2_CR_SET_OTYPE((crn_to), (crn_from), (c).c_otype); \ + CP2_CR_SET_OTYPE((crn_to), (crn_from), (c).u.c_otype); \ CP2_CR_INC_BASE((crn_to), (crn_from), (c).c_base); \ CP2_CR_SET_LENGTH((crn_to), (crn_from), (c).c_length); \ CP2_CR_AND_UPERMS((crn_to), (crn_from), (c).c_uperms); \ ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/proc.h#2 (text+ko) ==== @@ -39,6 +39,9 @@ #ifndef _MACHINE_PROC_H_ #define _MACHINE_PROC_H_ +#ifdef CPU_CHERI +#include <mips/cheri/cp2.h> +#endif #ifdef CPU_CNMIPS #include <machine/octeon_cop2.h> #endif @@ -62,6 +65,9 @@ int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ void *md_tls; +#if defined(CPU_CHERI) + struct cp2_frame md_cp2frame; +#endif #ifdef CPU_CNMIPS struct octeon_cop2_state *md_cop2; /* kernel context */ struct octeon_cop2_state *md_ucop2; /* userland context */ ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#2 (text+ko) ==== @@ -90,6 +90,10 @@ VECTOR(MipsTLBMiss, unknown) .set push .set noat +#ifdef CPU_CHERI + cmove $c27, $c0 # Preserve user data segment in $kt1 + cmove $c0, $c30 # Restore kernel data segment from $kdc +#endif j MipsDoTLBMiss MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address .set pop @@ -143,6 +147,9 @@ COP0_SYNC tlbwr #1a: write to tlb HAZARD_DELAY +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret #1f: retUrn from exception 1: j MipsTLBMissException #20: kernel exception nop #21: branch delay slot @@ -160,6 +167,10 @@ * Find out what mode we came from and jump to the proper handler. */ .set noat +#ifdef CPU_CHERI + cmove $c27, $c0 # Preserve user data segment in $kt1 + cmove $c0, $c30 # Restore kernel data segment from $kdc +#endif mfc0 k0, MIPS_COP_0_STATUS # Get the status register mfc0 k1, MIPS_COP_0_CAUSE # Get the cause register value. and k0, k0, SR_KSU_USER # test for user mode @@ -388,6 +399,9 @@ SAVE_REG(a1, SR, sp) RESTORE_CPU # v0 contains the return address. sync +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret .set at END(MipsKernGenException) @@ -554,6 +568,9 @@ mtc0 k0, MIPS_COP_0_STATUS # still exception level ITLBNOPFIX sync +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret .set at END(MipsUserGenException) @@ -646,6 +663,9 @@ REG_L v0, CALLFRAME_RA + KERN_REG_SIZE(sp) RESTORE_CPU # v0 contains the return address. sync +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret .set at END(MipsKernIntr) @@ -821,6 +841,9 @@ mtc0 k0, MIPS_COP_0_STATUS # SR with EXL set. ITLBNOPFIX sync +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret .set at END(MipsUserIntr) @@ -916,11 +939,17 @@ bltz k0, tlb_insert_random nop tlbwi +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret ssnop tlb_insert_random: tlbwr +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret ssnop @@ -1052,6 +1081,9 @@ COP0_SYNC tlbwr # write to tlb HAZARD_DELAY +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret # return from exception .set at END(MipsTLBMissException) @@ -1204,6 +1236,10 @@ */ .text VECTOR(MipsCache, unknown) +#ifdef CPU_CHERI + cmove $c27, $c0 # Preserve user data segment in $kt1 + cmove $c0, $c30 # Restore kernel data segment from $kdc +#endif PTR_LA k0, _C_LABEL(MipsCacheException) li k1, MIPS_KSEG0_PHYS_MASK and k0, k1 @@ -1236,6 +1272,9 @@ mtc0 k0, MIPS_COP_0_STATUS # restore status COP0_SYNC +#ifdef CPU_CHERI + cmove $c0, $c27 # Restore user data segment +#endif eret MSG("cache error @ EPC 0x%x CachErr 0x%x"); ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#2 (text+ko) ==== @@ -116,11 +116,24 @@ * t1: Bits to set explicitly: * Enable FPU */ +#if defined(CPU_CHERI) + li t1, MIPS_SR_COP_1_BIT | MIPS_SR_COP_2_BIT +#else li t1, MIPS_SR_COP_1_BIT +#endif #ifdef __mips_n64 or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX #endif #endif + +#if defined(CPU_CHERI) + /* + * On CHERI MIPS, preserve the kernel's data segment context for use + * in exception handlers. $kcc will be preserved by the first eret. + */ + cmove $c30, $c0 # Preserve $kdc +#endif + /* * Read coprocessor 0 status register, clear bits not * preserved (namely, clearing interrupt bits), and set ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#2 (text+ko) ==== @@ -251,6 +251,10 @@ getpc: SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0) # save return address +#ifdef CPU_CHERI + /* XXXRW: CP2 state management here. */ +#endif + #ifdef CPU_CNMIPS lw t2, TD_MDFLAGS(a3) # get md_flags ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/trap.c#2 (text+ko) ==== @@ -831,6 +831,9 @@ goto err; break; case T_COP_UNUSABLE: +#ifdef CPU_CHERI + /* XXXRW: CP2 state management here. */ +#endif #ifdef CPU_CNMIPS cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT; /* Handle only COP2 exception */ @@ -885,6 +888,9 @@ goto out; #endif } +#ifdef CPU_CHERI + /* XXXRW: CP2 state management here. */ +#endif #ifdef CPU_CNMIPS else if (cop == 2) { addr = trapframe->pc; ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#2 (text+ko) ==== @@ -164,6 +164,9 @@ td2->td_md.md_tls = td1->td_md.md_tls; td2->td_md.md_saved_intr = MIPS_SR_INT_IE; td2->td_md.md_spinlock_count = 1; +#ifdef CPU_CHERI + /* XXXRW: CP2 state management here. */ +#endif #ifdef CPU_CNMIPS if (td1->td_md.md_flags & MDTD_COP2USED) { if (td1->td_md.md_cop2owner == COP2_OWNER_USERLAND) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205200417.q4K4HRlb040901>