Index: kernel/generic/include/mm/page.h
===================================================================
--- kernel/generic/include/mm/page.h	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ kernel/generic/include/mm/page.h	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -37,4 +37,5 @@
 
 #include <typedefs.h>
+#include <proc/task.h>
 #include <mm/as.h>
 #include <memstr.h>
@@ -62,4 +63,6 @@
 extern uintptr_t hw_map(uintptr_t, size_t);
 
+extern sysarg_t sys_page_find_mapping(uintptr_t, uintptr_t *);
+
 #endif
 
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ kernel/generic/include/syscall/syscall.h	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -59,4 +59,6 @@
 	SYS_AS_AREA_DESTROY,
 	
+	SYS_PAGE_FIND_MAPPING,
+	
 	SYS_IPC_CALL_SYNC_FAST,
 	SYS_IPC_CALL_SYNC_SLOW,
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ kernel/generic/src/mm/page.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -60,4 +60,6 @@
 
 #include <mm/page.h>
+#include <genarch/mm/page_ht.h>
+#include <genarch/mm/page_pt.h>
 #include <arch/mm/page.h>
 #include <arch/mm/asid.h>
@@ -70,4 +72,6 @@
 #include <debug.h>
 #include <arch.h>
+#include <syscall/copy.h>
+#include <errno.h>
 
 /** Virtual operations for page subsystem. */
@@ -173,4 +177,35 @@
 }
 
+/** Syscall wrapper for getting mapping of a virtual page.
+ * 
+ * @retval EOK Everything went find, @p uspace_frame and @p uspace_node
+ *             contains correct values.
+ * @retval ENOENT Virtual address has no mapping.
+ */
+sysarg_t sys_page_find_mapping(uintptr_t virt_address,
+    uintptr_t *uspace_frame)
+{
+	mutex_lock(&AS->lock);
+	
+	pte_t *pte = page_mapping_find(AS, virt_address);
+	if (!PTE_VALID(pte) || !PTE_PRESENT(pte)) {
+		mutex_unlock(&AS->lock);
+		
+		return (sysarg_t) ENOENT;
+	}
+	
+	uintptr_t phys_address = PTE_GET_FRAME(pte);
+	
+	mutex_unlock(&AS->lock);
+	
+	int rc = copy_to_uspace(uspace_frame,
+	    &phys_address, sizeof(phys_address));
+	if (rc != EOK) {
+		return (sysarg_t) rc;
+	}
+	
+	return EOK;
+}
+
 /** @}
  */
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ kernel/generic/src/syscall/syscall.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -41,4 +41,5 @@
 #include <proc/program.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <print.h>
 #include <arch.h>
@@ -144,4 +145,7 @@
 	(syshandler_t) sys_as_area_destroy,
 	
+	/* Page mapping related syscalls. */
+	(syshandler_t) sys_page_find_mapping,
+	
 	/* IPC related syscalls. */
 	(syshandler_t) sys_ipc_call_sync_fast,
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ uspace/app/tester/Makefile	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -53,4 +53,5 @@
 	loop/loop1.c \
 	mm/malloc1.c \
+	mm/mapping1.c \
 	hw/misc/virtchar1.c \
 	hw/serial/serial1.c
