Branch cpuctl.
Add a flag to map sf buf readonly. Use it for sendfile.

diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index d2c13b8..9e8bbc6 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -806,6 +806,12 @@ sf_buf_alloc(struct vm_page *m, int flags)
 				nsfbufsused++;
 				nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
 			}
+			if ((flags & SFB_RONLY) == 0) {
+				ptep = vtopte(sf->kva);
+				opte = *ptep;
+				if ((opte & PG_RW) == 0)
+					*ptep |= PG_RW | PG_A;
+			}
 #ifdef SMP
 			goto shootdown;	
 #else
@@ -850,8 +856,9 @@ sf_buf_alloc(struct vm_page *m, int flags)
        PT_SET_MA(sf->kva, xpmap_ptom(VM_PAGE_TO_PHYS(m)) | pgeflag
 	   | PG_RW | PG_V | pmap_cache_bits(m->md.pat_mode, 0));
 #else
-	*ptep = VM_PAGE_TO_PHYS(m) | pgeflag | PG_RW | PG_V |
-	    pmap_cache_bits(m->md.pat_mode, 0);
+       *ptep = VM_PAGE_TO_PHYS(m) | pgeflag |
+	   ((flags & SFB_RONLY) ? 0 : PG_RW) | PG_V |
+	   pmap_cache_bits(m->md.pat_mode, 0);
 #endif
 
 	/*
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index a14be72..9009e32 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2132,7 +2132,8 @@ retry_space:
 			 * as necessary, but this wait can be interrupted.
 			 */
 			if ((sf = sf_buf_alloc(pg,
-			    (mnw ? SFB_NOWAIT : SFB_CATCH))) == NULL) {
+			    (mnw ? SFB_NOWAIT : SFB_CATCH) | SFB_RONLY))
+			    == NULL) {
 				mbstat.sf_allocfail++;
 				vm_page_lock_queues();
 				vm_page_unwire(pg, 0);
diff --git a/sys/sys/sf_buf.h b/sys/sys/sf_buf.h
index af42065..fcb31f8 100644
--- a/sys/sys/sf_buf.h
+++ b/sys/sys/sf_buf.h
@@ -41,6 +41,7 @@
 #define	SFB_CPUPRIVATE	2		/* Create a CPU private mapping. */
 #define	SFB_DEFAULT	0
 #define	SFB_NOWAIT	4		/* Return NULL if all bufs are used. */
+#define	SFB_RONLY	8		/* Map page read-only, if possible. */
 
 struct vm_page;