From owner-p4-projects@FreeBSD.ORG Wed May 23 14:19:17 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 20283106567A; Wed, 23 May 2012 14:19:17 +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 D682B1065676 for ; Wed, 23 May 2012 14:19:16 +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 BD5BA8FC16 for ; Wed, 23 May 2012 14:19:16 +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 q4NEJGmU042248 for ; Wed, 23 May 2012 14:19:16 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 q4NEJGf8042245 for perforce@freebsd.org; Wed, 23 May 2012 14:19:16 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Wed, 23 May 2012 14:19:16 GMT Message-Id: <201205231419.q4NEJGf8042245@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 To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 211581 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 May 2012 14:19:17 -0000 http://p4web.freebsd.org/@@211581?ac=10 Change 211581 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/05/23 14:18:42 Continue to refine use of the capability coprocessor in MIPS exception handlers, providing two common chunks of assembly, CHERI_EXCEPTION_ENTER and CHERI_EXCEPTION_RETURN, that know how to check whether the source of an exception, or the context it will eret to, is kernel or userspace for the purposes of reconfiguring C0 at the beginning or end of the exception handler. Use the new UDC register for this purpose. Affected files ... .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#3 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#5 edit .. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#4 edit Differences ... ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/exception.S#3 (text+ko) ==== @@ -73,7 +73,41 @@ */ #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 + /* *---------------------------------------------------------------------------- * @@ -90,10 +124,7 @@ 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 + CHERI_EXCEPTION_ENTER(k0) j MipsDoTLBMiss MFC0 k0, MIPS_COP_0_BAD_VADDR # get the fault address .set pop @@ -147,10 +178,9 @@ COP0_SYNC tlbwr #1a: write to tlb HAZARD_DELAY -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret #1f: retUrn from exception + 1: j MipsTLBMissException #20: kernel exception nop #21: branch delay slot 2: j SlowFault #22: no page table present @@ -167,10 +197,7 @@ * 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 + CHERI_EXCEPTION_ENTER(k0) 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 @@ -399,9 +426,8 @@ SAVE_REG(a1, SR, sp) RESTORE_CPU # v0 contains the return address. sync -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + + CHERI_EXCEPTION_RETURN(k0) eret .set at END(MipsKernGenException) @@ -568,9 +594,7 @@ mtc0 k0, MIPS_COP_0_STATUS # still exception level ITLBNOPFIX sync -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret .set at END(MipsUserGenException) @@ -663,9 +687,7 @@ 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 + CHERI_EXCEPTION_RETURN(k0) eret .set at END(MipsKernIntr) @@ -841,9 +863,7 @@ mtc0 k0, MIPS_COP_0_STATUS # SR with EXL set. ITLBNOPFIX sync -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret .set at END(MipsUserIntr) @@ -939,17 +959,13 @@ bltz k0, tlb_insert_random nop tlbwi -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret ssnop tlb_insert_random: tlbwr -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret ssnop @@ -1081,9 +1097,7 @@ COP0_SYNC tlbwr # write to tlb HAZARD_DELAY -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret # return from exception .set at END(MipsTLBMissException) @@ -1236,10 +1250,7 @@ */ .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 + CHERI_EXCEPTION_ENTER(k0) PTR_LA k0, _C_LABEL(MipsCacheException) li k1, MIPS_KSEG0_PHYS_MASK and k0, k1 @@ -1272,9 +1283,7 @@ mtc0 k0, MIPS_COP_0_STATUS # restore status COP0_SYNC -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret MSG("cache error @ EPC 0x%x CachErr 0x%x"); ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/locore.S#5 (text+ko) ==== @@ -145,9 +145,13 @@ #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. + * in exception handlers. + * + * XXXRW: Do we want to rely on default initialisation of all CP2 + * registers here? */ cmove $c30, $c0 # Preserve $kdc + cmove $c29, $c0 # Preserve $kcc /* * Initialise saved user $c0 so we can later restore it. @@ -155,7 +159,7 @@ * XXXRW: This will be removed once we more explicitly manage user * thread capabilities. */ - cmove $c27, $c0 # + cmove $c25, $c0 # Global $udc for now #endif /*xxximp ==== //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/swtch.S#4 (text+ko) ==== @@ -92,8 +92,41 @@ #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. */ LEAF(fork_trampoline) @@ -162,9 +195,7 @@ mtc0 k0, MIPS_COP_0_STATUS # switch to user mode (when eret...) HAZARD_DELAY sync -#ifdef CPU_CHERI - cmove $c0, $c27 # Restore user data segment -#endif + CHERI_EXCEPTION_RETURN(k0) eret .set at END(fork_trampoline)