Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 908bb9645ed022f8ccdcdfd80a4b312d622b76e9)
+++ kernel/generic/src/mm/as.c	(revision f97f1e51a29f20f8f26f381c9c84567e9a997538)
@@ -79,5 +79,4 @@
 #include <syscall/copy.h>
 #include <arch/interrupt.h>
-#include <interrupt.h>
 
 /**
@@ -286,9 +285,8 @@
 /** Check area conflicts with other areas.
  *
- * @param as      Address space.
- * @param addr    Starting virtual address of the area being tested.
- * @param count   Number of pages in the area being tested.
- * @param guarded True if the area being tested is protected by guard pages.
- * @param avoid   Do not touch this area.
+ * @param as    Address space.
+ * @param addr  Starting virtual address of the area being tested.
+ * @param count Number of pages in the area being tested.
+ * @param avoid Do not touch this area.
  *
  * @return True if there is no conflict, false otherwise.
@@ -296,15 +294,8 @@
  */
 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
-    size_t count, bool guarded, as_area_t *avoid)
+    size_t count, as_area_t *avoid)
 {
 	ASSERT((addr % PAGE_SIZE) == 0);
 	ASSERT(mutex_locked(&as->lock));
-
-	/*
-	 * If the addition of the supposed area address and size overflows,
-	 * report conflict.
-	 */
-	if (overflows_into_positive(addr, P2SZ(count)))
-		return false;
 	
 	/*
@@ -313,5 +304,5 @@
 	if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))
 		return false;
-
+	
 	/*
 	 * The leaf node is found in O(log n), where n is proportional to
@@ -337,51 +328,6 @@
 		if (area != avoid) {
 			mutex_lock(&area->lock);
-
-			/*
-			 * If at least one of the two areas are protected
-			 * by the AS_AREA_GUARD flag then we must be sure
-			 * that they are separated by at least one unmapped
-			 * page.
-			 */
-			int const gp = (guarded || 
-			    (area->flags & AS_AREA_GUARD)) ? 1 : 0;
-			
-			/*
-			 * The area comes from the left neighbour node, which
-			 * means that there already are some areas in the leaf
-			 * node, which in turn means that adding gp is safe and
-			 * will not cause an integer overflow.
-			 */
+			
 			if (overlaps(addr, P2SZ(count), area->base,
-			    P2SZ(area->pages + gp))) {
-				mutex_unlock(&area->lock);
-				return false;
-			}
-			
-			mutex_unlock(&area->lock);
-		}
-	}
-	
-	node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
-	if (node) {
-		area = (as_area_t *) node->value[0];
-		
-		if (area != avoid) {
-			int gp;
-
-			mutex_lock(&area->lock);
-
-			gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
-			if (gp && overflows(addr, P2SZ(count))) {
-				/*
-				 * Guard page not needed if the supposed area
-				 * is adjacent to the end of the address space.
-				 * We already know that the following test is
-				 * going to fail...
-				 */
-				gp--;
-			}
-			
-			if (overlaps(addr, P2SZ(count + gp), area->base,
 			    P2SZ(area->pages))) {
 				mutex_unlock(&area->lock);
@@ -393,10 +339,25 @@
 	}
 	
+	node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
+	if (node) {
+		area = (as_area_t *) node->value[0];
+		
+		if (area != avoid) {
+			mutex_lock(&area->lock);
+			
+			if (overlaps(addr, P2SZ(count), area->base,
+			    P2SZ(area->pages))) {
+				mutex_unlock(&area->lock);
+				return false;
+			}
+			
+			mutex_unlock(&area->lock);
+		}
+	}
+	
 	/* Second, check the leaf node. */
 	btree_key_t i;
 	for (i = 0; i < leaf->keys; i++) {
 		area = (as_area_t *) leaf->value[i];
-		int agp;
-		int gp;
 		
 		if (area == avoid)
@@ -404,18 +365,7 @@
 		
 		mutex_lock(&area->lock);
-
-		gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
-		agp = gp;
-
-		/*
-		 * Sanitize the two possible unsigned integer overflows.
-		 */
-		if (gp && overflows(addr, P2SZ(count)))
-			gp--;
-		if (agp && overflows(area->base, P2SZ(area->pages)))
-			agp--;
-
-		if (overlaps(addr, P2SZ(count + gp), area->base,
-		    P2SZ(area->pages + agp))) {
+		
+		if (overlaps(addr, P2SZ(count), area->base,
+		    P2SZ(area->pages))) {
 			mutex_unlock(&area->lock);
 			return false;
@@ -427,10 +377,9 @@
 	/*
 	 * So far, the area does not conflict with other areas.
-	 * Check if it is contained in the user address space.
+	 * Check if it doesn't conflict with kernel address space.
 	 */
 	if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
-		return iswithin(USER_ADDRESS_SPACE_START,
-		    (USER_ADDRESS_SPACE_END - USER_ADDRESS_SPACE_START) + 1,
-		    addr, P2SZ(count));
+		return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
+		    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
 	}
 	
@@ -443,8 +392,7 @@
  * this function.
  *
- * @param as      Address space.
- * @param bound   Lowest address bound.
- * @param size    Requested size of the allocation.
- * @param guarded True if the allocation must be protected by guard pages.
+ * @param as    Address space.
+ * @param bound Lowest address bound.
+ * @param size  Requested size of the allocation.
  *
  * @return Address of the beginning of unmapped address space area.
@@ -453,5 +401,5 @@
  */
 NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
-    size_t size, bool guarded)
+    size_t size)
 {
 	ASSERT(mutex_locked(&as->lock));
@@ -475,15 +423,7 @@
 	/* First check the bound address itself */
 	uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
-	if (addr >= bound) {
-		if (guarded) {
-			/* Leave an unmapped page between the lower
-			 * bound and the area's start address.
-			 */
-			addr += P2SZ(1);
-		}
-
-		if (check_area_conflicts(as, addr, pages, guarded, NULL))
-			return addr;
-	}
+	if ((addr >= bound) &&
+	    (check_area_conflicts(as, addr, pages, NULL)))
+		return addr;
 	
 	/* Eventually check the addresses behind each area */
@@ -499,15 +439,7 @@
 			addr =
 			    ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
-
-			if (guarded || area->flags & AS_AREA_GUARD) {
-				/* We must leave an unmapped page
-				 * between the two areas.
-				 */
-				addr += P2SZ(1);
-			}
-
 			bool avail =
 			    ((addr >= bound) && (addr >= area->base) &&
-			    (check_area_conflicts(as, addr, pages, guarded, area)));
+			    (check_area_conflicts(as, addr, pages, area)));
 			
 			mutex_unlock(&area->lock);
@@ -549,5 +481,5 @@
 	if (size == 0)
 		return NULL;
-
+	
 	size_t pages = SIZE2FRAMES(size);
 	
@@ -555,11 +487,9 @@
 	if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
 		return NULL;
-
-	bool const guarded = flags & AS_AREA_GUARD;
 	
 	mutex_lock(&as->lock);
 	
 	if (*base == (uintptr_t) -1) {
-		*base = as_get_unmapped_area(as, bound, size, guarded);
+		*base = as_get_unmapped_area(as, bound, size);
 		if (*base == (uintptr_t) -1) {
 			mutex_unlock(&as->lock);
@@ -567,9 +497,6 @@
 		}
 	}
-
-	if (overflows_into_positive(*base, size))
-		return NULL;
-
-	if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
+	
+	if (!check_area_conflicts(as, *base, pages, NULL)) {
 		mutex_unlock(&as->lock);
 		return NULL;
@@ -698,8 +625,9 @@
 		return ENOENT;
 	}
-
-	if (!area->backend->is_resizable(area)) {
-		/*
-		 * The backend does not support resizing for this area.
+	
+	if (area->backend == &phys_backend) {
+		/*
+		 * Remapping of address space areas associated
+		 * with memory mapped devices is not supported.
 		 */
 		mutex_unlock(&area->lock);
@@ -737,4 +665,10 @@
 		
 		page_table_lock(as, false);
+		
+		/*
+		 * Start TLB shootdown sequence.
+		 */
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
+		    area->base + P2SZ(pages), area->pages - pages);
 		
 		/*
@@ -792,20 +726,4 @@
 				}
 				
-				/*
-				 * Start TLB shootdown sequence.
-				 *
-				 * The sequence is rather short and can be
-				 * repeated multiple times. The reason is that
-				 * we don't want to have used_space_remove()
-				 * inside the sequence as it may use a blocking
-				 * memory allocation for its B+tree. Blocking
-				 * while holding the tlblock spinlock is
-				 * forbidden and would hit a kernel assertion.
-				 */
-
-				ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES,
-				    as->asid, area->base + P2SZ(pages),
-				    area->pages - pages);
-		
 				for (; i < size; i++) {
 					pte_t *pte = page_mapping_find(as,
@@ -825,37 +743,29 @@
 					page_mapping_remove(as, ptr + P2SZ(i));
 				}
-		
-				/*
-				 * Finish TLB shootdown sequence.
-				 */
-		
-				tlb_invalidate_pages(as->asid,
-				    area->base + P2SZ(pages),
-				    area->pages - pages);
-		
-				/*
-				 * Invalidate software translation caches
-				 * (e.g. TSB on sparc64, PHT on ppc32).
-				 */
-				as_invalidate_translation_cache(as,
-				    area->base + P2SZ(pages),
-				    area->pages - pages);
-				tlb_shootdown_finalize(ipl);
 			}
 		}
