Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -507,5 +507,5 @@
 	if (t) {
 		/*
-		 * The mapping was found in software page hash table.
+		 * The mapping was found in the software page hash table.
 		 * Insert it into data translation cache.
 		 */
@@ -514,5 +514,5 @@
 	} else {
 		/*
-		 * Forward the page fault to address space page fault handler.
+		 * Forward the page fault to the address space page fault handler.
 		 */
 		page_table_unlock(AS, true);
Index: kernel/arch/sparc64/include/context.h
===================================================================
--- kernel/arch/sparc64/include/context.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/context.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -90,5 +90,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/context_offset.h
===================================================================
--- kernel/arch/sparc64/include/context_offset.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/context_offset.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -21,5 +21,2 @@
 #define OFFSET_CLEANWIN 0x98
 
- /** @}
- */
-
Index: kernel/arch/sparc64/include/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/interrupt.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/interrupt.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64interrupt sparc64
+/** @addtogroup sparc64interrupt sparc64
  * @ingroup interrupt
  * @{
@@ -53,4 +53,8 @@
 
 struct istate {
+	uint64_t	pstate;
+	uint64_t	tnpc;
+	uint64_t	tpc;
+	uint64_t	tstate;
 };
 
@@ -75,5 +79,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/mm/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/tlb.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/mm/tlb.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -67,4 +67,5 @@
 /* TLB Tag Access shifts */
 #define TLB_TAG_ACCESS_CONTEXT_SHIFT	0
+#define TLB_TAG_ACCESS_CONTEXT_MASK	((1<<13)-1)
 #define TLB_TAG_ACCESS_VPN_SHIFT	13
 
@@ -108,5 +109,5 @@
 	struct {
 		uint64_t vpn : 51;		/**< Virtual Address bits 63:13. */
-		unsigned context : 13;	/**< Context identifier. */
+		unsigned context : 13;		/**< Context identifier. */
 	} __attribute__ ((packed));
 };
