Index: abi/include/abi/ipc/interfaces.h
===================================================================
--- abi/include/abi/ipc/interfaces.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ abi/include/abi/ipc/interfaces.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -81,4 +81,6 @@
 	INTERFACE_LOADER =
 	    FOURCC_COMPACT('l', 'o', 'a', 'd') | IFACE_EXCHANGE_SERIALIZE,
+	INTERFACE_PAGER =
+	    FOURCC_COMPACT('p', 'a', 'g', 'e') | IFACE_EXCHANGE_ATOMIC,
 	INTERFACE_LOGGER_WRITER =
 	    FOURCC_COMPACT('l', 'o', 'g', 'w') | IFACE_EXCHANGE_SERIALIZE,
Index: abi/include/abi/ipc/methods.h
===================================================================
--- abi/include/abi/ipc/methods.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ abi/include/abi/ipc/methods.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -51,144 +51,153 @@
  */
 
-/** This message is sent to answerbox when the phone is hung up
- *
- * The numerical value zero (0) of this method is important,
- * so as the value can be easily tested in conditions.
- *
- */
-#define IPC_M_PHONE_HUNGUP  0
-
-/** Clone connection.
- *
- * The calling task clones one of its phones for the callee.
- *
- * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
- *        - The callee gets the new phone from ARG1.
- *
- * - on answer, the callee acknowledges the new connection by sending EOK back
- *   or the kernel closes it
- *
- */
-#define IPC_M_CONNECTION_CLONE  1
-
-/** Protocol for establishing a cloned connection.
- *
- * Through this call, the recipient learns about the new cloned connection.
- *
- * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
- * - on answer, the callee acknowledges the new connection by sending EOK back
- *   or the kernel closes it
- *
- */
-#define IPC_M_CLONE_ESTABLISH  2
-
-/** Protocol for initializing callback connections.
- *
- * Calling process asks the callee to create a callback connection,
- * so that it can start initiating new messages.
- *
- * The protocol for negotiating is:
- * - sys_connect_to_me - sends a message IPC_M_CONNECT_TO_ME
- * - recipient         - upon receipt tries to allocate new phone
- *                       - if it fails, responds with ELIMIT
- *                     - passes call to userspace. If userspace
- *                       responds with error, phone is deallocated and
- *                       error is sent back to caller. Otherwise 
- *                       the call is accepted and the response is sent back.
- *                     - the hash of the allocated phone is passed to userspace
- *                       (on the receiving side) as ARG5 of the call.
- *
- */
-#define IPC_M_CONNECT_TO_ME  3
-
-/** Protocol for initializing new foward connections.
- *
- * Calling process asks the callee to create for him a new connection.
- * E.g. the caller wants a name server to connect him to print server.
- *
- * The protocol for negotiating is:
- * - sys_connect_me_to - send a synchronous message to name server
- *                       indicating that it wants to be connected to some
- *                       service
- *                     - arg1/2/3 are user specified, arg5 contains
- *                       address of the phone that should be connected
- *                       (TODO: it leaks to userspace)
- *  - recipient        -  if ipc_answer == 0, then accept connection
- *                     -  otherwise connection refused
- *                     -  recepient may forward message.
- *
- */
-#define IPC_M_CONNECT_ME_TO  4
-
-/** Send as_area over IPC.
- * - ARG1 - source as_area base address
- * - ARG2 - size of source as_area (filled automatically by kernel)
- * - ARG3 - flags of the as_area being sent
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - dst as_area lower bound
- * - ARG2 - dst as_area base adress pointer
- *          (filled automatically by the kernel)
- *
- */
-#define IPC_M_SHARE_OUT  5
-
-/** Receive as_area over IPC.
- * - ARG1 - destination as_area size
- * - ARG2 - user defined argument
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - source as_area base address
- * - ARG2 - flags that will be used for sharing
- * - ARG3 - dst as_area lower bound
- * - ARG4 - dst as_area base address (filled automatically by kernel)
- *
- */
-#define IPC_M_SHARE_IN  6
-
-/** Send data to another address space over IPC.
- * - ARG1 - source address space virtual address
- * - ARG2 - size of data to be copied, may be overriden by the recipient
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - final destination address space virtual address
- * - ARG2 - final size of data to be copied
- *
- */
-#define IPC_M_DATA_WRITE  7
-
-/** Receive data from another address space over IPC.
- * - ARG1 - destination virtual address in the source address space
- * - ARG2 - size of data to be received, may be cropped by the recipient 
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - source virtual address in the destination address space
- * - ARG2 - final size of data to be copied
- *
- */
-#define IPC_M_DATA_READ  8
-
-/** Authorize change of recipient's state in a third party task.
- * - ARG1 - user protocol defined data
- * - ARG2 - user protocol defined data
- * - ARG3 - user protocol defined data
- * - ARG5 - sender's phone to the third party task
- *
- * on EOK answer, the recipient must set:
- *
- * - ARG1 - recipient's phone to the third party task
- */
-#define IPC_M_STATE_CHANGE_AUTHORIZE  9
-
-/** Debug the recipient.
- * - ARG1 - specifies the debug method (from udebug_method_t)
- * - other arguments are specific to the debug method
- *
- */
-#define IPC_M_DEBUG  10
+enum {
+	/** This message is sent to answerbox when the phone is hung up
+	 *
+	 * The numerical value zero (0) of this method is important,
+	 * so as the value can be easily tested in conditions.
+	 */
+	IPC_M_PHONE_HUNGUP = 0,
+
+	/** Clone connection.
+	 *
+	 * The calling task clones one of its phones for the callee.
+	 *
+	 * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
+	 *        - The callee gets the new phone from ARG1.
+	 *
+	 * - on answer, the callee acknowledges the new connection by sending EOK back
+	 *   or the kernel closes it
+	 */
+	IPC_M_CONNECTION_CLONE,
+
+	/** Protocol for establishing a cloned connection.
+	 *
+	 * Through this call, the recipient learns about the new cloned connection.
+	 *
+	 * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
+	 * - on answer, the callee acknowledges the new connection by sending EOK back
+	 *   or the kernel closes it
+	 */
+	IPC_M_CLONE_ESTABLISH,
+
+	/** Protocol for initializing callback connections.
+	 *
+	 * Calling process asks the callee to create a callback connection,
+	 * so that it can start initiating new messages.
+	 *
+	 * The protocol for negotiating is:
+	 * - sys_connect_to_me - sends a message IPC_M_CONNECT_TO_ME
+	 * - recipient         - upon receipt tries to allocate new phone
+	 *                       - if it fails, responds with ELIMIT
+	 *                     - passes call to userspace. If userspace
+	 *                       responds with error, phone is deallocated and
+	 *                       error is sent back to caller. Otherwise 
+	 *                       the call is accepted and the response is sent back.
+	 *                     - the hash of the allocated phone is passed to userspace
+	 *                       (on the receiving side) as ARG5 of the call.
+	 */
+	IPC_M_CONNECT_TO_ME,
+
+	/** Protocol for initializing new foward connections.
+	 *
+	 * Calling process asks the callee to create for him a new connection.
+	 * E.g. the caller wants a name server to connect him to print server.
+	 *
+	 * The protocol for negotiating is:
+	 * - sys_connect_me_to - send a synchronous message to name server
+	 *                       indicating that it wants to be connected to some
+	 *                       service
+	 *                     - arg1/2/3 are user specified, arg5 contains
+	 *                       address of the phone that should be connected
+	 *                       (TODO: it leaks to userspace)
+	 *  - recipient        - if ipc_answer == 0, then accept connection
+	 *                     - otherwise connection refused
+	 *                     - recepient may forward message.
+	 */
+	IPC_M_CONNECT_ME_TO,
+
+	/** Share a single page over IPC.
+	 *
+	 * - ARG1 - page-aligned offset from the beginning of the memory object
+	 * - ARG2 - page size
+	 *
+	 * on answer, the recipient must set:
+	 *
+	 * - ARG1 - source user page address
+	 */ 
+	IPC_M_PAGE_IN,
+
+	/** Receive as_area over IPC.
+	 * 
+	 * - ARG1 - destination as_area size
+	 * - ARG2 - user defined argument
+	 *
+	 * on answer, the recipient must set:
+	 *
+	 * - ARG1 - source as_area base address
+	 * - ARG2 - flags that will be used for sharing
+	 * - ARG3 - dst as_area lower bound
+	 * - ARG4 - dst as_area base address (filled automatically by kernel)
+	 */
+	IPC_M_SHARE_IN,
+
+	/** Send as_area over IPC.
+	 *
+	 * - ARG1 - source as_area base address
+	 * - ARG2 - size of source as_area (filled automatically by kernel)
+	 * - ARG3 - flags of the as_area being sent
+	 *
+	 * on answer, the recipient must set:
+	 *
+	 * - ARG1 - dst as_area lower bound
+	 * - ARG2 - dst as_area base adress pointer
+	 *          (filled automatically by the kernel)
+	 */
+	IPC_M_SHARE_OUT,
+
+	/** Receive data from another address space over IPC.
+	 *
+	 * - ARG1 - destination virtual address in the source address space
+	 * - ARG2 - size of data to be received, may be cropped by the recipient 
+	 *
+	 * on answer, the recipient must set:
+	 *
+	 * - ARG1 - source virtual address in the destination address space
+	 * - ARG2 - final size of data to be copied
+	 */
+	IPC_M_DATA_READ,
+
+	/** Send data to another address space over IPC.
+	 *
+	 * - ARG1 - source address space virtual address
+	 * - ARG2 - size of data to be copied, may be overriden by the recipient
+	 *
+	 * on answer, the recipient must set:
+	 *
+	 * - ARG1 - final destination address space virtual address
+	 * - ARG2 - final size of data to be copied
+	 */
+	IPC_M_DATA_WRITE,
+
+	/** Authorize change of recipient's state in a third party task.
+ 	 *
+	 * - ARG1 - user protocol defined data
+	 * - ARG2 - user protocol defined data
+	 * - ARG3 - user protocol defined data
+	 * - ARG5 - sender's phone to the third party task
+	 *
+	 * on EOK answer, the recipient must set:
+	 *
+	 * - ARG1 - recipient's phone to the third party task
+	 */
+	IPC_M_STATE_CHANGE_AUTHORIZE,
+
+	/** Debug the recipient.
+	 *
+	 * - ARG1 - specifies the debug method (from udebug_method_t)
+	 * - other arguments are specific to the debug method
+	 */
+	IPC_M_DEBUG,
+};
 
 /** Last system IPC method */
