Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/include/ddi/ddi.h	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -55,11 +55,14 @@
 extern void ddi_parea_register(parea_t *);
 
-extern sysarg_t sys_physmem_map(uintptr_t, uintptr_t, size_t, unsigned int);
+extern sysarg_t sys_physmem_map(uintptr_t, size_t, unsigned int, void *,
+    uintptr_t);
+extern sysarg_t sys_physmem_unmap(uintptr_t);
 
-extern sysarg_t sys_dmamem_map(uintptr_t, size_t, unsigned int, unsigned int,
-    void *);
+extern sysarg_t sys_dmamem_map(size_t, unsigned int, unsigned int, void *,
+    void *, uintptr_t);
 extern sysarg_t sys_dmamem_unmap(uintptr_t, size_t, unsigned int);
 
 extern sysarg_t sys_iospace_enable(ddi_ioarg_t *);
+extern sysarg_t sys_iospace_disable(ddi_ioarg_t *);
 
 /*
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/include/mm/as.h	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -242,10 +242,10 @@
 extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
 
-extern as_area_t *as_area_create(as_t *, unsigned int, size_t, uintptr_t,
-    unsigned int, mem_backend_t *, mem_backend_data_t *);
+extern as_area_t *as_area_create(as_t *, unsigned int, size_t, unsigned int,
+    mem_backend_t *, mem_backend_data_t *, uintptr_t *, uintptr_t);
 extern int as_area_destroy(as_t *, uintptr_t);
 extern int as_area_resize(as_t *, uintptr_t, size_t, unsigned int);
-extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t,
-    unsigned int);
+extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, unsigned int,
+    uintptr_t *, uintptr_t);
 extern int as_area_change_flags(as_t *, unsigned int, uintptr_t);
 
@@ -284,9 +284,8 @@
 
 /* Address space area related syscalls. */
-extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int);
+extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t);
 extern sysarg_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
 extern sysarg_t sys_as_area_change_flags(uintptr_t, unsigned int);
 extern sysarg_t sys_as_area_destroy(uintptr_t);
-extern sysarg_t sys_as_get_unmapped_area(uintptr_t, size_t);
 
 /* Introspection functions. */
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/ddi/ddi.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -90,11 +90,12 @@
  *
  * @param phys  Physical address of the starting frame.
- * @param virt  Virtual address of the starting page.
  * @param pages Number of pages to map.
  * @param flags Address space area flags for the mapping.
+ * @param virt  Virtual address of the starting page.
+ * @param bound Lowest virtual address bound.
  *
  * @return EOK on success.
  * @return EPERM if the caller lacks capabilities to use this syscall.
- * @return EBADMEM if phys or virt is not page aligned.
+ * @return EBADMEM if phys is not page aligned.
  * @return ENOENT if there is no task matching the specified ID or
  *         the physical address space is not enabled for mapping.
@@ -102,13 +103,10 @@
  *
  */
-NO_TRACE static int ddi_physmem_map(uintptr_t phys, uintptr_t virt, size_t pages,
-    unsigned int flags)
+NO_TRACE static int physmem_map(uintptr_t phys, size_t pages,
+    unsigned int flags, uintptr_t *virt, uintptr_t bound)
 {
 	ASSERT(TASK);
 	
 	if ((phys % FRAME_SIZE) != 0)
-		return EBADMEM;
-	
-	if ((virt % PAGE_SIZE) != 0)
 		return EBADMEM;
 	
@@ -185,6 +183,6 @@
 	
 map:
-	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), virt,
-	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
+	if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages),
+	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
 		/*
 		 * The address space area was not created.
@@ -210,4 +208,44 @@
 }
 
+NO_TRACE static int physmem_unmap(uintptr_t virt)
+{
+	// TODO: implement unmap
+	return EOK;
+}
+
+/** Wrapper for SYS_PHYSMEM_MAP syscall.
+ *
+ * @param phys     Physical base address to map
+ * @param pages    Number of pages
+ * @param flags    Flags of newly mapped pages
+ * @param virt_ptr Destination virtual address
+ * @param bound    Lowest virtual address bound.
+ *
+ * @return 0 on success, otherwise it returns error code found in errno.h
+ *
+ */
+sysarg_t sys_physmem_map(uintptr_t phys, size_t pages, unsigned int flags,
+    void *virt_ptr, uintptr_t bound)
+{
+	uintptr_t virt = (uintptr_t) -1;
+	int rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags,
+	    &virt, bound);
+	if (rc != EOK)
+		return rc;
+	
+	rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));
+	if (rc != EOK) {
+		physmem_unmap((uintptr_t) virt);
+		return rc;
+	}
+	
+	return EOK;
+}
+
+sysarg_t sys_physmem_unmap(uintptr_t virt)
+{
+	return physmem_unmap(virt);
+}
+
 /** Enable range of I/O space for task.
  *
@@ -220,6 +258,5 @@
  *
  */
