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) {