Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/tester/Makefile	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -74,4 +74,5 @@
 	mm/malloc3.c \
 	mm/mapping1.c \
+	mm/pager1.c \
 	hw/misc/virtchar1.c \
 	hw/serial/serial1.c
Index: uspace/app/tester/mm/common.c
===================================================================
--- uspace/app/tester/mm/common.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/tester/mm/common.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -341,5 +341,6 @@
 	
 	area->addr = as_area_create(AS_AREA_ANY, size,
-	    AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
+	    AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE,
+	    AS_AREA_UNPAGED);
 	if (area->addr == AS_MAP_FAILED) {
 		free(area);
Index: uspace/app/tester/mm/mapping1.c
===================================================================
--- uspace/app/tester/mm/mapping1.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/tester/mm/mapping1.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -43,5 +43,5 @@
 	
 	void *result = as_area_create(AS_AREA_ANY, size,
-	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
 	if (result == AS_MAP_FAILED)
 		return NULL;
Index: uspace/app/tester/mm/pager1.c
===================================================================
--- uspace/app/tester/mm/pager1.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ uspace/app/tester/mm/pager1.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Jakub Jermar
+ * 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 <ns.h>
+#include <async.h>
+#include <errno.h>
+#include "../tester.h"
+
+static void *create_paged_area(size_t size)
+{
+	async_sess_t *vfs_pager_sess;
+
+	TPRINTF("Connecting to VFS pager...\n");
+
+	vfs_pager_sess = service_connect_blocking(SERVICE_VFS, INTERFACE_PAGER, 0);
+
+	if (!vfs_pager_sess)
+		return NULL;
+	
+	TPRINTF("Creating AS area...\n");
+	
+	void *result = async_as_area_create(AS_AREA_ANY, size,
+	    AS_AREA_READ | AS_AREA_CACHEABLE, vfs_pager_sess);
+	if (result == AS_MAP_FAILED)
+		return NULL;
+	
+	return result;
+}
+
+static void touch_area(void *area, size_t size)
+{
+	TPRINTF("Touching (faulting-in) AS area...\n");
+	
+	volatile char *ptr = (char *) area;
+	
+	char ch;
+	while ((ch = *ptr++))
+		putchar(ch);
+}
+
+const char *test_pager1(void)
+{
+	size_t buffer_len = PAGE_SIZE;
+	void *buffer = create_paged_area(buffer_len);
+	if (!buffer) {
+		return "Cannot allocate memory";
+	}
+	
+	touch_area(buffer, buffer_len);
+	
+	return NULL;
+}
Index: uspace/app/tester/mm/pager1.def
===================================================================
--- uspace/app/tester/mm/pager1.def	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ uspace/app/tester/mm/pager1.def	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -0,0 +1,6 @@
+{
+	"pager1",
+	"Pager test",
+	&test_pager1,
+	true
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/tester/tester.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -74,4 +74,5 @@
 #include "mm/malloc3.def"
 #include "mm/mapping1.def"
+#include "mm/pager1.def"
 #include "hw/serial/serial1.def"
 #include "hw/misc/virtchar1.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/tester/tester.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -107,4 +107,5 @@
 extern const char *test_malloc3(void);
 extern const char *test_mapping1(void);
+extern const char *test_pager1(void);
 extern const char *test_serial1(void);
 extern const char *test_virtchar1(void);
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/app/trace/syscalls.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -49,5 +49,5 @@
     [SYS_FUTEX_WAKEUP] = { "futex_wakeup",		1,	V_ERRNO },
 
-    [SYS_AS_AREA_CREATE] = { "as_area_create",		3,	V_ERRNO },
+    [SYS_AS_AREA_CREATE] = { "as_area_create",		5,	V_ERRNO },
     [SYS_AS_AREA_RESIZE] = { "as_area_resize",		3,	V_ERRNO },
     [SYS_AS_AREA_DESTROY] = { "as_area_destroy",	1,	V_ERRNO },
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/as.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -50,4 +50,6 @@
  * @param size  Size of the area.
  * @param flags Flags describing type of the area.
+ * @param pager If non-negative, phone to the external pager backing the area.
+ *              If AS_AREA_UNPAGED (-1), the area is anonymous.
  *
  * @return Starting virtual address of the created area on success.
@@ -55,8 +57,9 @@
  *
  */
-void *as_area_create(void *base, size_t size, unsigned int flags)
+void *as_area_create(void *base, size_t size, unsigned int flags, int pager)
 {
-	return (void *) __SYSCALL4(SYS_AS_AREA_CREATE, (sysarg_t) base,
-	    (sysarg_t) size, (sysarg_t) flags, (sysarg_t) __entry);
+	return (void *) __SYSCALL5(SYS_AS_AREA_CREATE, (sysarg_t) base,
+	    (sysarg_t) size, (sysarg_t) flags, (sysarg_t) __entry,
+	    (sysarg_t) pager);
 }
 
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/async.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -116,4 +116,5 @@
 #include <stdlib.h>
 #include <macros.h>
+#include <as.h>
 #include "private/libc.h"
 
@@ -3381,4 +3382,10 @@
 }
 
+void *async_as_area_create(void *base, size_t size, unsigned int flags,
+    async_sess_t *pager)
+{
+	return as_area_create(base, size, flags, pager->phone);
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/elf/elf_mod.c
===================================================================
--- uspace/lib/c/generic/elf/elf_mod.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/elf/elf_mod.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -370,5 +370,6 @@
 	 */
 	a = as_area_create((uint8_t *) base + bias, mem_sz,
-	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
+	    AS_AREA_UNPAGED);
 	if (a == AS_MAP_FAILED) {
 		DPRINTF("memory mapping failed (%p, %zu)\n",
Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/fibril.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -279,7 +279,7 @@
 	size_t stack_size = (stksz == FIBRIL_DFLT_STK_SIZE) ?
 	    stack_size_get() : stksz;
-	fibril->stack = as_area_create((void *) -1, stack_size,
+	fibril->stack = as_area_create(AS_AREA_ANY, stack_size,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
-	    AS_AREA_LATE_RESERVE);
+	    AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED);
 	if (fibril->stack == (void *) -1) {
 		fibril_teardown(fibril, false);
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/io/chargrid.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -60,5 +60,6 @@
 	if ((flags & CHARGRID_FLAG_SHARED) == CHARGRID_FLAG_SHARED) {
 		scrbuf = (chargrid_t *) as_area_create(AS_AREA_ANY, size,
-		    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+		    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
+		    AS_AREA_UNPAGED);
 		if (scrbuf == AS_MAP_FAILED)
 			return NULL;
Index: uspace/lib/c/generic/malloc.c
===================================================================
--- uspace/lib/c/generic/malloc.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/malloc.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -354,5 +354,5 @@
 	size_t asize = ALIGN_UP(size, PAGE_SIZE);
 	void *astart = as_area_create(AS_AREA_ANY, asize,
-	    AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
+	    AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
 	if (astart == AS_MAP_FAILED)
 		return false;
Index: uspace/lib/c/generic/thread.c
===================================================================
--- uspace/lib/c/generic/thread.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/generic/thread.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -116,5 +116,5 @@
 	void *stack = as_area_create(AS_AREA_ANY, stack_size,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
-	    AS_AREA_LATE_RESERVE);
+	    AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED);
 	if (stack == AS_MAP_FAILED) {
 		free(uarg);
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/include/as.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -38,9 +38,5 @@
 #include <sys/types.h>
 #include <abi/mm/as.h>
-#include <task.h>
 #include <libarch/config.h>
-
-#define AS_AREA_ANY    ((void *) -1)
-#define AS_MAP_FAILED  ((void *) -1)
 
 static inline size_t SIZE2PAGES(size_t size)
@@ -57,5 +53,5 @@
 }
 
-extern void *as_area_create(void *, size_t, unsigned int);
+extern void *as_area_create(void *, size_t, unsigned int, int);
 extern int as_area_resize(void *, size_t, unsigned int);
 extern int as_area_change_flags(void *, unsigned int);
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/c/include/async.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -488,4 +488,6 @@
 extern void async_remote_state_release_exchange(async_exch_t *);
 
+extern void *async_as_area_create(void *, size_t, unsigned int, async_sess_t *);
+
 #endif
 
Index: uspace/lib/draw/surface.c
===================================================================
--- uspace/lib/draw/surface.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/draw/surface.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -64,6 +64,8 @@
 	if (!pixbuf) {
 		if ((flags & SURFACE_FLAG_SHARED) == SURFACE_FLAG_SHARED) {
-			pixbuf = (pixel_t *) as_area_create(AS_AREA_ANY, pixbuf_size,
-			    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+			pixbuf = (pixel_t *) as_area_create(AS_AREA_ANY,
+			    pixbuf_size,
+			    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
+			    AS_AREA_UNPAGED);
 			if (pixbuf == AS_MAP_FAILED) {
 				free(surface);
Index: uspace/lib/posix/source/sys/mman.c
===================================================================
--- uspace/lib/posix/source/sys/mman.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/lib/posix/source/sys/mman.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -54,5 +54,5 @@
 		return MAP_FAILED;
 	
-	return as_area_create(start, length, prot);
+	return as_area_create(start, length, prot, AS_AREA_UNPAGED);
 }
 
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/srv/hid/compositor/compositor.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -55,4 +55,5 @@
 #include <async.h>
 #include <loc.h>
+#include <task.h>
 
 #include <io/keycode.h>
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/srv/hid/console/console.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -49,4 +49,5 @@
 #include <malloc.h>
 #include <as.h>
+#include <task.h>
 #include <fibril_synch.h>
 #include "console.h"
Index: uspace/srv/hid/output/output.c
===================================================================
--- uspace/srv/hid/output/output.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/srv/hid/output/output.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -32,4 +32,5 @@
 #include <macros.h>
 #include <as.h>
+#include <task.h>
 #include <ipc/output.h>
 #include "port/ega.h"
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ uspace/srv/vfs/vfs.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -37,5 +37,8 @@
 
 #include <vfs/vfs.h>
+#include <stdlib.h>
 #include <ipc/services.h>
+#include <abi/ipc/methods.h>
+#include <libarch/config.h>
 #include <ns.h>
 #include <async.h>
@@ -51,4 +54,35 @@
 #define NAME  "vfs"
 
+static void vfs_pager(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	async_answer_0(iid, EOK);
+
+	char *buf = memalign(PAGE_SIZE, 1);
+	const char hello[] = "Hello world!";
+
+	memcpy(buf, hello, sizeof(hello));
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		
+		if (!IPC_GET_IMETHOD(call))
+			break;
+		
+		switch (IPC_GET_IMETHOD(call)) {
+		case IPC_M_PAGE_IN:
+			if (buf)
+				async_answer_1(callid, EOK, (sysarg_t) buf);
+			else
+				async_answer_0(callid, ENOMEM);
+			break;
+			
+		default:
+			async_answer_0(callid, ENOTSUP);
+			break;
+		}
+	}
+}
+
 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
@@ -150,4 +184,6 @@
 int main(int argc, char **argv)
 {
+	int rc;
+
 	printf("%s: HelenOS VFS server\n", NAME);
 	
@@ -165,5 +201,5 @@
 	 */
 	plb = as_area_create(AS_AREA_ANY, PLB_SIZE,
-	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
 	if (plb == AS_MAP_FAILED) {
 		printf("%s: Cannot create address space area\n", NAME);
@@ -179,4 +215,12 @@
 
 	/*
+	 * Create a port for the pager.
+	 */
+	port_id_t port;
+	rc = async_create_port(INTERFACE_PAGER, vfs_pager, NULL, &port);
+	if (rc != EOK)
+		return rc;
+		
+	/*
 	 * Set a connection handling function/fibril.
 	 */
@@ -192,5 +236,5 @@
 	 * Register at the naming service.
 	 */
-	int rc = service_register(SERVICE_VFS);
+	rc = service_register(SERVICE_VFS);
 	if (rc != EOK) {
 		printf("%s: Cannot register VFS service\n", NAME);