@@ -119,5 +120,5 @@
 	uint64_t value;
 	struct {
-		uint64_t vpn: 51;		/**< Virtual Address bits 63:13. */
+		uint64_t vpn: 51;	/**< Virtual Address bits 63:13. */
 		unsigned : 6;		/**< Ignored. */
 		unsigned type : 1;	/**< The type of demap operation. */
@@ -132,9 +133,7 @@
 	uint64_t value;
 	struct {
-		unsigned long : 39;	/**< Implementation dependent. */
-		unsigned nf : 1;	/**< Nonfaulting load. */
+		unsigned long : 40;	/**< Implementation dependent. */
 		unsigned asi : 8;	/**< ASI. */
-		unsigned tm : 1;	/**< TLB miss. */
-		unsigned : 1;
+		unsigned : 2;
 		unsigned ft : 7;	/**< Fault type. */
 		unsigned e : 1;		/**< Side-effect bit. */
@@ -426,7 +425,7 @@
 }
 
-extern void fast_instruction_access_mmu_miss(void);
-extern void fast_data_access_mmu_miss(void);
-extern void fast_data_access_protection(void);
+extern void fast_instruction_access_mmu_miss(int n, istate_t *istate);
+extern void fast_data_access_mmu_miss(int n, istate_t *istate);
+extern void fast_data_access_protection(int n, istate_t *istate);
 
 extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
Index: kernel/arch/sparc64/include/regdef.h
===================================================================
--- kernel/arch/sparc64/include/regdef.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/regdef.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -39,4 +39,8 @@
 #define PSTATE_AM_BIT	8
 
+#define PSTATE_AG_BIT	(1<<0)
+#define PSTATE_IG_BIT	(1<<11)
+#define PSTATE_MG_BIT	(1<<10)
+
 #endif
 
Index: kernel/arch/sparc64/include/trap/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/trap/interrupt.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/trap/interrupt.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -82,5 +82,4 @@
 	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
 	mov \n - 1, %o0
-	mov %fp, %o1
 	PREEMPTIBLE_HANDLER exc_dispatch
 .endm
Index: kernel/arch/sparc64/include/trap/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/mmu.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/trap/mmu.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -39,4 +39,7 @@
 
 #include <arch/stack.h>
+#include <arch/mm/tlb.h>
+#include <arch/mm/mmu.h>
+#include <arch/mm/tte.h>
 
 #define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS	0x64
@@ -56,9 +59,35 @@
 
 .macro FAST_DATA_ACCESS_MMU_MISS_HANDLER
-	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
-	call fast_data_access_mmu_miss
-	nop
-	restore
+	/*
+	 * First, test if it is the portion of the kernel address space
+	 * which is faulting. If that is the case, immediately create
+	 * identity mapping for that page in DTLB. VPN 0 is excluded from
+	 * this treatment.
+	 *
+	 * Note that branch-delay slots are used in order to save space.
+	 */
+	mov VA_DMMU_TAG_ACCESS, %g1
+	ldxa [%g1] ASI_DMMU, %g1			! read the faulting Context and VPN
+	set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
+	andcc %g1, %g2, %g3				! get Context
+	bnz 0f						! Context is non-zero
+	andncc %g1, %g2, %g3				! get page address into %g3
+	bz 0f						! page address is zero
+
+	/*
+	 * Create and insert the identity-mapped entry for
+	 * the faulting kernel page.
+	 */
+	
+	or %g3, (TTE_CP|TTE_P|TTE_W), %g2		! 8K pages are the default (encoded as 0)
+        set 1, %g3
+        sllx %g3, TTE_V_SHIFT, %g3
+        or %g2, %g3, %g2
+	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
 	retry
+
+0:
+	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp						 
+	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
 .endm
 
Index: kernel/arch/sparc64/include/trap/trap_table.h
===================================================================
--- kernel/arch/sparc64/include/trap/trap_table.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/include/trap/trap_table.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -78,4 +78,8 @@
 .endm
 
+/*
+ * The following needs to be in sync with the
+ * definition of the istate structure.
+ */
 #define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE	(STACK_WINDOW_SAVE_AREA_SIZE+(4*8))
 #define SAVED_TSTATE	-(1*8)
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -35,8 +35,11 @@
 #include <arch/mm/tlb.h>
 #include <mm/tlb.h>
+#include <mm/as.h>
+#include <mm/asid.h>
 #include <arch/mm/frame.h>
 #include <arch/mm/page.h>
 #include <arch/mm/mmu.h>
-#include <mm/asid.h>
+#include <arch/interrupt.h>
+#include <arch.h>
 #include <print.h>
 #include <arch/types.h>
@@ -47,4 +50,7 @@
 #include <arch/asm.h>
 #include <symtab.h>
+
+static void dtlb_pte_copy(pte_t *t);
+static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
 
 char *context_encoding[] = {
@@ -100,35 +106,58 @@
 }
 
+void dtlb_pte_copy(pte_t *t)
+{
+}
+
 /** ITLB miss handler. */
-void fast_instruction_access_mmu_miss(void)
+void fast_instruction_access_mmu_miss(int n, istate_t *istate)
 {
 	panic("%s\n", __FUNCTION__);
 }
 
-/** DTLB miss handler. */
-void fast_data_access_mmu_miss(void)
+/** DTLB miss handler.
+ *
+ * Note that some faults (e.g. kernel faults) were already resolved
+ * by the low-level, assembly language part of the fast_data_access_mmu_miss
+ * handler.
+ */
+void fast_data_access_mmu_miss(int n, istate_t *istate)
 {
 	tlb_tag_access_reg_t tag;
-	uintptr_t tpc;
-	char *tpc_str;
+	uintptr_t va;
+	pte_t *t;
 
 	tag.value = dtlb_tag_access_read();
-	if (tag.context != ASID_KERNEL || tag.vpn == 0) {
-		tpc = tpc_read();
-		tpc_str = get_symtab_entry(tpc);
-
-		printf("Faulting page: %p, ASID=%d\n", tag.vpn * PAGE_SIZE, tag.context);
-		printf("TPC=%p, (%s)\n", tpc, tpc_str ? tpc_str : "?");
-		panic("%s\n", __FUNCTION__);
-	}
-
-	/*
-	 * Identity map piece of faulting kernel address space.
-	 */
-	dtlb_insert_mapping(tag.vpn * PAGE_SIZE, tag.vpn * FRAME_SIZE, PAGESIZE_8K, false, true);
+	va = tag.vpn * PAGE_SIZE;
+	if (tag.context == ASID_KERNEL) {
+		if (!tag.vpn) {
+			/* NULL access in kernel */
+			do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__);
+		}
+		do_fast_data_access_mmu_miss_fault(istate, "Unexpected kernel page fault.");
+	}
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, va);
+	if (t) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into DTLB.
+		 */
+		dtlb_pte_copy(t);
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
+			do_fast_data_access_mmu_miss_fault(istate, __FUNCTION__);
+		}
+	}
 }
 
 /** DTLB protection fault handler. */
