Index: kernel/arch/sparc64/include/trap/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/trap/interrupt.h	(revision beb3926abd13d8632e1c3093c0d2bef995372dee)
+++ kernel/arch/sparc64/include/trap/interrupt.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
@@ -85,8 +85,5 @@
 
 .macro INTERRUPT_VECTOR_TRAP_HANDLER
-	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
-	SIMPLE_HANDLER interrupt
-	restore
-	retry
+	PREEMPTIBLE_HANDLER interrupt
 .endm
 #endif /* __ASM__ */
Index: kernel/arch/sparc64/include/trap/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/mmu.h	(revision beb3926abd13d8632e1c3093c0d2bef995372dee)
+++ kernel/arch/sparc64/include/trap/mmu.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
@@ -35,6 +35,6 @@
  */
 
-#ifndef __sparc64_MMU_TRAP_H__
-#define __sparc64_MMU_TRAP_H__
+#ifndef KERN_sparc64_MMU_TRAP_H_
+#define KERN_sparc64_MMU_TRAP_H_
 
 #include <arch/stack.h>
@@ -52,9 +52,11 @@
 #ifdef __ASM__
 .macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
-	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
-	call fast_instruction_access_mmu_miss
-	nop
-	restore
-	retry	
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+	! TODO
+
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+	PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
 .endm
 
@@ -102,9 +104,6 @@
 
 .macro FAST_DATA_ACCESS_PROTECTION_HANDLER
-	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
-	call fast_data_access_protection
-	nop
-	restore
-	retry
+	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
+	PREEMPTIBLE_HANDLER fast_data_access_protection
 .endm
 #endif /* __ASM__ */
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision beb3926abd13d8632e1c3093c0d2bef995372dee)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
@@ -55,4 +55,5 @@
 static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
 static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str);
+static void do_fast_data_access_protection_fault(istate_t *istate, const char *str);
 
 char *context_encoding[] = {
@@ -246,5 +247,32 @@
 void fast_data_access_protection(int n, istate_t *istate)
 {
-	panic("%s\n", __FUNCTION__);
+	tlb_tag_access_reg_t tag;
+	uintptr_t va;
+	pte_t *t;
+
+	tag.value = dtlb_tag_access_read();
+	va = tag.vpn * PAGE_SIZE;
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, va);
+	if (t && PTE_WRITABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table and is writable.
+		 * Demap the old mapping and insert an updated mapping into DTLB.
+		 */
+		t->a = true;
+		t->d = true;
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, va);
+		dtlb_pte_copy(t, false);
+		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_WRITE, istate) == AS_PF_FAULT) {
+			do_fast_data_access_protection_fault(istate, __FUNCTION__);
+		}
+	}
 }
 
@@ -298,4 +326,18 @@
 }
 
+void do_fast_data_access_protection_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)
