Index: kernel/arch/ia64/include/mm/frame.h
===================================================================
--- kernel/arch/ia64/include/mm/frame.h	(revision 7aaed09d88be49fac8360d3017e3328ed9b0635c)
+++ kernel/arch/ia64/include/mm/frame.h	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -43,4 +43,6 @@
 #include <typedefs.h>
 
+extern uintptr_t end_of_identity;
+
 extern void frame_low_arch_init(void);
 extern void frame_high_arch_init(void);
Index: kernel/arch/ia64/src/mm/frame.c
===================================================================
--- kernel/arch/ia64/src/mm/frame.c	(revision 7aaed09d88be49fac8360d3017e3328ed9b0635c)
+++ kernel/arch/ia64/src/mm/frame.c	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -51,4 +51,6 @@
 #define MINCONF 1
 
+uintptr_t end_of_identity = -1ULL;
+
 static void frame_common_arch_init(bool low)
 {
@@ -102,4 +104,7 @@
 	frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
 	    SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
+
+	/* PA2KA will work only on low-memory. */
+	end_of_identity = PA2KA(config.physmem_end - FRAME_SIZE) + PAGE_SIZE;
 }
 
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision 7aaed09d88be49fac8360d3017e3328ed9b0635c)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision 0fd9b3513b2c0cfce8b0c99e0acbaf3470c1bc80)
@@ -467,4 +467,13 @@
 }
 
+static bool is_kernel_fault(uintptr_t va)
+{
+	region_register_t rr;
+
+	rr.word = rr_read(VA2VRN(va));
+	rid_t rid = rr.map.rid;
+	return (RID2ASID(rid) == ASID_KERNEL) && (VA2VRN(va) == VRN_KERNEL);
+}
+
 /** Instruction TLB fault handler for faults with VHPT turned off.
  *
@@ -480,4 +489,6 @@
 	va = istate->cr_ifa; /* faulting address */
 	
+	ASSERT(!is_kernel_fault(va));
+
 	t = page_mapping_find(AS, va, true);
 	if (t) {
@@ -567,11 +578,11 @@
 {
 	if (istate->cr_isr.sp) {
-		/* Speculative load. Deffer the exception
-		   until a more clever approach can be used.
-		   
-		   Currently if we try to find the mapping
-		   for the speculative load while in the kernel,
-		   we might introduce a livelock because of
-		   the possibly invalid values of the address. */
+		/*
+		 * Speculative load. Deffer the exception until a more clever
+		 * approach can be used. Currently if we try to find the
+		 * mapping for the speculative load while in the kernel, we
+		 * might introduce a livelock because of the possibly invalid
+		 * values of the address.
+		 */
 		istate->cr_ipsr.ed = true;
 		return;
@@ -579,21 +590,20 @@
 	
 	uintptr_t va = istate->cr_ifa;  /* faulting address */
-	
-	region_register_t rr;
-	rr.word = rr_read(VA2VRN(va));
-	rid_t rid = rr.map.rid;
-	if (RID2ASID(rid) == ASID_KERNEL) {
-		if (VA2VRN(va) == VRN_KERNEL) {
+	as_t *as = AS;
+	
+	if (is_kernel_fault(va)) {
+		if (va < end_of_identity) {
 			/*
-			 * Provide KA2PA(identity) mapping for faulting piece of
-			 * kernel address space.
+			 * Create kernel identity mapping for low memory. 
 			 */
 			dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
 			return;
+		} else {
+			as = AS_KERNEL;
 		}
 	}
 	
 	
-	pte_t *entry = page_mapping_find(AS, va, true);
+	pte_t *entry = page_mapping_find(as, va, true);
 	if (entry) {
 		/*
@@ -641,8 +651,12 @@
 	uintptr_t va;
 	pte_t *t;
+	as_t *as = AS;
 	
 	va = istate->cr_ifa;  /* faulting address */
 	
-	t = page_mapping_find(AS, va, true);
+	if (is_kernel_fault(va))
+		as = AS_KERNEL;
+
+	t = page_mapping_find(as, va, true);
 	ASSERT((t) && (t->p));
 	if ((t) && (t->p) && (t->w)) {
@@ -674,4 +688,6 @@
 	
 	va = istate->cr_ifa;  /* faulting address */
+
+	ASSERT(!is_kernel_fault(va));
 	
 	t = page_mapping_find(AS, va, true);
@@ -703,8 +719,12 @@
 	uintptr_t va;
 	pte_t *t;
+	as_t *as = AS;
 	
 	va = istate->cr_ifa;  /* faulting address */
 	
-	t = page_mapping_find(AS, va, true);
+	if (is_kernel_fault(va))
+		as = AS_KERNEL;
+
+	t = page_mapping_find(as, va, true);
 	ASSERT((t) && (t->p));
 	if ((t) && (t->p)) {
@@ -736,4 +756,6 @@
 	
 	va = istate->cr_ifa;  /* faulting address */
+
+	ASSERT(!is_kernel_fault(va));
 	
 	/*
@@ -763,4 +785,6 @@
 	va = istate->cr_ifa;  /* faulting address */
 	
+	ASSERT(!is_kernel_fault(va));
+
 	t = page_mapping_find(AS, va, true);
 	ASSERT(t);