Index: uspace/app/tester/mm/mapping1.c
===================================================================
--- uspace/app/tester/mm/mapping1.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
+++ uspace/app/tester/mm/mapping1.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <as.h>
+#include <errno.h>
+#include "../tester.h"
+
+#define BUFFER1_PAGES 4
+#define BUFFER2_PAGES 2
+
+static void *create_as_area(size_t size)
+{
+	void *result = as_get_mappable_page(size);
+	TPRINTF("Creating AS area...\n");
+	if (as_area_create(result, size,
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE) != result) {
+		return NULL;
+	}
+	return result;
+}
+
+static void touch_area(void *area, size_t size)
+{
+	TPRINTF("Touching (faulting-in) AS area...\n");
+	
+	char *ptr = (char *)area;
+	
+	while (size > 0) {
+		*ptr = 0;
+		size--;
+		ptr++;
+	}
+}
+
+#define VERIFY_MAPPING(area, page_count, expected_rc) \
+    verify_mapping((area), (page_count), (expected_rc), #expected_rc)
+
+static bool verify_mapping(void *area, int page_count, int expected_rc,
+    const char *expected_rc_str)
+{
+	TPRINTF("Verifying mapping (expected: %s).\n", expected_rc_str);
+	int i;
+	for (i = 0; i < page_count; i++) {
+		void *page_start = ((char *)area) + PAGE_SIZE * i;
+		int rc = as_get_physical_mapping(page_start, NULL);
+		if (rc != expected_rc) {
+			TPRINTF("as_get_physical_mapping() = %d != %d\n",
+			    rc, expected_rc);
+			return false;
+		}
+	}
+	return true;
+}
+
+const char *test_mapping1(void)
+{
+	int rc;
+	
+	size_t buffer1_len = BUFFER1_PAGES * PAGE_SIZE;
+	size_t buffer2_len = BUFFER2_PAGES * PAGE_SIZE;
+	void *buffer1 = create_as_area(buffer1_len);
+	void *buffer2 = create_as_area(buffer2_len);
+	if (!buffer1 || !buffer2) {
+		return "Cannot allocate memory";
+	}
+	
+	touch_area(buffer1, buffer1_len);
+	touch_area(buffer2, buffer2_len);
+	
+	/* Now verify that mapping to physical frames exist. */
+	if (!VERIFY_MAPPING(buffer1, BUFFER1_PAGES, EOK)) {
+		return "Failed to find mapping (buffer1)";
+	}
+	if (!VERIFY_MAPPING(buffer2, BUFFER2_PAGES, EOK)) {
+		return "Failed to find mapping (buffer2)";
+	}
+	
+	/* Let's destroy the buffer1 area and access it again. */
+	rc = as_area_destroy(buffer1);
+	if (rc != EOK) {
+		return "Failed to destroy AS area";
+	}
+	if (!VERIFY_MAPPING(buffer1, BUFFER1_PAGES, ENOENT)) {
+		return "Mapping of destroyed area still exists";
+	}
+	
+	/* clean-up */
+	rc = as_area_destroy(buffer2);
+	if (rc != EOK) {
+		return "Failed to destroy AS area";
+	}
+	
+	return NULL;
+}
Index: uspace/app/tester/mm/mapping1.def
===================================================================
--- uspace/app/tester/mm/mapping1.def	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
+++ uspace/app/tester/mm/mapping1.def	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -0,0 +1,6 @@
+{
+	"mapping1",
+	"Page mapping test",
+	&test_mapping1,
+	true
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ uspace/app/tester/tester.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -62,4 +62,5 @@
 #include "loop/loop1.def"
 #include "mm/malloc1.def"
+#include "mm/mapping1.def"
 #include "hw/serial/serial1.def"
 #include "adt/usbaddrkeep.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ uspace/app/tester/tester.h	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -79,4 +79,5 @@
 extern const char *test_loop1(void);
 extern const char *test_malloc1(void);
+extern const char *test_mapping1(void);
 extern const char *test_serial1(void);
 extern const char *test_usbaddrkeep(void);
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ uspace/lib/c/generic/as.c	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -35,4 +35,5 @@
 #include <as.h>
 #include <libc.h>
+#include <errno.h>
 #include <unistd.h>
 #include <align.h>
@@ -128,4 +129,30 @@
 }
 
+/** Find mapping to physical address.
+ *
+ * @param address Virtual address in question (virtual).
+ * @param[out] frame Frame address (physical).
+ * @return Error code.
+ * @retval EOK No error, @p frame holds the translation.
+ * @retval ENOENT Mapping not found.
+ */
+int as_get_physical_mapping(void *address, uintptr_t *frame)
+{
+	uintptr_t tmp_frame;
+	uintptr_t virt = (uintptr_t) address;
+	
+	int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING,
+	    (sysarg_t) virt, (sysarg_t) &tmp_frame);
+	if (rc != EOK) {
+		return rc;
+	}
+	
+	if (frame != NULL) {
+		*frame = tmp_frame;
+	}
+	
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision 5d00e4020b7b5f980093c2a2251d4139e3abaa21)
+++ uspace/lib/c/include/as.h	(revision aa9f0a47f54267f92e96ab721dba7a89c21b440c)
@@ -47,4 +47,5 @@
 extern void *set_maxheapsize(size_t mhs);
 extern void * as_get_mappable_page(size_t sz);
+extern int as_get_physical_mapping(void *address, uintptr_t *frame);
 
 #endif