Index: abi/include/abi/mm/as.h
===================================================================
--- abi/include/abi/mm/as.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ abi/include/abi/mm/as.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -44,4 +44,9 @@
 #define AS_AREA_LATE_RESERVE 0x20
 
+#define AS_AREA_ANY    ((void *) -1)
+#define AS_MAP_FAILED  ((void *) -1)
+
+#define AS_AREA_UNPAGED -1
+
 /** Address space area info exported to uspace. */
 typedef struct {
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/Makefile	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -237,4 +237,5 @@
 	generic/src/mm/backend_elf.c \
 	generic/src/mm/backend_phys.c \
+	generic/src/mm/backend_user.c \
 	generic/src/mm/slab.c \
 	generic/src/lib/func.c \
@@ -278,4 +279,5 @@
 	generic/src/ipc/ops/datawrite.c \
 	generic/src/ipc/ops/debug.c \
+	generic/src/ipc/ops/pagein.c \
 	generic/src/ipc/ops/sharein.c \
 	generic/src/ipc/ops/shareout.c \
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/include/ipc/ipc.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -147,4 +147,11 @@
 	struct task *sender;
 	
+	/*
+	 * Answerbox that will receive the answer.
+	 * This will most of the times be the sender's answerbox,
+	 * but we allow for useful exceptions.
+	 */
+	answerbox_t *callerbox;
+
 	/** Phone which was used to send the call. */
 	phone_t *caller_phone;
@@ -172,4 +179,5 @@
 extern void ipc_call_release(call_t *);
 
+extern int ipc_call_sync(phone_t *, call_t *);
 extern int ipc_call(phone_t *, call_t *);
 extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/include/ipc/sysipc.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -40,4 +40,6 @@
 #include <typedefs.h>
 
+extern int ipc_req_internal(int, ipc_data_t *);
+
 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t);
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/include/mm/as.h	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -169,4 +169,8 @@
 /** Backend data stored in address space area. */
 typedef union mem_backend_data {
+	/* anon_backend members */
+	struct {
+	};
+
 	/** elf_backend members */
 	struct {
@@ -181,4 +185,10 @@
 		bool anonymous;
 	};
+
+	/** user_backend members */
+	struct {
+		int pager;	/**< Phone to the pager. */
+	};
+
 } mem_backend_data_t;
 
