valid VMA ranges and mincore()

Konstantin Belousov kostikbel at gmail.com
Wed Jun 14 13:56:14 UTC 2006


On Wed, Jun 14, 2006 at 02:04:08PM +0200, Bruno Haible wrote:
> Hello Konstantin,
> 
> Thanks for reacting on this issue.
> 
> > Please, evaluate the patch. If it does what you need
> 
> - It doesn't change the manual page mincore.2.
Yes, it was intended. Exactly because I anticipated issues
you described below.

> - For unmapped areas, it appears to be filling in values of -1 into
>   the array. This is not what Linux, Solaris, NetBSD do: They return
>   -1 from the system call and set errno to ENOMEM. See
>   Linux:    http://linux.about.com/library/cmd/blcmdl2_mincore.htm
>   Solaris:  http://docs.sun.com/app/docs/doc/816-5167/6mbb2jaib?a=view
>   NetBSD:   http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/sys/mincore.2?rev=1.19&content-type=text/plain
> - Filling in values of -1 into the array will confuse existing applications,
>   because -1 is all bits set, i.e. the nonexistent pages will appear to
>   be in-core, modified, referenced.
Ok. See below. I hope that I fixed my problems with comprehension.

> - Filling in values of -1 into the array could be done more easily by
>   changing the statements in sys/vm/vm_mmap.c lines 861 and 902.
I do not agree. It zeroes array not only for holes, but also for (some)
skipped vm areas. For instance, it happens for freshly allocated
anonymous memory that has not faulted any pages still.


Index: vm_mmap.c
===================================================================
RCS file: /usr/local/arch/ncvs/src/sys/vm/vm_mmap.c,v
retrieving revision 1.205
diff -u -r1.205 vm_mmap.c
--- vm_mmap.c	21 Apr 2006 07:17:25 -0000	1.205
+++ vm_mmap.c	14 Jun 2006 13:51:20 -0000
@@ -756,8 +756,10 @@
 	first_addr = addr = trunc_page((vm_offset_t) uap->addr);
 	end = addr + (vm_size_t)round_page(uap->len);
 	map = &td->td_proc->p_vmspace->vm_map;
-	if (end > vm_map_max(map) || end < addr)
+	if (end < addr)
 		return (EINVAL);
+	if (end > vm_map_max(map))
+		return (ENOMEM);
 
 	/*
 	 * Address of byte vector
@@ -770,8 +772,18 @@
 RestartScan:
 	timestamp = map->timestamp;
 
-	if (!vm_map_lookup_entry(map, addr, &entry))
-		entry = entry->next;
+	if (!vm_map_lookup_entry(map, first_addr, &entry)) {
+		vm_map_unlock_read(map);
+		return (ENOMEM);
+	}
+	for (current = entry;
+	    (current != &map->header) && (current->end < end);
+	    current = current->next) {
+		if (current->end != current->next->start) {
+			vm_map_unlock_read(map);
+			return (ENOMEM);
+		}
+	}
 
 	/*
 	 * Do this on a map entry basis so that if the pages are not
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20060614/bd80288e/attachment.pgp


More information about the freebsd-hackers mailing list