+		
+		/*
+		 * Finish TLB shootdown sequence.
+		 */
+		
+		tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
+		    area->pages - pages);
+		
+		/*
+		 * Invalidate software translation caches
+		 * (e.g. TSB on sparc64, PHT on ppc32).
+		 */
+		as_invalidate_translation_cache(as, area->base + P2SZ(pages),
+		    area->pages - pages);
+		tlb_shootdown_finalize(ipl);
+		
 		page_table_unlock(as, false);
 	} else {
 		/*
 		 * Growing the area.
-		 */
-
-		if (overflows_into_positive(address, P2SZ(pages)))
-			return EINVAL;
-
-		/*
 		 * Check for overlaps with other address space areas.
 		 */
-		bool const guarded = area->flags & AS_AREA_GUARD;
-		if (!check_area_conflicts(as, address, pages, guarded, area)) {
+		if (!check_area_conflicts(as, address, pages, area)) {
 			mutex_unlock(&area->lock);
 			mutex_unlock(&as->lock);
@@ -1058,7 +968,8 @@
 	}
 	
-	if (!src_area->backend->is_shareable(src_area)) {
-		/*
-		 * The backend does not permit sharing of this area.
+	if ((!src_area->backend) || (!src_area->backend->share)) {
+		/*
+		 * There is no backend or the backend does not
+		 * know how to share the area.
 		 */
 		mutex_unlock(&src_area->lock);
@@ -1363,11 +1274,9 @@
 int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
 {
-	int rc = AS_PF_FAULT;
-
 	if (!THREAD)
-		goto page_fault;
+		return AS_PF_FAULT;
 	
 	if (!AS)
-		goto page_fault;
+		return AS_PF_FAULT;
 	
 	mutex_lock(&AS->lock);
@@ -1425,6 +1334,5 @@
 	 * Resort to the backend page fault handler.
 	 */
-	rc = area->backend->page_fault(area, page, access);
-	if (rc != AS_PF_OK) {
+	if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
 		page_table_unlock(AS, false);
 		mutex_unlock(&area->lock);
@@ -1447,11 +1355,6 @@
 		istate_set_retaddr(istate,
 		    (uintptr_t) &memcpy_to_uspace_failover_address);
-	} else if (rc == AS_PF_SILENT) {
-		printf("Killing task %" PRIu64 " due to a "
-		    "failed late reservation request.\n", TASK->taskid);
-		task_kill_self(true);
 	} else {
-		fault_if_from_uspace(istate, "Page fault: %p.", (void *) page);
-		panic_memtrap(istate, access, page, NULL);
+		return AS_PF_FAULT;
 	}
 	
