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)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to