-NO_TRACE static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr,
-    size_t size)
+NO_TRACE static int iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
 {
 	/*
@@ -246,28 +283,8 @@
 	/* Lock the task and release the lock protecting tasks_btree. */
 	irq_spinlock_exchange(&tasks_lock, &task->lock);
-	
 	int rc = ddi_iospace_enable_arch(task, ioaddr, size);
-	
 	irq_spinlock_unlock(&task->lock, true);
 	
 	return rc;
-}
-
-/** Wrapper for SYS_PHYSMEM_MAP syscall.
- *
- * @param phys  Physical base address to map
- * @param virt  Destination virtual address
- * @param pages Number of pages
- * @param flags Flags of newly mapped pages
- *
- * @return 0 on success, otherwise it returns error code found in errno.h
- *
- */
-sysarg_t sys_physmem_map(uintptr_t phys, uintptr_t virt,
-    size_t pages, unsigned int flags)
-{
-	return (sysarg_t)
-	    ddi_physmem_map(ALIGN_DOWN(phys, FRAME_SIZE),
-	    ALIGN_DOWN(virt, PAGE_SIZE), pages, flags);
 }
 
@@ -286,68 +303,109 @@
 		return (sysarg_t) rc;
 	
-	return (sysarg_t) ddi_iospace_enable((task_id_t) arg.task_id,
+	return (sysarg_t) iospace_enable((task_id_t) arg.task_id,
 	    (uintptr_t) arg.ioaddr, (size_t) arg.size);
 }
 
-NO_TRACE static int dmamem_map(uintptr_t virt, size_t size,
-    unsigned int map_flags, unsigned int flags, void **phys)
+sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)
+{
+	// TODO: implement
+	return ENOTSUP;
+}
+
+NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys)
 {
 	ASSERT(TASK);
 	
+	// TODO: implement locking of non-anonymous mapping
+	return page_find_mapping(virt, phys);
+}
+
+NO_TRACE static int dmamem_map_anonymous(size_t size, unsigned int map_flags,
+    unsigned int flags, void **phys, uintptr_t *virt, uintptr_t bound)
+{
+	ASSERT(TASK);
+	
+	size_t pages = SIZE2FRAMES(size);
+	uint8_t order;
+	
+	/* We need the 2^order >= pages */
+	if (pages == 1)
+		order = 0;
+	else
+		order = fnzb(pages - 1) + 1;
+	
+	*phys = frame_alloc_noreserve(order, 0);
+	if (*phys == NULL)
+		return ENOMEM;
+	
+	mem_backend_data_t backend_data;
+	backend_data.base = (uintptr_t) *phys;
+	backend_data.frames = pages;
+	
+	if (!as_area_create(TASK->as, map_flags, size,
+	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
+		frame_free_noreserve((uintptr_t) *phys);
+		return ENOMEM;
+	}
+	
+	return EOK;
+}
+
+NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size)
+{
+	// TODO: implement unlocking & unmap
+	return EOK;
+}
+
+NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)
+{
+	// TODO: implement unlocking & unmap
+	return EOK;
+}
+
+sysarg_t sys_dmamem_map(size_t size, unsigned int map_flags, unsigned int flags,
+    void *phys_ptr, void *virt_ptr, uintptr_t bound)
+{
 	if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) {
-		// TODO: implement locking of non-anonymous mapping
-		return page_find_mapping(virt, phys);
+		/*
+		 * Non-anonymous DMA mapping
+		 */
+		
+		void *phys;
+		int rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags,
+		    flags, &phys);
+		
+		if (rc != EOK)
+			return rc;
+		
+		rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
+		if (rc != EOK) {
+			dmamem_unmap((uintptr_t) virt_ptr, size);
+			return rc;
+		}
 	} else {
-		// TODO: implement locking
-		
-		if ((virt % PAGE_SIZE) != 0)
-			return EBADMEM;
-		
-		size_t pages = SIZE2FRAMES(size);
-		uint8_t order;
-		
-		/* We need the 2^order >= pages */
-		if (pages == 1)
-			order = 0;
-		else
-			order = fnzb(pages - 1) + 1;
-		
-		*phys = frame_alloc_noreserve(order, 0);
-		if (*phys == NULL)
-			return ENOMEM;
-		
-		mem_backend_data_t backend_data;
-		backend_data.base = (uintptr_t) *phys;
-		backend_data.frames = pages;
-		
-		if (!as_area_create(TASK->as, map_flags, size, virt,
-		    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
-			frame_free_noreserve((uintptr_t) *phys);
-			return ENOMEM;
+		/*
+		 * Anonymous DMA mapping
+		 */
+		
+		void *phys;
+		uintptr_t virt = (uintptr_t) -1;
+		int rc = dmamem_map_anonymous(size, map_flags, flags,
+		    &phys, &virt, bound);
+		if (rc != EOK)
+			return rc;
+		
+		rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
+		if (rc != EOK) {
+			dmamem_unmap_anonymous((uintptr_t) virt);
+			return rc;
 		}
 		
-		return EOK;
-	}
-}
-
-NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size,
-    unsigned int flags)
-{
-	// TODO: implement unlocking & unmap
-	return EOK;
-}
-
-sysarg_t sys_dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
-    unsigned int flags, void *phys_ptr)
-{
-	void *phys;
-	int rc = dmamem_map(virt, size, map_flags, flags, &phys);
-	if (rc != EOK)
-		return rc;
-	
-	rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
-	if (rc != EOK) {
-		dmamem_unmap(virt, size, flags);
-		return rc;
+		rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));
+		if (rc != EOK) {
+			dmamem_unmap_anonymous((uintptr_t) virt);
+			return rc;
+		}
 	}
 	
