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 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -47,11 +47,12 @@
 {
 	if (!IPC_GET_RETVAL(answer->data)) {
-		pte_t *pte;
+		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);
+		bool found = page_mapping_find(AS, IPC_GET_ARG1(answer->data),
+		    false, &pte);
+		if (found) {
+			frame = PTE_GET_FRAME(&pte);
 			pfn_t pfn = ADDR2PFN(frame);
 			if (find_zone(pfn, 1, 0) != (size_t) -1) {
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/mm/as.c	(revision 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -889,10 +889,11 @@
 		
 				for (; i < node_size; i++) {
-					pte_t *pte = page_mapping_find(as,
-					    ptr + P2SZ(i), false);
+					pte_t pte;
+					bool found = page_mapping_find(as,
+					    ptr + P2SZ(i), false, &pte);
 					
-					ASSERT(pte);
-					ASSERT(PTE_VALID(pte));
-					ASSERT(PTE_PRESENT(pte));
+					ASSERT(found);
+					ASSERT(PTE_VALID(&pte));
+					ASSERT(PTE_PRESENT(&pte));
 					
 					if ((area->backend) &&
@@ -900,5 +901,5 @@
 						area->backend->frame_free(area,
 						    ptr + P2SZ(i),
-						    PTE_GET_FRAME(pte));
+						    PTE_GET_FRAME(&pte));
 					}
 					
@@ -1003,10 +1004,11 @@
 			
 			for (size = 0; size < (size_t) node->value[i]; size++) {
-				pte_t *pte = page_mapping_find(as,
-				     ptr + P2SZ(size), false);
+				pte_t pte;
+				bool found = page_mapping_find(as,
+				     ptr + P2SZ(size), false, &pte);
 				
-				ASSERT(pte);
-				ASSERT(PTE_VALID(pte));
-				ASSERT(PTE_PRESENT(pte));
+				ASSERT(found);
+				ASSERT(PTE_VALID(&pte));
+				ASSERT(PTE_PRESENT(&pte));
 				
 				if ((area->backend) &&
@@ -1014,5 +1016,5 @@
 					area->backend->frame_free(area,
 					    ptr + P2SZ(size),
-					    PTE_GET_FRAME(pte));
+					    PTE_GET_FRAME(&pte));
 				}
 				
@@ -1315,12 +1317,13 @@
 			
 			for (size = 0; size < (size_t) node->value[i]; size++) {
-				pte_t *pte = page_mapping_find(as,
-				    ptr + P2SZ(size), false);
+				pte_t pte;
+				bool found = page_mapping_find(as,
+				    ptr + P2SZ(size), false, &pte);
 				
-				ASSERT(pte);
-				ASSERT(PTE_VALID(pte));
-				ASSERT(PTE_PRESENT(pte));
+				ASSERT(found);
+				ASSERT(PTE_VALID(&pte));
+				ASSERT(PTE_PRESENT(&pte));
 				
-				old_frame[frame_idx++] = PTE_GET_FRAME(pte);
+				old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
 				
 				/* Remove old mapping */
@@ -1452,10 +1455,11 @@
 	 * we need to make sure the mapping has not been already inserted.
 	 */
-	pte_t *pte;
-	if ((pte = page_mapping_find(AS, page, false))) {
-		if (PTE_PRESENT(pte)) {
-			if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
-			    (access == PF_ACCESS_WRITE && PTE_WRITABLE(pte)) ||
-			    (access == PF_ACCESS_EXEC && PTE_EXECUTABLE(pte))) {
+	pte_t pte;
+	bool found = page_mapping_find(AS, page, false, &pte);
+	if (found) {
+		if (PTE_PRESENT(&pte)) {
+			if (((access == PF_ACCESS_READ) && PTE_READABLE(&pte)) ||
+			    (access == PF_ACCESS_WRITE && PTE_WRITABLE(&pte)) ||
+			    (access == PF_ACCESS_EXEC && PTE_EXECUTABLE(&pte))) {
 				page_table_unlock(AS, false);
 				mutex_unlock(&area->lock);
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/mm/backend_anon.c	(revision 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -131,17 +131,21 @@
 			
 			for (j = 0; j < count; j++) {
-				pte_t *pte;
+				pte_t pte;
+				bool found;
 			
 				page_table_lock(area->as, false);
-				pte = page_mapping_find(area->as,
-				    base + P2SZ(j), false);
-				ASSERT(pte && PTE_VALID(pte) &&
-				    PTE_PRESENT(pte));
+				found = page_mapping_find(area->as,
+				    base + P2SZ(j), false, &pte);
+
+				ASSERT(found);
+				ASSERT(PTE_VALID(&pte));
+				ASSERT(PTE_PRESENT(&pte));
+
 				btree_insert(&area->sh_info->pagemap,
 				    (base + P2SZ(j)) - area->base,
-				    (void *) PTE_GET_FRAME(pte), NULL);
+				    (void *) PTE_GET_FRAME(&pte), NULL);
 				page_table_unlock(area->as, false);
 
-				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
+				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
 				frame_reference_add(pfn);
 			}
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/mm/backend_elf.c	(revision 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -184,5 +184,6 @@
 			
 			for (j = 0; j < count; j++) {
-				pte_t *pte;
+				pte_t pte;
+				bool found;
 			
 				/*
@@ -196,14 +197,17 @@
 				
 				page_table_lock(area->as, false);
-				pte = page_mapping_find(area->as,
-				    base + P2SZ(j), false);
-				ASSERT(pte && PTE_VALID(pte) &&
-				    PTE_PRESENT(pte));
+				found = page_mapping_find(area->as,
+				    base + P2SZ(j), false, &pte);
+
+				ASSERT(found);
+				ASSERT(PTE_VALID(&pte));
+				ASSERT(PTE_PRESENT(&pte));
+
 				btree_insert(&area->sh_info->pagemap,
 				    (base + P2SZ(j)) - area->base,
-				    (void *) PTE_GET_FRAME(pte), NULL);
+				    (void *) PTE_GET_FRAME(&pte), NULL);
 				page_table_unlock(area->as, false);
 
-				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
+				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
 				frame_reference_add(pfn);
 			}
@@ -335,11 +339,14 @@
 			dirty = true;
 		} else {
-			pte_t *pte = page_mapping_find(AS_KERNEL,
-			    base + i * FRAME_SIZE, true);
-
-			ASSERT(pte);
-			ASSERT(PTE_PRESENT(pte));
-
-			frame = PTE_GET_FRAME(pte);
+			pte_t pte;
+			bool found;
+
+			found = page_mapping_find(AS_KERNEL,
+			    base + i * FRAME_SIZE, true, &pte);
+
+			ASSERT(found);
+			ASSERT(PTE_PRESENT(&pte));
+
+			frame = PTE_GET_FRAME(&pte);
 		}	
 	} else if (upage >= start_anon) {
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/mm/page.c	(revision 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -137,13 +137,13 @@
 /** Find mapping for virtual page.
  *
- * @param as     Address space to which page belongs.
- * @param page   Virtual page.
- * @param nolock True if the page tables need not be locked.
- *
- * @return NULL if there is no such mapping; requested mapping
- *         otherwise.
- *
- */
-NO_TRACE pte_t *page_mapping_find(as_t *as, uintptr_t page, bool nolock)
+ * @param as       Address space to which page belongs.
+ * @param page     Virtual page.
+ * @param nolock   True if the page tables need not be locked.
+ * @param[out] pte Structure that will receive a copy of the found PTE.
+ *
+ * @return True if the mapping was found, false otherwise.
+ */
+NO_TRACE bool page_mapping_find(as_t *as, uintptr_t page, bool nolock,
+    pte_t *pte)
 {
 	ASSERT(nolock || page_table_locked(as));
@@ -153,5 +153,26 @@
 	
 	return page_mapping_operations->mapping_find(as,
-	    ALIGN_DOWN(page, PAGE_SIZE), nolock);
+	    ALIGN_DOWN(page, PAGE_SIZE), nolock, pte);
+}
+
+/** Update mapping for virtual page.
+ *
+ * Use only to update accessed and modified/dirty bits.
+ *
+ * @param as       Address space to which page belongs.
+ * @param page     Virtual page.
+ * @param nolock   True if the page tables need not be locked.
+ * @param pte      New PTE.
+ */
+NO_TRACE void page_mapping_update(as_t *as, uintptr_t page, bool nolock,
+    pte_t *pte)
+{
+	ASSERT(nolock || page_table_locked(as));
+	
+	ASSERT(page_mapping_operations);
+	ASSERT(page_mapping_operations->mapping_find);
+	
+	page_mapping_operations->mapping_update(as,
+	    ALIGN_DOWN(page, PAGE_SIZE), nolock, pte);
 }
 
@@ -173,11 +194,12 @@
 	page_table_lock(AS, true);
 	
-	pte_t *pte = page_mapping_find(AS, virt, false);
-	if ((!PTE_VALID(pte)) || (!PTE_PRESENT(pte))) {
+	pte_t pte;
+	bool found = page_mapping_find(AS, virt, false, &pte);
+	if (!found || !PTE_VALID(&pte) || !PTE_PRESENT(&pte)) {
 		page_table_unlock(AS, true);
 		return ENOENT;
 	}
 	
-	*phys = PTE_GET_FRAME(pte) +
+	*phys = PTE_GET_FRAME(&pte) +
 	    (virt - ALIGN_DOWN(virt, PAGE_SIZE));
 	
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision f126c876616f5bbece442f6a35e0434e74d4c869)
+++ kernel/generic/src/synch/futex.c	(revision 2a2fbc84d3b2a2ff06b9bb236ff8e813c17ce223)
@@ -291,10 +291,14 @@
 	spinlock_lock(&futex_ht_lock);
 
-	bool found = false;
-	pte_t *t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), true);
-	
-	if (t && PTE_VALID(t) && PTE_PRESENT(t)) {
-		found = true;
-		*paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
+	bool success = false;
+
+	pte_t t;
+	bool found;
+
+	found = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), true, &t);
+	if (found && PTE_VALID(&t) && PTE_PRESENT(&t)) {
+		success = true;
+		*paddr = PTE_GET_FRAME(&t) +
+		    (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
 	}
 	
@@ -302,5 +306,5 @@
 	page_table_unlock(AS, false);
 	
-	return found;
+	return success;
 }
 
