Index: arch/ia64/src/mm/tlb.c
===================================================================
--- arch/ia64/src/mm/tlb.c	(revision a0d74fd54b1285e717ed7f3095dbcf46662e74e9)
+++ arch/ia64/src/mm/tlb.c	(revision f76fed4ce9ef078664208e11cf713b1e09aa3a72)
@@ -33,4 +33,6 @@
 #include <mm/tlb.h>
 #include <mm/asid.h>
+#include <mm/page.h>
+#include <mm/as.h>
 #include <arch/mm/tlb.h>
 #include <arch/mm/page.h>
@@ -39,5 +41,5 @@
 #include <typedefs.h>
 #include <panic.h>
-#include <print.h>
+#include <arch.h>
 
 /** Invalidate all TLB entries. */
@@ -87,7 +89,4 @@
 	region_register rr;
 	bool restore_rr = false;
-
-	if (!(entry.p))
-		return;
 
 	rr.word = rr_read(VA2VRN(va));
@@ -167,7 +166,4 @@
 	bool restore_rr = false;
 
-	if (!(entry.p))
-		return;
-
 	rr.word = rr_read(VA2VRN(va));
 	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
@@ -217,5 +213,5 @@
  * @param tr Translation register if dtr is true, ignored otherwise.
  */
-void dtlb_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
+void dtlb_kernel_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
 {
 	tlb_entry_t entry;
@@ -239,10 +235,81 @@
 }
 
+/** Copy content of PTE into data translation cache.
+ *
+ * @param t PTE.
+ */
+void dtc_pte_copy(pte_t *t)
+{
+	tlb_entry_t entry;
+
+	entry.word[0] = 0;
+	entry.word[1] = 0;
+	
+	entry.p = t->p;
+	entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
+	entry.a = t->a;
+	entry.d = t->d;
+	entry.pl = t->k ? PL_KERNEL : PL_USER;
+	entry.ar = t->w ? AR_WRITE : AR_READ;
+	entry.ppn = t->frame >> PPN_SHIFT;
+	entry.ps = PAGE_WIDTH;
+	
+	dtc_mapping_insert(t->page, t->as->asid, entry);
+}
+
+/** Copy content of PTE into instruction translation cache.
+ *
+ * @param t PTE.
+ */
+void itc_pte_copy(pte_t *t)
+{
+	tlb_entry_t entry;
+
+	entry.word[0] = 0;
+	entry.word[1] = 0;
+	
+	ASSERT(t->x);
+	
+	entry.p = t->p;
+	entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
+	entry.a = t->a;
+	entry.pl = t->k ? PL_KERNEL : PL_USER;
+	entry.ar = t->x ? (AR_EXECUTE | AR_READ) : AR_READ;
+	entry.ppn = t->frame >> PPN_SHIFT;
+	entry.ps = PAGE_WIDTH;
+	
+	itc_mapping_insert(t->page, t->as->asid, entry);
+}
+
+/** Instruction TLB fault handler for faults with VHPT turned off.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void alternate_instruction_tlb_fault(__u64 vector, struct exception_regdump *pstate)
 {
-	panic("%s\n", __FUNCTION__);
-}
-
-/** Data TLB fault with VHPT turned off.
+	region_register rr;
+	__address va;
+	pte_t *t;
+	
+	va = pstate->cr_ifa;	/* faulting address */
+	t = page_mapping_find(AS, va);
+	if (t) {
+		/*
+		 * The mapping was found in software page hash table.
+		 * Insert it into data translation cache.
+		 */
+		itc_pte_copy(t);
+	} else {
+		/*
+		 * Forward the page fault to address space page fault handler.
+		 */
+		if (!as_page_fault(va)) {
+			panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
+		}
+	}
+}
+
+/** Data TLB fault handler for faults with VHPT turned off.
  *
  * @param vector Interruption vector.
@@ -254,4 +321,5 @@
 	rid_t rid;
 	__address va;
+	pte_t *t;
 	
 	va = pstate->cr_ifa;	/* faulting address */
@@ -264,11 +332,33 @@
 			 * kernel address space.
 			 */
-			dtlb_mapping_insert(va, KA2PA(va), false, 0);
+			dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
 			return;
 		}
 	}
-	panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
-}
-
+	
+	t = page_mapping_find(AS, va);
+	if (t) {
+		/*
+		 * The mapping was found in software page hash table.
+		 * Insert it into data translation cache.
+		 */
+		dtc_pte_copy(t);
+	} else {
+		/*
+		 * Forward the page fault to address space page fault handler.
+		 */
+		if (!as_page_fault(va)) {
+			panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
+		}
+	}
+}
+
+/** Data nested TLB fault handler.
+ *
+ * This fault should not occur.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void data_nested_tlb_fault(__u64 vector, struct exception_regdump *pstate)
 {
@@ -276,21 +366,95 @@
 }
 
+/** Data Dirty bit fault handler.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void data_dirty_bit_fault(__u64 vector, struct exception_regdump *pstate)
 {
-	panic("%s\n", __FUNCTION__);
-}
-
+	pte_t *t;
+
+	t = page_mapping_find(AS, pstate->cr_ifa);
+	ASSERT(t && t->p);
+	if (t && t->p) {
+		/*
+		 * Update the Dirty bit in page tables and reinsert
+		 * the mapping into DTC.
+		 */
+		t->d = true;
+		dtc_pte_copy(t);
+	}
+}
+
+/** Instruction access bit fault handler.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void instruction_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
 {
-	panic("%s\n", __FUNCTION__);
-}
-
+	pte_t *t;
+
+	t = page_mapping_find(AS, pstate->cr_ifa);
+	ASSERT(t && t->p);
+	if (t && t->p) {
+		/*
+		 * Update the Accessed bit in page tables and reinsert
+		 * the mapping into ITC.
+		 */
+		t->a = true;
+		itc_pte_copy(t);
+	}
+}
+
+/** Data access bit fault handler.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void data_access_bit_fault(__u64 vector, struct exception_regdump *pstate)
 {
-	panic("%s\n", __FUNCTION__);
-}
-
+	pte_t *t;
+
+	t = page_mapping_find(AS, pstate->cr_ifa);
+	ASSERT(t && t->p);
+	if (t && t->p) {
+		/*
+		 * Update the Accessed bit in page tables and reinsert
+		 * the mapping into DTC.
+		 */
+		t->a = true;
+		dtc_pte_copy(t);
+	}
+}
+
+/** Page not present fault handler.
+ *
+ * @param vector Interruption vector.
+ * @param pstate Structure with saved interruption state.
+ */
 void page_not_present(__u64 vector, struct exception_regdump *pstate)
 {
-	panic("%s\n", __FUNCTION__);
-}
+	region_register rr;
+	__address va;
+	pte_t *t;
+	
+	va = pstate->cr_ifa;	/* faulting address */
+	t = page_mapping_find(AS, va);
+	ASSERT(t);
+	
+	if (t->p) {
+		/*
+		 * If the Present bit is set in page hash table, just copy it
+		 * and update ITC/DTC.
+		 */
+		if (t->x)
+			itc_pte_copy(t);
+		else
+			dtc_pte_copy(t);
+	} else {
+		if (!as_page_fault(va)) {
+			panic("%s: va=%P, rid=%d\n", __FUNCTION__, pstate->cr_ifa, rr.map.rid);
+		}
+	}
+}