@@ -357,5 +415,8 @@
 sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags)
 {
-	return dmamem_unmap(virt, size, flags);
+	if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0)
+		return dmamem_unmap(virt, size);
+	else
+		return dmamem_unmap_anonymous(virt);
 }
 
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/ipc/sysipc.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -271,7 +271,13 @@
 			irq_spinlock_unlock(&answer->sender->lock, true);
 			
+			uintptr_t dst_base = (uintptr_t) -1;
 			int rc = as_area_share(as, IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(*olddata), AS,
-			    IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
+			    IPC_GET_ARG2(*olddata), AS, IPC_GET_ARG3(*olddata),
+			    &dst_base, IPC_GET_ARG1(answer->data));
+			
+			if (rc == EOK)
+				rc = copy_to_uspace((void *) IPC_GET_ARG2(answer->data),
+				    &dst_base, sizeof(dst_base));
+			
 			IPC_SET_RETVAL(answer->data, rc);
 			return rc;
@@ -283,7 +289,9 @@
 			irq_spinlock_unlock(&answer->sender->lock, true);
 			
+			uintptr_t dst_base = (uintptr_t) -1;
 			int rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
-			    IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(answer->data));
+			    IPC_GET_ARG1(*olddata), as, IPC_GET_ARG2(answer->data),
+			    &dst_base, IPC_GET_ARG3(answer->data));
+			IPC_SET_ARG4(answer->data, dst_base);
 			IPC_SET_RETVAL(answer->data, rc);
 		}
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/lib/elf.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -226,6 +226,6 @@
 	size_t mem_sz = entry->p_memsz + (entry->p_vaddr - base);
 	
-	as_area_t *area = as_area_create(as, flags, mem_sz, base,
-	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
+	as_area_t *area = as_area_create(as, flags, mem_sz,
+	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data, &base, 0);
 	if (!area)
 		return EE_MEMORY;
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/mm/as.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -387,4 +387,71 @@
 }
 
