svn commit: r338467 - in head/sys/riscv: include riscv

Ruslan Bukin br at FreeBSD.org
Wed Sep 5 11:35:00 UTC 2018


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 <br at bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br at 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 <br at bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br at 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 <br at bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br at 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 <br at bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br at 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 <br at bsdpad.com>
+ * Copyright (c) 2015-2018 Ruslan Bukin <br at 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;


More information about the svn-src-all mailing list