shithub: riscv

Download patch

ref: 77ddc8c654824962149160af822f849b78cc6cc0
parent: 11fcf41472411fc0b683cc4431c42301e06124fe
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 12 17:42:26 EDT 2020

kernel: make segments non-executable when icache is not maintained

This change makes it mandatory for programs to call segflush() on
code that is not in the text segment if they want to execute it.

As a side effect, this means that everything but the text segment
will be non-executable by default, even without the SG_NOEXEC
attribute. Segments with the SG_NOEXEC attribute never become
executable, even when segflush() is called on them.

--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -221,7 +221,7 @@
 	}
 
 #ifdef PTENOEXEC
-	if((s->type & SG_NOEXEC) != 0)
+	if((s->type & SG_NOEXEC) != 0 || s->flushme == 0)
 		mmuphys |= PTENOEXEC;
 #endif
 
@@ -242,6 +242,8 @@
 	pg.ref = 1;
 	pg.va = addr;
 	pg.pa = s->pseg->pa+(addr-s->base);
+	if(s->flushme)
+		pg.txtflush = ~0;
 
 	mmuphys = PPN(pg.pa) | PTEVALID;
 	if((attr & SG_RONLY) == 0)
@@ -250,7 +252,7 @@
 		mmuphys |= PTERONLY;
 
 #ifdef PTENOEXEC
-	if((attr & SG_NOEXEC) != 0)
+	if((attr & SG_NOEXEC) != 0 || s->flushme == 0)
 		mmuphys |= PTENOEXEC;
 #endif
 
@@ -303,7 +305,7 @@
 			attr |= s->pseg->attr;
 
 		if((attr & SG_FAULT) != 0
-		|| read? (attr & SG_NOEXEC) != 0 && (addr & -BY2PG) == (pc & -BY2PG):
+		|| read? ((attr & SG_NOEXEC) != 0 || s->flushme == 0) && (addr & -BY2PG) == (pc & -BY2PG):
 			 (attr & SG_RONLY) != 0) {
 			qunlock(s);
 			up->psstate = sps;