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 <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * 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 <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
+#include <machine/riscvreg.h>
 #include <sys/errno.h>
 
 #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 <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * 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 <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * 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 <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -36,6 +36,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <machine/setjmp.h>
+#include <machine/riscvreg.h>
 
 #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 <b...@bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <b...@bsdpad.com>
  * 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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to