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