@@ -296,7 +306,9 @@
 extern mem_backend_t elf_backend;
 extern mem_backend_t phys_backend;
+extern mem_backend_t user_backend;
 
 /* Address space area related syscalls. */
-extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t);
+extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t,
+    int);
 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);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/src/ipc/ipc.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -77,4 +77,5 @@
 	call->forget = false;
 	call->sender = NULL;
+	call->callerbox = &TASK->answerbox;
 	call->buffer = NULL;
 }
@@ -185,4 +186,32 @@
 	phone->state = IPC_PHONE_FREE;
 	atomic_set(&phone->active_calls, 0);
+}
+
+/** Helper function to facilitate synchronous calls.
+ *
+ * @param phone   Destination kernel phone structure.
+ * @param request Call structure with request.
+ *
+ * @return EOK on success or a negative error code.
+ *
+ */
+int ipc_call_sync(phone_t *phone, call_t *request)
+{
+	answerbox_t *mybox = slab_alloc(ipc_answerbox_slab, 0);
+	ipc_answerbox_init(mybox, TASK);
+	
+	/* We will receive data in a special box. */
+	request->callerbox = mybox;
+	
+	int rc = ipc_call(phone, request);
+	if (rc != EOK) {
+		slab_free(ipc_answerbox_slab, mybox);
+		return rc;
+	}
+	// TODO: forget the call if interrupted
+	(void) ipc_wait_for_call(mybox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
+	
+	slab_free(ipc_answerbox_slab, mybox);
+	return EOK;
 }
 
@@ -220,5 +249,5 @@
 	spinlock_unlock(&call->forget_lock);
 
-	answerbox_t *callerbox = &call->sender->answerbox;
+	answerbox_t *callerbox = call->callerbox;
 	bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox));
 	