-void fast_data_access_protection(void)
+void fast_data_access_protection(int n, istate_t *istate)
 {
 	panic("%s\n", __FUNCTION__);
@@ -162,4 +191,18 @@
 }
 
+void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
+{
+	tlb_tag_access_reg_t tag;
+	uintptr_t va;
+	char *tpc_str = get_symtab_entry(istate->tpc);
+
+	tag.value = dtlb_tag_access_read();
+	va = tag.vpn * PAGE_SIZE;
+
+	printf("Faulting page: %p, ASID=%d\n", va, tag.context);
+	printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
+	panic("%s\n", str);
+}
+
 /** Invalidate all unlocked ITLB and DTLB entries. */
 void tlb_invalidate_all(void)
Index: kernel/arch/sparc64/src/trap/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/trap_table.S	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/arch/sparc64/src/trap/trap_table.S	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -44,4 +44,5 @@
 #include <arch/trap/mmu.h>
 #include <arch/stack.h>
+#include <arch/regdef.h>
 
 #define TABLE_SIZE	TRAP_TABLE_SIZE
@@ -276,12 +277,22 @@
 
 
-/* Preemptible trap handler.
- *
- * This trap handler makes arrangements to
- * make calling scheduler() possible.
- *
- * The caller is responsible for doing save
- * and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE
- * bytes on stack.
+/* Preemptible trap handler for TL=1.
+ *
+ * This trap handler makes arrangements to make calling of scheduler() from
+ * within a trap context possible. It is guaranteed to function only when traps
+ * are not nested (i.e. for TL=1).
+ *
+ * Every trap handler on TL=1 that makes a call to the scheduler needs to
+ * be based on this function. The reason behind it is that the nested
+ * trap levels and the automatic saving of the interrupted context by hardware
+ * does not work well together with scheduling (i.e. a thread cannot be rescheduled
+ * with TL>0). Therefore it is necessary to eliminate the effect of trap levels
+ * by software and save the necessary state on the kernel stack.
+ *
+ * Note that for traps with TL>1, more state needs to be saved. This function
+ * is therefore not going to work when TL>1.
+ *
+ * The caller is responsible for doing SAVE and allocating
+ * PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE bytes on the stack.
  *
  * Input registers:
@@ -300,4 +311,9 @@
 	rdpr %pstate, %g4
 
+	/*
+	 * The following memory accesses will not fault
+	 * because special provisions are made to have
+	 * the kernel stack of THREAD locked in DTLB.
+	 */
 	stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE]
 	stx %g2, [%fp + STACK_BIAS + SAVED_TPC]
@@ -314,5 +330,5 @@
 	 * - switch to normal globals.
 	 */
