From owner-p4-projects@FreeBSD.ORG Sat Sep 28 18:03:32 2013 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 43F26C15; Sat, 28 Sep 2013 18:03:32 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 05CECC13 for ; Sat, 28 Sep 2013 18:03:32 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [8.8.178.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id E3A2B29E5 for ; Sat, 28 Sep 2013 18:03:31 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id r8SI3V4S080567 for ; Sat, 28 Sep 2013 18:03:31 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.6/Submit) id r8SI3VkA080558 for perforce@freebsd.org; Sat, 28 Sep 2013 18:03:31 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sat, 28 Sep 2013 18:03:31 GMT Message-Id: <201309281803.r8SI3VkA080558@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson Subject: PERFORCE change 882542 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.14 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Sep 2013 18:03:32 -0000 http://p4web.freebsd.org/@@882542?ac=10 Change 882542 by rwatson@rwatson_zenith_cl_cam_ac_uk on 2013/09/28 18:03:04 Various changes on the path to a (very experimental) software-path CCall/CReturn implementation: - Provide a temporary trusted stack implementation via a single global frame entry, but lay some of the groundwork for a trust per-thread trusted stack. - Pull more of the CCall implementation from test_cp2_ccall2.s: push the old IDC, PCC, and PC+4 to the temporary trusted stack. Unseal code and data capabilities into EPCC and IDC, and install the new PC. - Pull more of the CReturn implementation from test_cp2_ccall2.s: pop IDC, EPCC, and PC from the temporary trusted stack. Attempting to execute this path wedges the CPU, but it seems likely that even if it did not, this code would not [yet] work. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/ccall.S#6 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri.c#16 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#23 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheriasm.h#12 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#12 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#9 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#6 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#10 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/ccall.S#6 (text+ko) ==== @@ -1,6 +1,6 @@ /*- - * Copyright (c) 2013 Robert N. M. Watson - * Copyright (c) 2013 Michael Roe + * Copyright (c) 2012-2013 Robert N. M. Watson + * Copyright (c) 2012-2013 Michael Roe * All rights reserved. * * This software was developed by SRI International and the University of @@ -94,38 +94,101 @@ /* * Software implementation of CCall; this code does not need to be position- - * independent. + * independent as it is not relocated to an exception vector. + * + * XXXRW: This software implementation of CCall uses an alternative calling + * convention, in which the code capability to invoke is always placed in $c1, + * and the corresponding data capability is always placed in $c2. This + * prevents software from having to copy in the faulting ccall instruction, + * decoding it, and then switch()ing on the register numbers to use the right + * instruction to extract the capabilities to fixed ones targetable in + * assembly and by the compiler. + * + * XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc. We + * need a C error-handling path. * - * XXXRW: Gubbins missing. + * 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. */ CHERICCall: .set push .set noat - /* XXXRW: For now, increment PC as though it were a no-op. */ - MFC0 k0, MIPS_COP_0_EXC_PC - PTR_ADDU k0, 4 - MTC0 k0, MIPS_COP_0_EXC_PC + /* XXXRW: Change to PCB reference in the future. */ + PTR_LA k1, cheri_tsc_hack + + /* Push IDC. */ + csc CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC) + + /* Push PCC. */ + csc CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC) + + /* Push PC + 4 */ + MFC0 k0, MIPS_COP_0_EXC_PC + daddiu k0, 4 + csd k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC) + + /* + * Temporarily set KDC type to allow unsealing. + * + * XXXRW: This is inefficient and (should be) unnecessary. + */ + cgettype k0, CHERI_REG_CCALLCODE + csettype CHERI_REG_KDC, CHERI_REG_KDC, k0 + + /* Unseal cs; install in PCC. */ + cunseal CHERI_REG_EPCC, CHERI_REG_CCALLCODE, CHERI_REG_KDC + + /* 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. */ + cgettype k0, CHERI_REG_CCALLCODE + cgetbase k1, CHERI_REG_CCALLCODE + dsub k0, k0, k1 + MTC0 k0, MIPS_COP_0_EXC_PC COP0_SYNC + /* + * Restore KDC type. + * + * XXXRW: This should also be unnecessary. + */ + PTR_LI k0, 0 + csettype CHERI_REG_KDC, CHERI_REG_KDC, k0 + CHERI_EXCEPTION_RETURN(k0) eret .set pop /* * Software implementation of CReturn; this code does not need to be position- - * independent. + * independent as it is not relocated to an exception vector. + * + * XXXRW: Lots of non-done checking -- e.g., types, protection bits, etc. We + * need a C error handling path. * - * XXXRW: Gubbins missing. + * 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. */ CHERICReturn: .set push .set noat - /* XXXRW: For now, increment PC as though it were a no-op. */ - MFC0 k0, MIPS_COP_0_EXC_PC - PTR_ADDU k0, 4 - MTC0 k0, MIPS_COP_0_EXC_PC + /* XXXRW: Change to PCB reference in the future. */ + PTR_LA k1, cheri_tsc_hack + + /* Pop IDC. */ + clc CHERI_REG_IDC, k1, U_CHERI_STACK_IDC(CHERI_REG_KDC) + + /* Pop PCC. */ + csc CHERI_REG_EPCC, k1, U_CHERI_STACK_PCC(CHERI_REG_KDC) + + /* Pop PC + padding; +4 increment already done. */ + cld k0, k1, U_CHERI_STACK_PC(CHERI_REG_KDC) + MTC0 k0, MIPS_COP_0_EXC_PC COP0_SYNC CHERI_EXCEPTION_RETURN(k0) ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cheri.c#16 (text+ko) ==== @@ -73,6 +73,13 @@ "Run debugger on CHERI exception"); /* + * XXXRW: Temporary hack -- single global trusted stack used by any instance + * of CCall or CReturn in any thread of any process. This won't last long, + * but is enough to test things a little. + */ +struct cheri_stack_frame cheri_tsc_hack; + +/* * Given an existing more privileged capability (fromcrn), build a new * capability in tocrn with the contents of the passed flattened * representation. @@ -224,6 +231,8 @@ bzero(cfp, sizeof(*cfp)); cheri_capability_set_user(&cfp->cf_c0); cheri_capability_set_user(&cfp->cf_pcc); + + /* XXXRW: Trusted stack initialisation here? */ } #define CHERI_REG_PRINT(c, ctag, num) do { \ ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheri.h#23 (text+ko) ==== @@ -99,6 +99,34 @@ struct chericap cf_pcc; }; CTASSERT(sizeof(struct cheri_frame) == (28 * CHERICAP_SIZE)); + +/* + * Per-thread CHERI CCall/CReturn stack, which preserves the calling PC/PCC/ + * IDC across CCall so that CReturn can restore them. + * + * XXXRW: This is a very early experiment -- it's not clear if this idea will + * persist in its current form, or at all. For more complex userspace + * language, there's a reasonable expectation that it, rather than the kernel, + * will want to manage the idea of a "trusted stack". + */ +struct cheri_stack_frame { + register_t csf_pc; + register_t _csf_pad0; + register_t _csf_pad1; + register_t _csf_pad2; + struct chericap csf_pcc; + struct chericap csf_idc; +}; + +#define CHERI_STACK_DEPTH 10 /* XXXRW: 10 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_pad0; + register_t _cs_pad1; + register_t _cs_pad2; + struct cheri_stack_frame cs_frames[CHERI_STACK_DEPTH]; +} __aligned(CHERICAP_SIZE); #endif /* ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cheriasm.h#12 (text+ko) ==== @@ -87,6 +87,13 @@ #define CHERI_REG_SEC0 CHERI_REG_KR2C /* Saved $c0 in exception handling. */ /* + * (Possibly) temporary ABI in which $c1 is the code argument to CCall, and + * $c2 is the data argument. + */ +#define CHERI_REG_CCALLCODE $c1 +#define CHERI_REG_CCALLDATA $c2 + +/* * Assembly code to be used in CHERI exception handling and context switching. * * When entering an exception handler from userspace, conditionally save the ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#12 (text+ko) ==== ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/pcb.h#9 (text+ko) ==== @@ -73,7 +73,8 @@ { struct trapframe pcb_regs; /* saved CPU and registers */ #ifdef CPU_CHERI - struct cheri_frame pcb_cheriframe; /* Userspace capabilities. */ + struct cheri_frame pcb_cheriframe; /* Userspace capabilities. */ + struct cheri_stack pcb_cheristack; /* CCall/CReturn stack. */ #endif __register_t pcb_context[14]; /* kernel context for resume */ void *pcb_onfault; /* for copyin/copyout faults */ ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/genassym.c#6 (text+ko) ==== @@ -74,9 +74,6 @@ ASSYM(TD_MDFLAGS, offsetof(struct thread, td_md.md_flags)); ASSYM(U_PCB_REGS, offsetof(struct pcb, pcb_regs.zero)); -#ifdef CPU_CHERI -ASSYM(U_PCB_CHERIFRAME, offsetof(struct pcb, pcb_cheriframe.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)); @@ -108,6 +105,13 @@ ASSYM(MIPS_KSEG2_START, MIPS_KSEG2_START); 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)); +#endif + #ifdef CPU_CNMIPS ASSYM(TD_COP2OWNER, offsetof(struct thread, td_md.md_cop2owner)); ASSYM(TD_COP2, offsetof(struct thread, td_md.md_cop2)); ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/vm_machdep.c#10 (text+ko) ==== @@ -151,6 +151,8 @@ */ cheri_context_copy(&pcb2->pcb_cheriframe, &td1->td_pcb->pcb_cheriframe); + + /* XXXRW: Trusted stack initialisation here? */ #endif /* Point mdproc and then copy over td1's contents @@ -432,6 +434,8 @@ */ cheri_context_copy(&pcb2->pcb_cheriframe, &td0->td_pcb->pcb_cheriframe); + + /* XXXRW: Trusted stack initialisation here? */ #endif /*