Index: arch/amd64/include/mm/page.h
===================================================================
--- arch/amd64/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/amd64/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -82,4 +82,6 @@
 
 #define PTE_VALID_ARCH(p)			(*((__u64 *) (p)) != 0)
+#define PTE_PRESENT_ARCH(p)			((p)->present != 0)
+#define PTE_GET_FRAME_ARCH(p)			((((__address)(p)->addr_12_31)<<12) | ((__address)(p)->addr_32_51<<32))
 
 #ifndef __ASM__
Index: arch/ia32/include/mm/page.h
===================================================================
--- arch/ia32/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/ia32/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -81,4 +81,6 @@
 
 #define PTE_VALID_ARCH(p)			(*((__u32 *) (p)) != 0)
+#define PTE_PRESENT_ARCH(p)			((p)->present != 0)
+#define PTE_GET_FRAME_ARCH(p)			((p)->frame_address<<FRAME_WIDTH)
 
 #ifndef __ASM__
Index: arch/mips32/include/mm/page.h
===================================================================
--- arch/mips32/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/mips32/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -95,5 +95,7 @@
 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x)	set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
 
-#define PTE_VALID_ARCH(p)			(*((__u32 *) (p)) != 0)
+#define PTE_VALID_ARCH(pte)			(*((__u32 *) (pte)) != 0)
+#define PTE_PRESENT_ARCH(pte)			((pte)->p != 0)
+#define PTE_GET_FRAME_ARCH(pte)			((pte)->pfn<<FRAME_WIDTH)
 
 #ifndef __ASM__
Index: arch/ppc32/include/mm/page.h
===================================================================
--- arch/ppc32/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/ppc32/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -78,4 +78,6 @@
 
 #define PTE_VALID_ARCH(p)		1
+#define PTE_PRESENT_ARCH(p)		1
+#define PTE_GET_FRAME_ARCH(p)		0
 
 #ifndef __ASM__
Index: arch/ppc32/src/dummy.s
===================================================================
--- arch/ppc32/src/dummy.s	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/ppc32/src/dummy.s	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -37,4 +37,7 @@
 .global fpu_enable
 .global fpu_disable
+.global tlb_invalidate_all
+.global tlb_invalidate_asid
+.global tlb_invalidate_pages
 
 before_thread_runs_arch:
@@ -45,4 +48,8 @@
 fpu_enable:	
 fpu_disable:	
+tlb_invalidate_all:
+tlb_invalidate_asid:
+tlb_invalidate_pages:
+
 
 dummy:
Index: arch/sparc64/include/mm/page.h
===================================================================
--- arch/sparc64/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/sparc64/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -39,4 +39,5 @@
 #include <mm/page.h>
 #include <arch/types.h>
+#include <genarch/mm/page_ht.h>
 
 #define KA2PA(x)	((__address) (x))
Index: arch/sparc64/include/types.h
===================================================================
--- arch/sparc64/include/types.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ arch/sparc64/include/types.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -48,5 +48,5 @@
 
 typedef __u64 __native;
-typedef __s64 __native;
+typedef __s64 __snative;
 
 typedef struct pte pte_t;
Index: genarch/include/mm/page_ht.h
===================================================================
--- genarch/include/mm/page_ht.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ genarch/include/mm/page_ht.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -47,4 +47,8 @@
 #define PAGE_HT_ENTRIES		(1<<PAGE_HT_ENTRIES_BITS)
 
+#define PTE_VALID_ARCH(pte)		((pte) != NULL)
+#define PTE_PRESENT_ARCH(pte)		((pte)->p != 0)
+#define PTE_GET_FRAME_ARCH(pte)		((pte)->frame)
+
 struct pte {
 	link_t link;		/**< Page hash table link. */
Index: genarch/include/mm/page_pt.h
===================================================================
--- genarch/include/mm/page_pt.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ genarch/include/mm/page_pt.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -93,8 +93,7 @@
 #define SET_FRAME_FLAGS(ptl3, i, x)	SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
-/*
- * Determine whether the mapping is valid.
- */
-#define PTE_VALID(p)			PTE_VALID_ARCH((p))
+#define PTE_VALID(p)		PTE_VALID_ARCH((p))
+#define PTE_PRESENT(p)		PTE_PRESENT_ARCH((p))
+#define PTE_GET_FRAME(p)	PTE_GET_FRAME_ARCH((p))
 
 extern page_mapping_operations_t pt_mapping_operations;
Index: generic/include/mm/as.h
===================================================================
--- generic/include/mm/as.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ generic/include/mm/as.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -105,4 +105,5 @@
 extern as_t *as_create(int flags);
 extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base);
+extern __address as_remap(as_t *as, __address address, size_t size, int flags);
 extern void as_set_mapping(as_t *as, __address page, __address frame);
 extern int as_page_fault(__address page);
Index: generic/include/mm/page.h
===================================================================
--- generic/include/mm/page.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ generic/include/mm/page.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -61,5 +61,4 @@
 #define PAGE_GLOBAL		(1<<PAGE_GLOBAL_SHIFT)
 
-
 /* TODO - check that userspace is OK, platform specific functions etc */
 static inline void copy_to_uspace(void *dst, void *src, count_t cnt)
Index: generic/include/syscall/syscall.h
===================================================================
--- generic/include/syscall/syscall.h	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ generic/include/syscall/syscall.h	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -33,4 +33,5 @@
 	SYS_CTL = 0,
 	SYS_IO,
+	SYS_MREMAP,
 	SYS_IPC_CALL_SYNC,
 	SYS_IPC_CALL_SYNC_MEDIUM,
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ generic/src/mm/as.c	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -70,4 +70,5 @@
 
 static int get_area_flags(as_area_t *a);