+/** Return pointer to unmapped address space area
+ *
+ * The address space must be already locked when calling
+ * this function.
+ *
+ * @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.
+ * @return -1 if no suitable address space area was found.
+ *
+ */
+NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
+    size_t size)
+{
+	ASSERT(mutex_locked(&as->lock));
+	
+	if (size == 0)
+		return (uintptr_t) -1;
+	
+	/*
+	 * Make sure we allocate from page-aligned
+	 * address. Check for possible overflow in
+	 * each step.
+	 */
+	
+	size_t pages = SIZE2FRAMES(size);
+	
+	/*
+	 * Find the lowest unmapped address aligned on the size
+	 * boundary, not smaller than bound and of the required size.
+	 */
+	
+	/* First check the bound address itself */
+	uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
+	if ((addr >= bound) &&
+	    (check_area_conflicts(as, addr, pages, NULL)))
+		return addr;
+	
+	/* Eventually check the addresses behind each area */
+	list_foreach(as->as_area_btree.leaf_list, cur) {
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
+		
+		for (btree_key_t i = 0; i < node->keys; i++) {
+			as_area_t *area = (as_area_t *) node->value[i];
+			
+			mutex_lock(&area->lock);
+			
+			addr =
+			    ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
+			bool avail =
+			    ((addr >= bound) && (addr >= area->base) &&
+			    (check_area_conflicts(as, addr, pages, area)));
+			
+			mutex_unlock(&area->lock);
+			
+			if (avail)
+				return addr;
+		}
+	}
+	
+	/* No suitable address space area found */
+	return (uintptr_t) -1;
+}
+
 /** Create address space area of common attributes.
  *
@@ -394,8 +461,11 @@
  * @param flags        Flags of the area memory.
  * @param size         Size of area.
- * @param base         Base address of area.
  * @param attrs        Attributes of the area.
  * @param backend      Address space area backend. NULL if no backend is used.
  * @param backend_data NULL or a pointer to an array holding two void *.
+ * @param base         Starting virtual address of the area.
+ *                     If set to -1, a suitable mappable area is found.
+ * @param bound        Lowest address bound if base is set to -1.
+ *                     Otherwise ignored.
  *
  * @return Address space area on success or NULL on failure.
@@ -403,8 +473,8 @@
  */
 as_area_t *as_area_create(as_t *as, unsigned int flags, size_t size,
-    uintptr_t base, unsigned int attrs, mem_backend_t *backend,
-    mem_backend_data_t *backend_data)
-{
-	if ((base % PAGE_SIZE) != 0)
+    unsigned int attrs, mem_backend_t *backend,
+    mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound)
+{
+	if ((*base != (uintptr_t) -1) && ((*base % PAGE_SIZE) != 0))
 		return NULL;
 	
@@ -420,5 +490,13 @@
 	mutex_lock(&as->lock);
 	
-	if (!check_area_conflicts(as, base, pages, NULL)) {
+	if (*base == (uintptr_t) -1) {
+		*base = as_get_unmapped_area(as, bound, size);
+		if (*base == (uintptr_t) -1) {
+			mutex_unlock(&as->lock);
+			return NULL;
+		}
+	}
+	
+	if (!check_area_conflicts(as, *base, pages, NULL)) {
 		mutex_unlock(&as->lock);
 		return NULL;
@@ -434,5 +512,5 @@
 	area->pages = pages;
 	area->resident = 0;
-	area->base = base;
+	area->base = *base;
 	area->sh_info = NULL;
 	area->backend = backend;
@@ -452,5 +530,6 @@
 	
 	btree_create(&area->used_space);
-	btree_insert(&as->as_area_btree, base, (void *) area, NULL);
+	btree_insert(&as->as_area_btree, *base, (void *) area,
+	    NULL);
 	
 	mutex_unlock(&as->lock);
@@ -860,6 +939,9 @@
  * @param acc_size       Expected size of the source area.
  * @param dst_as         Pointer to destination address space.
- * @param dst_base       Target base address.
  * @param dst_flags_mask Destination address space area flags mask.
+ * @param dst_base       Target base address. If set to -1,
+ *                       a suitable mappable area is found.
+ * @param bound          Lowest address bound if dst_base is set to -1.
+ *                       Otherwise ignored.
  *
  * @return Zero on success.
@@ -873,5 +955,6 @@
  */
 int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
-    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
+    as_t *dst_as, unsigned int dst_flags_mask, uintptr_t *dst_base,
+    uintptr_t bound)
 {
 	mutex_lock(&src_as->lock);
@@ -945,6 +1028,7 @@
 	 * to support sharing in less privileged mode.
 	 */
-	as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size,
-	    dst_base, AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
+	as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask,
+	    src_size, AS_AREA_ATTR_PARTIAL, src_backend,
+	    &src_backend_data, dst_base, bound);
 	if (!dst_area) {
 		/*
@@ -1955,15 +2039,16 @@
  */
 
-/** Wrapper for as_area_create(). */
-sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
-{
-	if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
-	    AS_AREA_ATTR_NONE, &anon_backend, NULL))
-		return (sysarg_t) address;
-	else
+sysarg_t sys_as_area_create(uintptr_t base, size_t size, unsigned int flags,
+    uintptr_t bound)
+{
+	uintptr_t virt = base;
+	as_area_t *area = as_area_create(AS, flags | AS_AREA_CACHEABLE, size,
+	    AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
+	if (area == NULL)
 		return (sysarg_t) -1;
-}
-
-/** Wrapper for as_area_resize(). */
+	
+	return (sysarg_t) virt;
+}
+
 sysarg_t sys_as_area_resize(uintptr_t address, size_t size, unsigned int flags)
 {
@@ -1971,5 +2056,4 @@
 }
 
-/** Wrapper for as_area_change_flags(). */
 sysarg_t sys_as_area_change_flags(uintptr_t address, unsigned int flags)
 {
@@ -1977,75 +2061,7 @@
 }
 
-/** Wrapper for as_area_destroy(). */
 sysarg_t sys_as_area_destroy(uintptr_t address)
 {
 	return (sysarg_t) as_area_destroy(AS, address);
-}
-
-/** Return pointer to unmapped address space area
- *
- * @param base Lowest address bound.
- * @param size Requested size of the allocation.
- *
- * @return Pointer to the beginning of unmapped address space area.
- *
- */
-sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
-{
-	if (size == 0)
-		return 0;
-	
-	/*
-	 * Make sure we allocate from page-aligned
-	 * address. Check for possible overflow in
-	 * each step.
-	 */
-	
-	size_t pages = SIZE2FRAMES(size);
-	uintptr_t ret = 0;
-	
-	/*
-	 * Find the lowest unmapped address aligned on the sz
-	 * boundary, not smaller than base and of the required size.
-	 */
-	
-	mutex_lock(&AS->lock);
-	
-	/* First check the base address itself */
-	uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
-	if ((addr >= base) &&
-	    (check_area_conflicts(AS, addr, pages, NULL)))
-		ret = addr;
-	
-	/* Eventually check the addresses behind each area */
-	list_foreach(AS->as_area_btree.leaf_list, cur) {
-		if (ret != 0)
-			break;
-
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
-		btree_key_t i;
-		for (i = 0; (ret == 0) && (i < node->keys); i++) {
-			uintptr_t addr;
-
-			as_area_t *area = (as_area_t *) node->value[i];
-			
-			mutex_lock(&area->lock);
-			
-			addr = ALIGN_UP(area->base + P2SZ(area->pages),
-			    PAGE_SIZE);
-			
-			if ((addr >= base) && (addr >= area->base) &&
-			    (check_area_conflicts(AS, addr, pages, area)))
-				ret = addr;
-			
-			mutex_unlock(&area->lock);
-		}
-	}
-	
-	mutex_unlock(&AS->lock);
-	
-	return (sysarg_t) ret;
 }
 
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/proc/program.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -87,8 +87,8 @@
 	 * Create the stack address space area.
 	 */
+	uintptr_t virt = USTACK_ADDRESS;
 	as_area_t *area = as_area_create(as,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
-	    STACK_SIZE, USTACK_ADDRESS, AS_AREA_ATTR_NONE,
-	    &anon_backend, NULL);
+	    STACK_SIZE, AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, 0);
 	if (!area)
 		return ENOMEM;
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 17b3cc6490538b595c50dba6c1b9ad41139e2d8b)
+++ kernel/generic/src/syscall/syscall.c	(revision d9cf684a06c89943fd883b794b0b10a3a95d4bd9)
@@ -146,5 +146,4 @@
 	(syshandler_t) sys_as_area_change_flags,
 	(syshandler_t) sys_as_area_destroy,
-	(syshandler_t) sys_as_get_unmapped_area,
 	
 	/* Page mapping related syscalls. */
@@ -176,7 +175,9 @@
 	(syshandler_t) sys_device_assign_devno,
 	(syshandler_t) sys_physmem_map,
+	(syshandler_t) sys_physmem_unmap,
 	(syshandler_t) sys_dmamem_map,
 	(syshandler_t) sys_dmamem_unmap,
 	(syshandler_t) sys_iospace_enable,
+	(syshandler_t) sys_iospace_disable,
 	(syshandler_t) sys_irq_register,
 	(syshandler_t) sys_irq_unregister,