@@ -755,5 +784,5 @@
 	ipc_cleanup_call_list(&TASK->answerbox,
 	    &TASK->answerbox.dispatched_calls);
-
+ 	
 	ipc_forget_all_active_calls();
 	ipc_wait_for_all_answered_calls();
Index: kernel/generic/src/ipc/ops/pagein.c
===================================================================
--- kernel/generic/src/ipc/ops/pagein.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/ipc/ops/pagein.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <mm/as.h>
+#include <mm/page.h>
+#include <genarch/mm/page_pt.h>
+#include <genarch/mm/page_ht.h>
+#include <mm/frame.h>
+#include <proc/task.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	if (!IPC_GET_RETVAL(answer->data)) {
+		pte_t *pte;
+		uintptr_t frame;
+
+		page_table_lock(AS, true);
+		pte = page_mapping_find(AS, IPC_GET_ARG1(answer->data), false);
+		if (pte) {
+			frame = PTE_GET_FRAME(pte);
+			pfn_t pfn = ADDR2PFN(frame);
+			if (find_zone(pfn, 1, 0) != (size_t) -1) {
+				/*
+				 * The frame is in physical memory managed by
+				 * the frame allocator.
+				 */
+				frame_reference_add(ADDR2PFN(frame));
+			}
+			IPC_SET_ARG1(answer->data, frame);
+		} else {
+			IPC_SET_RETVAL(answer->data, ENOENT);
+		}
+		page_table_unlock(AS, true);
+	}
+	
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_page_in_ops = {
+	.request_preprocess = null_request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/src/ipc/sysipc.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -106,4 +106,5 @@
 {
 	switch (imethod) {
+	case IPC_M_PAGE_IN:
 	case IPC_M_SHARE_OUT:
 	case IPC_M_SHARE_IN:
@@ -137,4 +138,5 @@
 	case IPC_M_CONNECT_TO_ME:
 	case IPC_M_CONNECT_ME_TO:
+	case IPC_M_PAGE_IN:
 	case IPC_M_SHARE_OUT:
 	case IPC_M_SHARE_IN:
@@ -257,4 +259,47 @@
 {
 	return SYSIPC_OP(request_process, call, box);
+}
+
+/** Make a call over IPC and wait for reply.
+ *
+ * @param phoneid     Phone handle for the call.
+ * @param data[inout] Structure with request/reply data.
+ *
+ * @return EOK on success.
+ * @return ENOENT if there is no such phone handle.
+ *
+ */
+int ipc_req_internal(int phoneid, ipc_data_t *data)
+{
+	phone_t *phone;
+	if (phone_get(phoneid, &phone) != EOK)
+		return ENOENT;
+	
+	call_t *call = ipc_call_alloc(0);
+	memcpy(call->data.args, data->args, sizeof(data->args));
+	
+	int rc = request_preprocess(call, phone);
+	if (!rc) {
+#ifdef CONFIG_UDEBUG
+		udebug_stoppable_begin();
+#endif
+
+		rc = ipc_call_sync(phone, call); 
+
+#ifdef CONFIG_UDEBUG
+		udebug_stoppable_end();
+#endif
+
+		if (rc != EOK)
+			return EINTR;
+
+		process_answer(call);
+	} else
+		IPC_SET_RETVAL(call->data, rc);
+	
+	memcpy(data->args, call->data.args, sizeof(data->args));
+	ipc_call_free(call);
+	
+	return EOK;
 }
 
Index: kernel/generic/src/ipc/sysipc_ops.c
===================================================================
--- kernel/generic/src/ipc/sysipc_ops.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/src/ipc/sysipc_ops.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -42,4 +42,5 @@
 sysipc_ops_t ipc_m_connect_to_me_ops;
 sysipc_ops_t ipc_m_connect_me_to_ops;
+sysipc_ops_t ipc_m_page_in_ops;
 sysipc_ops_t ipc_m_share_out_ops;
 sysipc_ops_t ipc_m_share_in_ops;
@@ -54,4 +55,5 @@
 	[IPC_M_CONNECT_TO_ME] = &ipc_m_connect_to_me_ops,
 	[IPC_M_CONNECT_ME_TO] = &ipc_m_connect_me_to_ops,
+	[IPC_M_PAGE_IN] = &ipc_m_page_in_ops,
 	[IPC_M_SHARE_OUT] = &ipc_m_share_out_ops,
 	[IPC_M_SHARE_IN] = &ipc_m_share_in_ops,
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision bdfdc51cf6c5f6efd8f390b380b3a7ea368992af)
+++ kernel/generic/src/mm/as.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -574,6 +574,7 @@
  * @param backend_data NULL or a pointer to custom backend data.
  * @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.
+ *                     If set to AS_AREA_ANY, a suitable mappable area is
+ *                     found.
+ * @param bound        Lowest address bound if base is set to AS_AREA_ANY.
  *                     Otherwise ignored.
  *
@@ -585,5 +586,5 @@
     mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound)
 {
-	if ((*base != (uintptr_t) -1) && !IS_ALIGNED(*base, PAGE_SIZE))
+	if ((*base != (uintptr_t) AS_AREA_ANY) && !IS_ALIGNED(*base, PAGE_SIZE))
 		return NULL;
 	
@@ -601,5 +602,5 @@
 	mutex_lock(&as->lock);
 	
-	if (*base == (uintptr_t) -1) {
+	if (*base == (uintptr_t) AS_AREA_ANY) {
 		*base = as_get_unmapped_area(as, bound, size, guarded);
 		if (*base == (uintptr_t) -1) {
@@ -2182,11 +2183,20 @@
 
 sysarg_t sys_as_area_create(uintptr_t base, size_t size, unsigned int flags,
-    uintptr_t bound)
+    uintptr_t bound, int pager)
 {
 	uintptr_t virt = base;
+	mem_backend_t *backend;
+	mem_backend_data_t backend_data;
+
+	if (pager == AS_AREA_UNPAGED)
+		backend = &anon_backend;
+	else {
+		backend = &user_backend;
+		backend_data.pager = pager;
+	}
 	as_area_t *area = as_area_create(AS, flags, size,
-	    AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
+	    AS_AREA_ATTR_NONE, backend, &backend_data, &virt, bound);
 	if (area == NULL)
-		return (sysarg_t) -1;
+		return (sysarg_t) AS_MAP_FAILED;
 	
 	return (sysarg_t) virt;
Index: kernel/generic/src/mm/backend_user.c
===================================================================
--- kernel/generic/src/mm/backend_user.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/mm/backend_user.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup genericmm
+ * @{
+ */
+
+/**
+ * @file
+ * @brief	Backend for address space areas backed by the user pager.
+ *
+ */
+
+#include <mm/as.h>
+#include <mm/page.h>
+#include <abi/ipc/methods.h>
+#include <ipc/sysipc.h>
+#include <synch/mutex.h>
+#include <typedefs.h>
+#include <align.h>
+#include <debug.h>
+#include <errno.h>
+#include <log.h>
+
+static bool user_create(as_area_t *);
+static bool user_resize(as_area_t *, size_t);
+static void user_share(as_area_t *);
+static void user_destroy(as_area_t *);
+
+static bool user_is_resizable(as_area_t *);
+static bool user_is_shareable(as_area_t *);
+
+static int user_page_fault(as_area_t *, uintptr_t, pf_access_t);
+static void user_frame_free(as_area_t *, uintptr_t, uintptr_t);
+
+mem_backend_t user_backend = {
+	.create = user_create,
+	.resize = user_resize,
+	.share = user_share,
+	.destroy = user_destroy,
+
+	.is_resizable = user_is_resizable,
+	.is_shareable = user_is_shareable,
+
+	.page_fault = user_page_fault,
+	.frame_free = user_frame_free,
+
+	.create_shared_data = NULL,
+	.destroy_shared_data = NULL
+};
+
+bool user_create(as_area_t *area)
+{
+	return true;
+}
+
+bool user_resize(as_area_t *area, size_t new_pages)
+{
+	return true;
+}
+
+/** Share the user-paged address space area.
+ *
+ * The address space and address space area must be already locked.
+ *
+ * @param area Address space area to be shared.
+ */
+void user_share(as_area_t *area)
+{
+	ASSERT(mutex_locked(&area->as->lock));
+	ASSERT(mutex_locked(&area->lock));
+}
+
+void user_destroy(as_area_t *area)
+{
+	return;
+}
+
+bool user_is_resizable(as_area_t *area)
+{
+	return true;
+}
+
+bool user_is_shareable(as_area_t *area)
+{
+	return true;
+}
+
+/** Service a page fault in the user-paged address space area.
+ *
+ * The address space area and page tables must be already locked.
+ *
+ * @param area Pointer to the address space area.
+ * @param upage Faulting virtual page.
+ * @param access Access mode that caused the fault (i.e. read/write/exec).
+ *
+ * @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e.
+ *     serviced).
+ */
+int user_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access)
+{
+	ASSERT(page_table_locked(AS));
+	ASSERT(mutex_locked(&area->lock));
+	ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
+
+	if (!as_area_check_access(area, access))
+		return AS_PF_FAULT;
+
+	ipc_data_t data = {};
+	IPC_SET_IMETHOD(data, IPC_M_PAGE_IN);
+	IPC_SET_ARG1(data, upage - area->base);
+	IPC_SET_ARG2(data, PAGE_SIZE);
+
+	int rc = ipc_req_internal(area->backend_data.pager, &data);
+
+	if (rc != EOK) {
+		log(LF_USPACE, LVL_FATAL,
+		    "Page-in request for page %#" PRIxn
+		    " at pager %d failed with error %d.",
+		    upage, area->backend_data.pager, rc);
+		return AS_PF_FAULT;
+	}
+
+	if (IPC_GET_RETVAL(data) != EOK)
+		return AS_PF_FAULT;
+
+	/*
+	 * A successful reply will contain the physical frame in ARG1.
+	 * The physical frame will have the reference count already
+	 * incremented (if applicable).
+	 */
+
+	uintptr_t frame = IPC_GET_ARG1(data);
+	page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
+	if (!used_space_insert(area, upage, 1))
+		panic("Cannot insert used space.");
+
+	return AS_PF_OK;
+}
+
+/** Free a frame that is backed by the user memory backend.
+ *
+ * The address space area and page tables must be already locked.
+ *
+ * @param area Ignored.
+ * @param page Virtual address of the page corresponding to the frame.
+ * @param frame Frame to be released.
+ */
+void user_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
+{
+	ASSERT(page_table_locked(area->as));
+	ASSERT(mutex_locked(&area->lock));
+}
+
+/** @}
+ */
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);