+static as_area_t *find_area_and_lock(as_t *as, __address va);
 
 /** Initialize address space subsystem. */
@@ -169,6 +170,5 @@
 void as_set_mapping(as_t *as, __address page, __address frame)
 {
-	as_area_t *a, *area = NULL;
-	link_t *cur;
+	as_area_t *area;
 	ipl_t ipl;
 	
@@ -176,27 +176,9 @@
 	spinlock_lock(&as->lock);
 	
-	/*
-	 * First, try locate an area.
-	 */
-	for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) {
-		a = list_get_instance(cur, as_area_t, link);
-		spinlock_lock(&a->lock);
-
-		if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) {
-			area = a;
-			break;
-		}
-		
-		spinlock_unlock(&a->lock);
-	}
-	
+	area = find_area_and_lock(as, page);
 	if (!area) {
 		panic("page not part of any as_area\n");
 	}
 
-	/*
-	 * Note: area->lock is held.
-	 */
-	
 	page_mapping_insert(as, page, frame, get_area_flags(area));
 	
@@ -217,6 +199,5 @@
 int as_page_fault(__address page)
 {
-	link_t *cur;
-	as_area_t *a, *area = NULL;
+	as_area_t *area;
 	__address frame;
 	
@@ -224,24 +205,5 @@
 	spinlock_lock(&AS->lock);
 	
-	/*
-	 * Search this areas of this address space for presence of 'page'.
-	 */
-	for (cur = AS->as_area_head.next; cur != &AS->as_area_head; cur = cur->next) {
-		a = list_get_instance(cur, as_area_t, link);
-		spinlock_lock(&a->lock);
-
-		if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) {
-
-			/*
-			 * We found the area containing 'page'.
-			 * TODO: access checking
-			 */
-			area = a;
-			break;
-		}
-		
-		spinlock_unlock(&a->lock);
-	}
-	
+	area = find_area_and_lock(AS, page);	
 	if (!area) {
 		/*
@@ -253,8 +215,4 @@
 	}
 
-	/*
-	 * Note: area->lock is held.
-	 */
-	
 	/*
 	 * In general, there can be several reasons that
@@ -400,2 +358,97 @@
         return as_operations->page_table_create(flags);
 }
+
+/** Find address space area and change it.
+ *
+ * @param as Address space.
+ * @param address Virtual address belonging to the area to be changed. Must be page-aligned.
+ * @param size New size of the virtual memory block starting at address. 
+ * @param flags Flags influencing the remap operation. Currently unused.
+ *
+ * @return address on success, (__address) -1 otherwise.
+ */ 
+__address as_remap(as_t *as, __address address, size_t size, int flags)
+{
+	as_area_t *area = NULL;
+	ipl_t ipl;
+	size_t pages;
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&as->lock);
+	
+	/*
+	 * Locate the area.
+	 */
+	area = find_area_and_lock(as, address);
+	if (!area) {
+		spinlock_unlock(&as->lock);
+		return (__address) -1;
+	}
+
+	pages = SIZE2FRAMES((address - area->base) + size);
+	if (pages < area->size) {
+		int i;
+
+		/*
+		 * Shrinking the area.
+		 */
+		for (i = pages; i < area->size; i++) {
+			pte_t *pte;
+			
+			/*
+			 * Releasing physical memory.
+			 * This depends on the fact that the memory was allocated using frame_alloc().
+			 */ 
+			pte = page_mapping_find(as, area->base + i*PAGE_SIZE);
+			if (pte) {
+				ASSERT(PTE_PRESENT(pte));
+				frame_free(ADDR2PFN(PTE_GET_FRAME(pte)));
+			}
+			page_mapping_remove(as, area->base + i*PAGE_SIZE);
+		}
+		/*
+		 * Invalidate TLB's.
+		 */
+		tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area->size - pages);
+		tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area->size - pages);
+		tlb_shootdown_finalize();
+	} else {
+		/*
+		 * Growing the area.
+		 */
+		area->size = size;
+	}
+	
+	spinlock_unlock(&area->lock);
+	spinlock_unlock(&as->lock);
+	interrupts_restore(ipl);
+
+	return address;
+}
+
+/** Find address space area and lock it.
+ *
+ * The address space must be locked and interrupts must be disabled.
+ *
+ * @param as Address space.
+ * @param va Virtual address.
+ *
+ * @return Locked address space area containing va on success or NULL on failure.
+ */
+as_area_t *find_area_and_lock(as_t *as, __address va)
+{
+	link_t *cur;
+	as_area_t *a;
+	
+	for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) {
+		a = list_get_instance(cur, as_area_t, link);
+		spinlock_lock(&a->lock);
+
+		if ((va >= a->base) && (va < a->base + a->size * PAGE_SIZE))
+			 return a;
+		
+		spinlock_unlock(&a->lock);
+	}
+
+	return NULL;
+}
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision 5be19237d21f74d46fb963baab938dd33e90755e)
+++ generic/src/syscall/syscall.c	(revision d3e7ff48035bedaa7c22200c5da1b8629500fb65)
@@ -29,4 +29,5 @@
 #include <syscall/syscall.h>
 #include <proc/thread.h>
+#include <mm/as.h>
 #include <print.h>
 #include <putchar.h>
@@ -182,8 +183,13 @@
 }
 
+static __native sys_mremap(void *address, size_t size, unsigned long flags)
+{
+	return as_remap(AS, (__address) address, size, 0);
+}
 
 syshandler_t syscall_table[SYSCALL_END] = {
 	sys_ctl,
 	sys_io,
+	sys_mremap,
 	sys_ipc_call_sync,
 	sys_ipc_call_sync_medium,
