PERFORCE change 213130 for review
Robert Watson
rwatson at FreeBSD.org
Tue Jun 19 10:22:03 UTC 2012
http://p4web.freebsd.org/@@213130?ac=10
Change 213130 by rwatson at rwatson_svr_ctsrd_mipsbuild on 2012/06/19 10:20:58
Checkpoint CHERI CP2 userspace context management for
FreeBSD/CHERI:
1. Introduce two new header files, cp2asm.h and cp2reg.h,
appropriate for inclusion from both assembly and C files.
2. Centralise previously distributed definitions of
CHERI_EXCEPTION_ENTER() and CHERI_EXCEPTION_RETURN() in
cp2asm.h.
3. For now, maintain only a userspace cp2frame, not a kernel
one, so remove nascent kernel frame from struct pcb.
4. Add new SAVE_CP2_CONTEXT() and RESTORE_CP2_CONTEXT() routines
to save and restore userspace CP2 registers in the pcb.
5. Save and restore CP2 state for userspace-sourced system calls
and interrupts that fire during usersapce execution. Also
restore userspace CP2 state when returning from
fork_trampoline().
With this change, the skeleton is in place to support
capability-aware userspace programs. Refinement will
undoubtably be required, and the object capability invocation
exception handler is currently unimplemented in this cut.
Affected files ...
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#6 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#8 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2asm.h#1 add
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2reg.h#1 add
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#3 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#4 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#2 edit
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#5 edit
Differences ...
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#6 (text+ko) ====
@@ -465,7 +465,7 @@
{
struct cp2_frame *cfp;
- cfp = &td->td_pcb->pcb_ucp2frame;
+ cfp = &td->td_pcb->pcb_cp2frame;
cp2_capability_load(CHERI_CR_CT0, &cp2_user_template);
cp2_capability_store(CHERI_CR_CT0, &cfp->cf_c0);
cp2_capability_store(CHERI_CR_CT0, &cfp->cf_c1);
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.h#8 (text+ko) ====
@@ -33,55 +33,9 @@
#include <sys/systm.h> /* CTASSERT */
-/*
- * CHERI ISA-defined constants for capabilities.
- *
- * 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
-
-/*
- * 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)
+#include <mips/cheri/cp2reg.h>
/*
- * A blend of hardware and software allocation of capability registers.
- */
-#define CHERI_CR_C0 0 /* MIPS fetch/load/store capability. */
-#define CHERI_CR_CT0 10 /* CT0: temporary capability. */
-#define CHERI_CR_UDC 25 /* SC0: user data capability. */
-#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. */
-#define CHERI_CR_KCC 29 /* KCC: kernel code capability. */
-#define CHERI_CR_KDC 30 /* KDC: kernel data capability. */
-#define CHERI_CR_EPCC 31 /* EPCC: exception program counter cap. */
-
-/*
* Canonical C-language representation of a capability.
*/
#define CAPABILITY_SIZE 32
@@ -101,6 +55,8 @@
* Register frame to be preserved on context switching -- very similar to
* struct mips_frame. As with mips_frame, the order of save/restore is very
* important for both reasons of correctness and security.
+ *
+ * Must match the register offset definitions (CHERI_*_OFF) in cp2reg.h.
*/
struct cp2_frame {
/* c0 has special properties for MIPS load/store instructions. */
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#3 (text+ko) ====
@@ -55,12 +55,9 @@
{
struct trapframe pcb_regs; /* saved CPU and registers */
#ifdef CPU_CHERI
- struct cp2_frame pcb_ucp2frame;
+ struct cp2_frame pcb_cp2frame; /* Userspace capabilities. */
#endif
__register_t pcb_context[14]; /* kernel context for resume */
-#ifdef CPU_CHERI
- struct cp2_frame pcb_cp2frame;
-#endif
void *pcb_onfault; /* for copyin/copyout faults */
register_t pcb_tpc;
};
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#4 (text+ko) ====
@@ -62,6 +62,11 @@
#include <machine/cpuregs.h>
#include <machine/pte.h>
+#ifdef CPU_CHERI
+#include <mips/cheri/cp2asm.h>
+#include <mips/cheri/cp2reg.h>
+#endif
+
#include "opt_cputype.h"
#include "assym.s"
@@ -73,42 +78,8 @@
*/
#define INTRCNT_COUNT 128
-#ifdef CPU_CHERI
-/*
- * When entering an exception handler, conditionally save the default user
- * data capability. Then install the kernel's default data capability. The
- * caller provides a temporary register to use for the purposes of querying
- * CP0 SR to determine whether the target is userspace or the kernel.
- */
-#define CHERI_EXCEPTION_ENTER(reg) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- andi reg, reg, SR_KSU_USER; \
- beq reg, $0, 64f; \
- nop; \
- cmove $c25, $c0; \
-64: \
- cmove $c0, $c30;
/*
- * When returning from an exception, conditionally restore the default user
- * data capability. The caller provides a temporary register to use for the
- * purposes of querying CP0 SR to determine whether the target is userspace
- * or the kernel.
- */
-#define CHERI_EXCEPTION_RETURN(reg) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- andi reg, reg, SR_KSU_USER; \
- beq reg, $0, 65f; \
- nop; \
- cmove $c0, $c25; \
-65:
-#else
-#define CHERI_EXCEPTION_ENTER(reg)
-#define CHERI_EXCEPTION_RETURN(reg)
-#endif
-
-
-/*
*----------------------------------------------------------------------------
*
* MipsTLBMiss --
@@ -124,7 +95,9 @@
VECTOR(MipsTLBMiss, unknown)
.set push
.set noat
+#ifdef CPU_CHERI
CHERI_EXCEPTION_ENTER(k0)
+#endif
j MipsDoTLBMiss
MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address
.set pop
@@ -178,7 +151,9 @@
COP0_SYNC
tlbwr #1a: write to tlb
HAZARD_DELAY
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret #1f: retUrn from exception
1: j MipsTLBMissException #20: kernel exception
@@ -197,7 +172,9 @@
* Find out what mode we came from and jump to the proper handler.
*/
.set noat
+#ifdef CPU_CHERI
CHERI_EXCEPTION_ENTER(k0)
+#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
@@ -427,7 +404,9 @@
RESTORE_CPU # v0 contains the return address.
sync
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
.set at
END(MipsKernGenException)
@@ -504,6 +483,9 @@
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a2, BADVADDR, k1)
SAVE_U_PCB_REG(a3, PC, k1)
+#ifdef CPU_CHERI
+ SAVE_CP2_CONTEXT(t0, k1)
+#endif
REG_S a3, CALLFRAME_RA(sp) # for debugging
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
# Turn off fpu and enter kernel mode
@@ -553,6 +535,9 @@
or a1, a1, a0
SAVE_U_PCB_REG(a1, SR, k1)
+#ifdef CPU_CHERI
+ RESTORE_CP2_CONTEXT(t0, k1)
+#endif
RESTORE_U_PCB_REG(t0, MULLO, k1)
RESTORE_U_PCB_REG(t1, MULHI, k1)
mtlo t0
@@ -594,7 +579,9 @@
mtc0 k0, MIPS_COP_0_STATUS # still exception level
ITLBNOPFIX
sync
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
.set at
END(MipsUserGenException)
@@ -687,7 +674,9 @@
REG_L v0, CALLFRAME_RA + KERN_REG_SIZE(sp)
RESTORE_CPU # v0 contains the return address.
sync
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
.set at
END(MipsKernIntr)
@@ -764,6 +753,9 @@
SAVE_U_PCB_REG(a0, SR, k1)
SAVE_U_PCB_REG(a1, CAUSE, k1)
SAVE_U_PCB_REG(a3, PC, k1) # PC in a3, note used later!
+#ifdef CPU_CHERI
+ SAVE_CP2_CONTEXT(t0, k1)
+#endif
PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP
PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP
@@ -822,6 +814,9 @@
or a1, a1, a0
SAVE_U_PCB_REG(a1, SR, k1)
+#ifdef CPU_CHERI
+ RESTORE_CP2_CONTEXT(t0, k1)
+#endif
RESTORE_U_PCB_REG(s0, S0, k1)
RESTORE_U_PCB_REG(s1, S1, k1)
RESTORE_U_PCB_REG(s2, S2, k1)
@@ -863,7 +858,9 @@
mtc0 k0, MIPS_COP_0_STATUS # SR with EXL set.
ITLBNOPFIX
sync
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
.set at
END(MipsUserIntr)
@@ -959,13 +956,17 @@
bltz k0, tlb_insert_random
nop
tlbwi
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
ssnop
tlb_insert_random:
tlbwr
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
ssnop
@@ -1097,7 +1098,9 @@
COP0_SYNC
tlbwr # write to tlb
HAZARD_DELAY
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret # return from exception
.set at
END(MipsTLBMissException)
@@ -1250,7 +1253,9 @@
*/
.text
VECTOR(MipsCache, unknown)
+#ifdef CPU_CHERI
CHERI_EXCEPTION_ENTER(k0)
+#endif
PTR_LA k0, _C_LABEL(MipsCacheException)
li k1, MIPS_KSEG0_PHYS_MASK
and k0, k1
@@ -1283,7 +1288,9 @@
mtc0 k0, MIPS_COP_0_STATUS # restore status
COP0_SYNC
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
MSG("cache error @ EPC 0x%x CachErr 0x%x");
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#2 (text+ko) ====
@@ -78,6 +78,9 @@
ASSYM(TF_REG_SR, offsetof(struct trapframe, sr));
ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero));
+#ifdef CPU_CHERI
+ASSYM(U_PCB_CP2FRAME, offsetof(struct pcb, pcb_cp2frame.cf_c0));
+#endif
ASSYM(U_PCB_CONTEXT, offsetof(struct pcb, pcb_context));
ASSYM(U_PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
ASSYM(U_PCB_FPREGS, offsetof(struct pcb, pcb_regs.f0));
==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#5 (text+ko) ====
@@ -64,6 +64,11 @@
#include <machine/regnum.h>
#include <machine/pte.h>
+#ifdef CPU_CHERI
+#include <mips/cheri/cp2asm.h>
+#include <mips/cheri/cp2reg.h>
+#endif
+
#include "assym.s"
.set noreorder # Noreorder is default style!
@@ -92,40 +97,6 @@
#define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
REG_L reg, U_PCB_CONTEXT + (SZREG * offs) (base)
-#ifdef CPU_CHERI
-/*
- * When entering an exception handler, conditionally save the default user
- * data capability. Then install the kernel's default data capability. The
- * caller provides a temporary register to use for the purposes of querying
- * CP0 SR to determine whether the target is userspace or the kernel.
- */
-#define CHERI_EXCEPTION_ENTER(reg) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- andi reg, reg, SR_KSU_USER; \
- beq reg, $0, 64f; \
- nop; \
- cmove $c25, $c0; \
-64: \
- cmove $c0, $c30;
-
-/*
- * When returning from an exception, conditionally restore the default user
- * data capability. The caller provides a temporary register to use for the
- * purposes of querying CP0 SR to determine whether the target is userspace
- * or the kernel.
- */
-#define CHERI_EXCEPTION_RETURN(reg) \
- mfc0 reg, MIPS_COP_0_STATUS; \
- andi reg, reg, SR_KSU_USER; \
- beq reg, $0, 65f; \
- nop; \
- cmove $c0, $c25; \
-65:
-#else
-#define CHERI_EXCEPTION_ENTER(reg)
-#define CHERI_EXCEPTION_RETURN(reg)
-#endif
-
/*
* Setup for and return to user.
*/
@@ -150,6 +121,9 @@
GET_CPU_PCPU(k1)
PTR_L k1, PC_CURPCB(k1)
+#ifdef CPU_CHERI
+ RESTORE_CP2_CONTEXT(t0, k1)
+#endif
RESTORE_U_PCB_REG(t0, MULLO, k1)
RESTORE_U_PCB_REG(t1, MULHI, k1)
mtlo t0
@@ -195,7 +169,9 @@
mtc0 k0, MIPS_COP_0_STATUS # switch to user mode (when eret...)
HAZARD_DELAY
sync
+#ifdef CPU_CHERI
CHERI_EXCEPTION_RETURN(k0)
+#endif
eret
.set at
END(fork_trampoline)
More information about the p4-projects
mailing list