From owner-p4-projects@FreeBSD.ORG Mon Oct 22 18:42:22 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 00B6DD03; Mon, 22 Oct 2012 18:42:22 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B3C6ED01 for ; Mon, 22 Oct 2012 18:42:21 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 96EB58FC08 for ; Mon, 22 Oct 2012 18:42:21 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q9MIgLdd022811 for ; Mon, 22 Oct 2012 18:42:21 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q9MIgLXN022808 for perforce@freebsd.org; Mon, 22 Oct 2012 18:42:21 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Mon, 22 Oct 2012 18:42:21 GMT Message-Id: <201210221842.q9MIgLXN022808@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 218920 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: Mon, 22 Oct 2012 18:42:22 -0000 http://p4web.freebsd.org/@@218920?ac=10 Change 218920 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/10/22 18:41:28 Update CheriBSD C code for CHERI ISAv2 updates -- no more hardware-defined TSC (for now), and the need to represent null capabilities explicitly is removed (we'll just use a capability register without the tag set). We end up disabling interrupts while constructing temporary capability values in exception reserved registers to prevent preemption, but will want instead to save and restore capabilities for preempted contexts so that the kernel can make use of capability registers more freely in the future. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#15 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#6 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/cheri/cp2.c#15 (text+ko) ==== @@ -67,16 +67,37 @@ */ void -cp2_capability_set(struct chericap *cp, uint32_t uperms, +cp2_capability_set(struct chericap *cp, uint32_t perms, void *otypep /* eaddr */, void *basep, uint64_t length) { + register_t s; - CP2_CR_MOVE(CHERI_CR_CT0, CHERI_CR_KDC); - CP2_CR_SET_OTYPE(CHERI_CR_CT0, CHERI_CR_CT0, (uint64_t)otypep); - CP2_CR_INC_BASE(CHERI_CR_CT0, CHERI_CR_CT0, (uint64_t)basep); - CP2_CR_SET_LENGTH(CHERI_CR_CT0, CHERI_CR_CT0, length); - CP2_CR_AND_UPERMS(CHERI_CR_CT0, CHERI_CR_CT0, uperms); - CP2_CR_STORE(CHERI_CR_CT0, CHERI_CR_KDC, (uint64_t)cp); + /* + * XXXRW: For now, we're using an exception handling temporary + * register to construct capabilities to store. Disable interrupts so + * that this is safe. In the future, we'd like to use a general + * temporary preserved during kernel execution to avoid this. + */ + s = intr_disable(); + CHERI_CSETTYPE(CHERI_CR_KR1C, CHERI_CR_KDC, (register_t)otypep); + CHERI_CINCBASE(CHERI_CR_KR1C, CHERI_CR_KR1C, (register_t)basep); + CHERI_CSETLEN(CHERI_CR_KR1C, CHERI_CR_KR1C, (register_t)length); + CHERI_CANDPERM(CHERI_CR_KR1C, CHERI_CR_KR1C, (register_t)perms); + CHERI_CSC(CHERI_CR_KR1C, CHERI_CR_KDC, (register_t)cp, 0); + intr_restore(s); +} + +static void +cp2_capability_clear(struct chericap *cp) +{ + + /* + * While we could construct a non-capability and write it out, simply + * bzero'ing memory is sufficient to clear the tag bit, and easier to + * spell. + */ + bzero(cp, sizeof(*cp)); + } /* @@ -89,7 +110,7 @@ cp2_capability_set_priv(struct chericap *cp) { - cp2_capability_set(cp, CHERI_CAP_PRIV_UPERMS, CHERI_CAP_PRIV_OTYPE, + cp2_capability_set(cp, CHERI_CAP_PRIV_PERMS, CHERI_CAP_PRIV_OTYPE, CHERI_CAP_PRIV_BASE, CHERI_CAP_PRIV_LENGTH); } @@ -97,7 +118,7 @@ cp2_capability_set_user(struct chericap *cp) { - cp2_capability_set(cp, CHERI_CAP_USER_UPERMS, CHERI_CAP_USER_OTYPE, + cp2_capability_set(cp, CHERI_CAP_USER_PERMS, CHERI_CAP_USER_OTYPE, CHERI_CAP_USER_BASE, CHERI_CAP_USER_LENGTH); } @@ -105,9 +126,7 @@ cp2_capability_set_null(struct chericap *cp) { - cp2_capability_set(cp, CHERI_CAP_NOPRIV_UPERMS, - CHERI_CAP_NOPRIV_OTYPE, CHERI_CAP_NOPRIV_BASE, - CHERI_CAP_NOPRIV_LENGTH); + cp2_capability_clear(cp); } /* @@ -123,9 +142,18 @@ void cp2_capability_copy(struct chericap *cp_to, struct chericap *cp_from) { + register_t s; - cp2_capability_load(CHERI_CR_CT0, cp_from); - cp2_capability_store(CHERI_CR_CT0, cp_to); + /* + * XXXRW: For now, we're using an exception handling temporary + * register to construct capabilities to store. Disable interrupts so + * that this is safe. In the future, we'd like to use a general + * temporary preserved during kernel execution to avoid this. + */ + s = intr_disable(); + cp2_capability_load(CHERI_CR_KR1C, cp_from); + cp2_capability_store(CHERI_CR_KR1C, cp_to); + intr_restore(s); } void @@ -157,7 +185,11 @@ cp2_capability_copy(&cf_destp->cf_c22, &cf_srcp->cf_c22); cp2_capability_copy(&cf_destp->cf_c23, &cf_srcp->cf_c23); cp2_capability_copy(&cf_destp->cf_c24, &cf_srcp->cf_c24); - cp2_capability_copy(&cf_destp->cf_tsc, &cf_srcp->cf_tsc); + cp2_capability_copy(&cf_destp->cf_c26, &cf_srcp->cf_c26); + /* + * XXXRW: not in CHERI ISAv2: + * cp2_capability_copy(&cf_destp->cf_tsc, &cf_srcp->cf_tsc); + */ cp2_capability_copy(&cf_destp->cf_pcc, &cf_srcp->cf_pcc); } @@ -198,7 +230,11 @@ cp2_capability_set_null(&cfp->cf_c22); cp2_capability_set_null(&cfp->cf_c23); cp2_capability_set_null(&cfp->cf_c24); - cp2_capability_set_null(&cfp->cf_tsc); + cp2_capability_set_null(&cfp->cf_c26); + /* + * XXXRW: not in CHERI ISAv2: + * cp2_capability_set_null(&cfp->cf_tsc); + */ cp2_capability_set_user(&cfp->cf_pcc); } @@ -206,9 +242,9 @@ #define DB_CP2_REG_PRINT_NUM(crn, num) do { \ struct chericap c; \ \ - CP2_CR_GET((crn), c); \ - db_printf("C%u perms %04jx otype %016jx\n", num, \ - (uintmax_t)c.c_uperms, (uintmax_t)c.u.c_otype); \ + CHERI_GETCAPREG((crn), c); \ + db_printf("C%u u: %u perms %04jx otype %016jx\n", num, \ + c.c_unsealed, (uintmax_t)c.c_perms, (uintmax_t)c.c_otype); \ db_printf("\tbase %016jx length %016jx\n", (uintmax_t)c.c_base, \ (uintmax_t)c.c_length); \ } while (0) @@ -263,6 +299,7 @@ { struct thread *td; struct cp2_frame *cfp; + register_t s; u_int i; if (have_addr) @@ -276,16 +313,22 @@ /* Laboriously load and print each capability. */ for (i = 0; i < 25; i++) { - cp2_capability_load(CHERI_CR_CT0, - (struct chericap *)&cfp->cf_c0 + i); - DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, i); + s = intr_disable(); + cp2_capability_load(CHERI_CR_KR1C, + (struct chericap *)&cfp->cf_c0 + i); + DB_CP2_REG_PRINT_NUM(CHERI_CR_KR1C, i); + intr_restore(s); } - db_printf("\nTSC and PCC:\n"); - cp2_capability_load(CHERI_CR_CT0, (struct chericap *)&cfp->cf_c0 + + db_printf("\nPCC:\n"); + s = intr_disable(); +#if 0 + cp2_capability_load(CHERI_CR_KR1C, (struct chericap *)&cfp->cf_c0 + CHERI_CR_TSC_OFF); - DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, CHERI_CR_TSC); - cp2_capability_load(CHERI_CR_CT0, (struct chericap *)&cfp->cf_c0 + + DB_CP2_REG_PRINT_NUM(CHERI_CR_KR1C, CHERI_CR_TSC); +#endif + cp2_capability_load(CHERI_CR_KR1C, (struct chericap *)&cfp->cf_c0 + CHERI_CR_PCC_OFF); - DB_CP2_REG_PRINT_NUM(CHERI_CR_CT0, CHERI_CR_EPCC); + DB_CP2_REG_PRINT_NUM(CHERI_CR_KR1C, CHERI_CR_EPCC); + intr_restore(s); } #endif ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/include/cherireg.h#6 (text+ko) ==== @@ -39,7 +39,7 @@ * but perhaps it should be. */ #define CHERI_PERM_NON_EPHEMERAL 0x0001 -#define CHEIR_PERM_EXECUTE 0x0002 +#define CHERI_PERM_EXECUTE 0x0002 #define CHERI_PERM_LOAD 0x0004 #define CHERI_PERM_STORE 0x0008 #define CHERI_PERM_LOAD_CAP 0x0010 @@ -73,7 +73,7 @@ * Definition for kernel "privileged" capability able to name the entire * address space. */ -#define CHERI_CAP_PRIV_UPERMS CHERI_PERM_PRIV +#define CHERI_CAP_PRIV_PERMS CHERI_PERM_PRIV #define CHERI_CAP_PRIV_OTYPE 0x0 #define CHERI_CAP_PRIV_BASE 0x0 #define CHERI_CAP_PRIV_LENGTH 0xffffffffffffffff @@ -82,7 +82,7 @@ * Definition for userspace "unprivileged" capability able to name the user * portion of the address space. */ -#define CHERI_CAP_USER_UPERMS CHERI_PERM_USER +#define CHERI_CAP_USER_PERMS CHERI_PERM_USER #define CHERI_CAP_USER_OTYPE 0x0 #define CHERI_CAP_USER_BASE MIPS_XUSEG_START #define CHERI_CAP_USER_LENGTH (MIPS_XUSEG_END - MIPS_XUSEG_START) @@ -94,7 +94,7 @@ * XXXRW: Probably no longer required in CHERI ISAv2 as we can clear * registers. */ -#define CHERI_CAP_NOPRIV_UPERMS 0x0 +#define CHERI_CAP_NOPRIV_PERMS 0x0 #define CHERI_CAP_NOPRIV_OTYPE 0x0 #define CHERI_CAP_NOPRIV_BASE 0x0 #define CHERI_CAP_NOPRIV_LENGTH 0x0