From owner-svn-src-all@freebsd.org Wed Sep 5 11:35:00 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 88966FECB04; Wed, 5 Sep 2018 11:35:00 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 3F6B17CE63; Wed, 5 Sep 2018 11:35:00 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 35BA625522; Wed, 5 Sep 2018 11:35:00 +0000 (UTC) (envelope-from br@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w85BZ0gd076040; Wed, 5 Sep 2018 11:35:00 GMT (envelope-from br@FreeBSD.org) Received: (from br@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w85BYxgR076020; Wed, 5 Sep 2018 11:34:59 GMT (envelope-from br@FreeBSD.org) Message-Id: <201809051134.w85BYxgR076020@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: br set sender to br@FreeBSD.org using -f From: Ruslan Bukin Date: Wed, 5 Sep 2018 11:34:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r338467 - in head/sys/riscv: include riscv X-SVN-Group: head X-SVN-Commit-Author: br X-SVN-Commit-Paths: in head/sys/riscv: include riscv X-SVN-Commit-Revision: 338467 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Sep 2018 11:35:00 -0000 Author: br Date: Wed Sep 5 11:34:58 2018 New Revision: 338467 URL: https://svnweb.freebsd.org/changeset/base/338467 Log: Permit supervisor to access user VA space for certain functions only. This is done by setting SUM (permit Supervisor User Memory access) bit in sstatus register. The functions we allow access for are routines in assembly that explicitly handle crossing the user kernel boundary. Approved by: re (kib) Sponsored by: DARPA, AFRL Modified: head/sys/riscv/include/asm.h head/sys/riscv/riscv/copyinout.S head/sys/riscv/riscv/exception.S head/sys/riscv/riscv/locore.S head/sys/riscv/riscv/support.S head/sys/riscv/riscv/vm_machdep.c Modified: head/sys/riscv/include/asm.h ============================================================================== --- head/sys/riscv/include/asm.h Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/include/asm.h Wed Sep 5 11:34:58 2018 (r338467) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin + * Copyright (c) 2015-2018 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -62,5 +62,13 @@ ld tmp, PC_CURTHREAD(gp); \ ld tmp, TD_PCB(tmp); /* Load the pcb */ \ sd handler, PCB_ONFAULT(tmp) /* Set the handler */ + +#define ENTER_USER_ACCESS(tmp) \ + li tmp, SSTATUS_SUM; \ + csrs sstatus, tmp + +#define EXIT_USER_ACCESS(tmp) \ + li tmp, SSTATUS_SUM; \ + csrc sstatus, tmp #endif /* _MACHINE_ASM_H_ */ Modified: head/sys/riscv/riscv/copyinout.S ============================================================================== --- head/sys/riscv/riscv/copyinout.S Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/riscv/copyinout.S Wed Sep 5 11:34:58 2018 (r338467) @@ -35,6 +35,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include "assym.inc" @@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$"); */ ENTRY(copyio_fault) SET_FAULT_HANDLER(x0, a1) /* Clear the handler */ + EXIT_USER_ACCESS(a1) copyio_fault_nopcb: li a0, EFAULT ret @@ -62,6 +64,7 @@ ENTRY(copyout) la a6, copyio_fault /* Get the handler address */ SET_FAULT_HANDLER(a6, a7) /* Set the handler */ + ENTER_USER_ACCESS(a7) 1: lb a4, 0(a0) /* Load from kaddr */ addi a0, a0, 1 @@ -70,6 +73,7 @@ ENTRY(copyout) addi a2, a2, -1 /* len-- */ bnez a2, 1b + EXIT_USER_ACCESS(a7) SET_FAULT_HANDLER(x0, a7) /* Clear the handler */ 2: li a0, 0 /* return 0 */ @@ -89,6 +93,7 @@ ENTRY(copyin) la a6, copyio_fault /* Get the handler address */ SET_FAULT_HANDLER(a6, a7) /* Set the handler */ + ENTER_USER_ACCESS(a7) 1: lb a4, 0(a0) /* Load from uaddr */ addi a0, a0, 1 @@ -97,6 +102,7 @@ ENTRY(copyin) addi a2, a2, -1 /* len-- */ bnez a2, 1b + EXIT_USER_ACCESS(a7) SET_FAULT_HANDLER(x0, a7) /* Clear the handler */ 2: li a0, 0 /* return 0 */ @@ -114,6 +120,7 @@ ENTRY(copyinstr) la a6, copyio_fault /* Get the handler address */ SET_FAULT_HANDLER(a6, a7) /* Set the handler */ + ENTER_USER_ACCESS(a7) li a7, VM_MAXUSER_ADDRESS 1: bgt a0, a7, copyio_fault @@ -125,8 +132,9 @@ ENTRY(copyinstr) addi a2, a2, -1 /* len-- */ addi a5, a5, 1 /* count++ */ bnez a2, 1b - -2: SET_FAULT_HANDLER(x0, a7) /* Clear the handler */ + +2: EXIT_USER_ACCESS(a7) + SET_FAULT_HANDLER(x0, a7) /* Clear the handler */ 3: beqz a3, 4f /* Check if done != NULL */ addi a5, a5, 1 /* count++ */ Modified: head/sys/riscv/riscv/exception.S ============================================================================== --- head/sys/riscv/riscv/exception.S Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/riscv/exception.S Wed Sep 5 11:34:58 2018 (r338467) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015-2017 Ruslan Bukin + * Copyright (c) 2015-2018 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -116,11 +116,8 @@ __FBSDID("$FreeBSD$"); .macro load_registers el ld t0, (TF_SSTATUS)(sp) .if \el == 0 - /* - * Ensure user interrupts will be enabled on eret - * and supervisor mode can access userspace on trap. - */ - li t1, (SSTATUS_SPIE | SSTATUS_SUM) + /* Ensure user interrupts will be enabled on eret */ + li t1, SSTATUS_SPIE or t0, t0, t1 .else /* Modified: head/sys/riscv/riscv/locore.S ============================================================================== --- head/sys/riscv/riscv/locore.S Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/riscv/locore.S Wed Sep 5 11:34:58 2018 (r338467) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015-2017 Ruslan Bukin + * Copyright (c) 2015-2018 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -61,9 +61,6 @@ _start: sub s9, t2, t1 /* s9 = physmem base */ mv s10, a0 /* s10 = hart id */ mv s11, a1 /* s11 = dtbp */ - - li t0, SSTATUS_SUM - csrs sstatus, t0 /* Direct secondary cores to mpentry */ bnez s10, mpentry Modified: head/sys/riscv/riscv/support.S ============================================================================== --- head/sys/riscv/riscv/support.S Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/riscv/support.S Wed Sep 5 11:34:58 2018 (r338467) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin + * Copyright (c) 2015-2018 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include "assym.inc" @@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$"); */ ENTRY(fsu_fault) SET_FAULT_HANDLER(x0, a1) /* Reset the handler function */ + EXIT_USER_ACCESS(a1) fsu_fault_nopcb: li a0, -1 ret @@ -57,11 +59,13 @@ ENTRY(casueword32) bgt a0, a4, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a4) /* And set it */ + ENTER_USER_ACCESS(a4) 1: lr.w a4, 0(a0) /* Load-exclusive the data */ bne a4, a1, 2f /* If not equal then exit */ sc.w a5, a3, 0(a0) /* Store the new data */ bnez a5, 1b /* Retry on failure */ -2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */ +2: EXIT_USER_ACCESS(a5) + SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */ sw a4, 0(a2) /* Store the read data */ li a0, 0 /* Success */ ret /* Return */ @@ -75,11 +79,13 @@ ENTRY(casueword) bgt a0, a4, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a4) /* And set it */ + ENTER_USER_ACCESS(a4) 1: lr.d a4, 0(a0) /* Load-exclusive the data */ bne a4, a1, 2f /* If not equal then exit */ sc.d a5, a3, 0(a0) /* Store the new data */ bnez a5, 1b /* Retry on failure */ -2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */ +2: EXIT_USER_ACCESS(a5) + SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */ sd a4, 0(a2) /* Store the read data */ li a0, 0 /* Success */ ret /* Return */ @@ -93,7 +99,9 @@ ENTRY(fubyte) bgt a0, a1, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a1) /* And set it */ + ENTER_USER_ACCESS(a1) lb a0, 0(a0) /* Try loading the data */ + EXIT_USER_ACCESS(a1) SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */ ret /* Return */ END(fubyte) @@ -106,7 +114,9 @@ ENTRY(fuword16) bgt a0, a1, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a1) /* And set it */ + ENTER_USER_ACCESS(a1) lh a0, 0(a0) /* Try loading the data */ + EXIT_USER_ACCESS(a1) SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */ ret /* Return */ END(fuword16) @@ -119,7 +129,9 @@ ENTRY(fueword32) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) lw a0, 0(a0) /* Try loading the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ sw a0, 0(a1) /* Save the data in kernel space */ li a0, 0 /* Success */ @@ -136,7 +148,9 @@ EENTRY(fueword64) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) ld a0, 0(a0) /* Try loading the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ sd a0, 0(a1) /* Save the data in kernel space */ li a0, 0 /* Success */ @@ -152,7 +166,9 @@ ENTRY(subyte) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) sb a1, 0(a0) /* Try storing the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ li a0, 0 /* Success */ ret /* Return */ @@ -166,7 +182,9 @@ ENTRY(suword16) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) sh a1, 0(a0) /* Try storing the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ li a0, 0 /* Success */ ret /* Return */ @@ -180,7 +198,9 @@ ENTRY(suword32) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) sw a1, 0(a0) /* Try storing the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ li a0, 0 /* Success */ ret /* Return */ @@ -195,7 +215,9 @@ EENTRY(suword64) bgt a0, a2, fsu_fault_nopcb la a6, fsu_fault /* Load the fault handler */ SET_FAULT_HANDLER(a6, a2) /* And set it */ + ENTER_USER_ACCESS(a2) sd a1, 0(a0) /* Try storing the data */ + EXIT_USER_ACCESS(a2) SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */ li a0, 0 /* Success */ ret /* Return */ Modified: head/sys/riscv/riscv/vm_machdep.c ============================================================================== --- head/sys/riscv/riscv/vm_machdep.c Wed Sep 5 09:53:55 2018 (r338466) +++ head/sys/riscv/riscv/vm_machdep.c Wed Sep 5 11:34:58 2018 (r338467) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015-2017 Ruslan Bukin + * Copyright (c) 2015-2018 Ruslan Bukin * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -105,7 +105,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct t tf->tf_a[0] = 0; tf->tf_a[1] = 0; tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */ - tf->tf_sstatus |= (SSTATUS_SUM); /* Supervisor can access userspace. */ tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */ td2->td_frame = tf;