-	and %g4, ~1, %g4		! mask alternate globals
+	and %g4, ~(PSTATE_AG_BIT|PSTATE_IG_BIT|PSTATE_MG_BIT), %g4
 	wrpr %g4, 0, %pstate
 	 
@@ -325,9 +341,10 @@
 	 * Call the higher-level handler.
 	 */
+	mov %fp, %o1				! calculate istate address
 	call %l0
-	nop
-	
-	/*
-	 * Restore the normal global register set.
+	add %o1, STACK_BIAS + SAVED_PSTATE, %o1	! calculate istate address
+	
+	/*
+	 * Restore	 the normal global register set.
 	 */
 	RESTORE_GLOBALS
@@ -335,5 +352,5 @@
 	/*
 	 * Restore PSTATE from saved copy.
-	 * Alternate globals become active.
+	 * Alternate/Interrupt/MM globals become active.
 	 */
 	ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4
@@ -358,8 +375,8 @@
 
 	/*
-	 * On execution of retry instruction, CWP will be restored from TSTATE register.
-	 * However, because of scheduling, it is possible that CWP in saved TSTATE
-	 * is different from current CWP. The following chunk of code fixes CWP
-	 * in the saved copy of TSTATE.
+	 * On execution of the RETRY instruction, CWP will be restored from the TSTATE
+	 * register. However, because of scheduling, it is possible that CWP in the saved
+	 * TSTATE is different from the current CWP. The following chunk of code fixes
+	 * CWP in the saved copy of TSTATE.
 	 */
 	rdpr %cwp, %g4		! read current CWP
Index: kernel/genarch/include/mm/as_ht.h
===================================================================
--- kernel/genarch/include/mm/as_ht.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/include/mm/as_ht.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -42,5 +42,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/include/mm/as_pt.h
===================================================================
--- kernel/genarch/include/mm/as_pt.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/include/mm/as_pt.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -42,5 +42,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/include/mm/page_ht.h
===================================================================
--- kernel/genarch/include/mm/page_ht.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/include/mm/page_ht.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,12 +27,10 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
-/** @file
- */
-
-/*
- * This is the generic page hash table interface.
+/**
+ * @file
+ * @brief	This is the generic page hash table interface.
  */
 
@@ -88,5 +86,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/include/mm/page_pt.h
===================================================================
--- kernel/genarch/include/mm/page_pt.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/include/mm/page_pt.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -117,5 +117,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/src/mm/as_ht.c
===================================================================
--- kernel/genarch/src/mm/as_ht.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/as_ht.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -119,5 +119,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/as_pt.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -140,5 +140,5 @@
 }
 
- /** @}
+/** @}
  */
 
Index: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/asid.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -175,5 +175,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/src/mm/asid_fifo.c
===================================================================
--- kernel/genarch/src/mm/asid_fifo.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/asid_fifo.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -95,5 +95,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/genarch/src/mm/page_ht.c
===================================================================
--- kernel/genarch/src/mm/page_ht.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/page_ht.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -245,5 +245,4 @@
 }
 
- /** @}
- */
-
+/** @}
+ */
Index: kernel/genarch/src/mm/page_pt.c
===================================================================
--- kernel/genarch/src/mm/page_pt.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/genarch/src/mm/page_pt.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genarchmm
+/** @addtogroup genarchmm
  * @{
  */
@@ -266,5 +266,4 @@
 }
 
- /** @}
- */
-
+/** @}
+ */
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/generic/include/mm/as.h	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup genericmm
+/** @addtogroup genericmm
  * @{
  */
@@ -207,5 +207,4 @@
 #endif
 
- /** @}
- */
-
+/** @}
+ */
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision ee289cf012d5ee670798a55abcda583a5b9988e4)
+++ kernel/generic/src/mm/as.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
@@ -544,5 +544,5 @@
 	if (!src_area->backend || !src_area->backend->share) {
 		/*
-		 * There is now backend or the backend does not
+		 * There is no backend or the backend does not
 		 * know how to share the area.
 		 */
