Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2009 09:16:57 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r191810 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb vm
Message-ID:  <200905050916.n459GvbI072939@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue May  5 09:16:57 2009
New Revision: 191810
URL: http://svn.freebsd.org/changeset/base/191810

Log:
  MFC r190886:
  When vm_map_wire(9) is allowed to skip holes in the wired region, skip
  the mappings without any of read and execution rights, in particular,
  the PROT_NONE entries. This makes mlockall(2) work for the process
  address space that has such mappings.
  
  Since protection mode of the entry may change between setting
  MAP_ENTRY_IN_TRANSITION and final pass over the region that records
  the wire status of the entries, allocate new map entry flag
  MAP_ENTRY_WIRE_SKIPPED to mark the skipped PROT_NONE entries.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/vm/vm_map.c
  stable/7/sys/vm/vm_map.h

Modified: stable/7/sys/vm/vm_map.c
==============================================================================
--- stable/7/sys/vm/vm_map.c	Tue May  5 09:08:37 2009	(r191809)
+++ stable/7/sys/vm/vm_map.c	Tue May  5 09:16:57 2009	(r191810)
@@ -2059,6 +2059,16 @@ vm_map_wire(vm_map_t map, vm_offset_t st
 		 *
 		 */
 		if (entry->wired_count == 0) {
+			if ((entry->protection & (VM_PROT_READ|VM_PROT_EXECUTE))
+			    == 0) {
+				if ((flags & VM_MAP_WIRE_HOLESOK) == 0) {
+					end = entry->end;
+					rv = KERN_INVALID_ADDRESS;
+					goto done;
+				}
+				entry->eflags |= MAP_ENTRY_WIRE_SKIPPED;
+				goto next_entry;
+			}
 			entry->wired_count++;
 			saved_start = entry->start;
 			saved_end = entry->end;
@@ -2116,6 +2126,7 @@ vm_map_wire(vm_map_t map, vm_offset_t st
 		 * Check the map for holes in the specified region.
 		 * If VM_MAP_WIRE_HOLESOK was specified, skip this check.
 		 */
+	next_entry:
 		if (((flags & VM_MAP_WIRE_HOLESOK) == 0) &&
 		    (entry->end < end && (entry->next == &map->header ||
 		    entry->next->start > entry->end))) {
@@ -2137,6 +2148,8 @@ done:
 	}
 	entry = first_entry;
 	while (entry != &map->header && entry->start < end) {
+		if ((entry->eflags & MAP_ENTRY_WIRE_SKIPPED) != 0)
+			goto next_entry_done;
 		if (rv == KERN_SUCCESS) {
 			if (user_wire)
 				entry->eflags |= MAP_ENTRY_USER_WIRED;
@@ -2159,9 +2172,10 @@ done:
 				    entry->object.vm_object->type == OBJT_DEVICE);
 			}
 		}
+	next_entry_done:
 		KASSERT(entry->eflags & MAP_ENTRY_IN_TRANSITION,
 			("vm_map_wire: in-transition flag missing"));
-		entry->eflags &= ~MAP_ENTRY_IN_TRANSITION;
+		entry->eflags &= ~(MAP_ENTRY_IN_TRANSITION|MAP_ENTRY_WIRE_SKIPPED);
 		if (entry->eflags & MAP_ENTRY_NEEDS_WAKEUP) {
 			entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP;
 			need_wakeup = TRUE;

Modified: stable/7/sys/vm/vm_map.h
==============================================================================
--- stable/7/sys/vm/vm_map.h	Tue May  5 09:08:37 2009	(r191809)
+++ stable/7/sys/vm/vm_map.h	Tue May  5 09:16:57 2009	(r191810)
@@ -138,6 +138,8 @@ struct vm_map_entry {
 #define	MAP_ENTRY_GROWS_DOWN		0x1000	/* Top-down stacks */
 #define	MAP_ENTRY_GROWS_UP		0x2000	/* Bottom-up stacks */
 
+#define	MAP_ENTRY_WIRE_SKIPPED		0x4000
+
 #ifdef	_KERNEL
 static __inline u_char
 vm_map_entry_behavior(vm_map_entry_t entry)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905050916.n459GvbI072939>