Module Name:    src
Committed By:   yamt
Date:           Sun Aug  2 16:03:47 UTC 2009

Modified Files:
        src/sys/uvm: uvm_mremap.c

Log Message:
- fix extend of unexistent mapping.  the problem reported by
  Nicolas Joly on current-us...@.
- check our reserved entry a little more strictly.
- comments.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/uvm/uvm_mremap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_mremap.c
diff -u src/sys/uvm/uvm_mremap.c:1.13 src/sys/uvm/uvm_mremap.c:1.14
--- src/sys/uvm/uvm_mremap.c:1.13	Mon Mar 23 02:12:54 2009
+++ src/sys/uvm/uvm_mremap.c	Sun Aug  2 16:03:47 2009
@@ -1,7 +1,7 @@
-/*	$NetBSD: uvm_mremap.c,v 1.13 2009/03/23 02:12:54 yamt Exp $	*/
+/*	$NetBSD: uvm_mremap.c,v 1.14 2009/08/02 16:03:47 yamt Exp $	*/
 
 /*-
- * Copyright (c)2006 YAMAMOTO Takashi,
+ * Copyright (c)2006,2007,2009 YAMAMOTO Takashi,
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_mremap.c,v 1.13 2009/03/23 02:12:54 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_mremap.c,v 1.14 2009/08/02 16:03:47 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/mman.h>
@@ -54,13 +54,13 @@
 	if (reserved_entry->start != endva ||
 	    reserved_entry->end != endva + size ||
 	    reserved_entry->object.uvm_obj != NULL ||
-	    reserved_entry->aref.ar_amap != NULL) {
+	    reserved_entry->aref.ar_amap != NULL ||
+	    reserved_entry->protection != VM_PROT_NONE) {
 		error = EINVAL;
 		goto done;
 	}
 	entry = reserved_entry->prev;
-	KASSERT(&map->header != entry);
-	if (entry->end != endva) {
+	if (&map->header == entry || entry->end != endva) {
 		error = EINVAL;
 		goto done;
 	}
@@ -209,7 +209,9 @@
 	    UVM_EXTRACT_RESERVED);
 	KASSERT(dstva == newva);
 	if (error != 0) {
-		/* undo uvm_map_reserve */
+		/*
+		 * undo uvm_map_reserve.
+		 */
 		uvm_unmap(newmap, newva, newva + newsize);
 		return error;
 	}
@@ -218,14 +220,22 @@
 		error = uvm_mapent_extend(newmap, newva + oldsize,
 		    newsize - oldsize);
 		if (error != 0) {
-			/* undo uvm_map_reserve and uvm_map_extract */
-			uvm_unmap(newmap, newva, newva + newsize);
+			/*
+			 * undo uvm_map_reserve and uvm_map_extract.
+			 */
+			if (newva == oldva && newmap == oldmap) {
+				uvm_unmap(newmap, newva + oldsize,
+				    newva + newsize);
+			} else {
+				uvm_unmap(newmap, newva, newva + newsize);
+			}
 			return error;
 		}
 	}
 
 	/*
-	 * now we won't fail.  remove original entries.
+	 * now we won't fail.
+	 * remove original entries unless we did in-place extend.
 	 */
 
 	if (oldva != newva || oldmap != newmap) {

Reply via email to