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>