Index: kernel/arch/sparc32/include/arch/stack.h
===================================================================
--- kernel/arch/sparc32/include/arch/stack.h	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc32/include/arch/stack.h	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -54,15 +54,4 @@
 #define STACK_ARG_SAVE_AREA_SIZE  (6 * STACK_ITEM_SIZE)
 
-/**
- * Offsets of arguments on stack.
- */
-#define STACK_ARG0  0
-#define STACK_ARG1  4
-#define STACK_ARG2  8
-#define STACK_ARG3  12
-#define STACK_ARG4  16
-#define STACK_ARG5  20
-#define STACK_ARG6  24
-
 #endif
 
Index: kernel/arch/sparc64/include/arch/istate_struct.ag
===================================================================
--- kernel/arch/sparc64/include/arch/istate_struct.ag	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/include/arch/istate_struct.ag	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -41,4 +41,98 @@
 
         members : [
+
+                #
+                # Window save area for locals and inputs. Required by ABI.
+                # Before using these, make sure that the corresponding register
+                # window has been spilled into memory, otherwise l0-l7 and
+                # i0-i7 will have undefined values.
+                #
+                {
+                        name : l0,
+                        type : uint64_t,
+                },
+                {
+                        name : l1,
+                        type : uint64_t,
+                },
+                {
+                        name : l2,
+                        type : uint64_t,
+                },
+                {
+                        name : l3,
+                        type : uint64_t,
+                },
+                {
+                        name : l4,
+                        type : uint64_t,
+                },
+                {
+                        name : l5,
+                        type : uint64_t,
+                },
+                {
+                        name : l6,
+                        type : uint64_t,
+                },
+                {
+                        name : l7,
+                        type : uint64_t,
+                },
+                {
+                        name : i0,
+                        type : uint64_t,
+                },
+                {
+                        name : i1,
+                        type : uint64_t,
+                },
+                {
+                        name : i2,
+                        type : uint64_t,
+                },
+                {
+                        name : i3,
+                        type : uint64_t,
+                },
+                {
+                        name : i4,
+                        type : uint64_t,
+                },
+                {
+                        name : i5,
+                        type : uint64_t,
+                },
+                {
+                        name : i6,
+                        type : uint64_t,
+                },
+                {
+                        name : i7,
+                        type : uint64_t,
+                },
+
+                #
+                # Six mandatory argument slots, required by the ABI, plus an
+                # optional argument slot for the 7th argument used by our
+                # syscalls. Since the preemptible handler is always passing
+                # integral arguments, undef_arg[0] - undef_arg[5] are always
+                # undefined.
+                #
+                {
+                        name : undef_arg,
+                        type : uint64_t,
+                        elements : 6,
+                },
+                {
+                        name : arg6,
+                        type : uint64_t,
+                },
+
+                #
+                # From this point onwards, the istate layout is not dicated by
+                # the ABI. The only requirement is the stack alignment.
+                #
+
                 {
                         name : tnpc,
@@ -51,4 +145,53 @@
                 {
                         name : tstate,
+                        type : uint64_t
+                },
+                {
+                        name : y,
+                        type : uint64_t,
+                },
+
+                #
+                # At the moment, these are defined only when needed by the
+                # preemptible handler, so consider them undefined for now.
+                #
+                {
+                        name : o0,
+                        type : uint64_t,
+                },
+                {
+                        name : o1,
+                        type : uint64_t,
+                },
+                {
+                        name : o2,
+                        type : uint64_t,
+                },
+                {
+                        name : o3,
+                        type : uint64_t,
+                },
+                {
+                        name : o4,
+                        type : uint64_t,
+                },
+                {
+                        name : o5,
+                        type : uint64_t,
+                },
+                {
+                        name : o6,
+                        type : uint64_t,
+                },
+                {
+                        name : o7,
+                        type : uint64_t,
+                },
+
+                #
+                # I/DTLB Tag Access register or zero for non-MMU traps.
+                #
+                {
+                        name : tlb_tag_access,
                         type : uint64_t
                 }
Index: kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -678,7 +678,7 @@
 }
 
-extern void fast_instruction_access_mmu_miss(sysarg_t, istate_t *);
-extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
-extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
+extern void fast_instruction_access_mmu_miss(unsigned int, istate_t *);
+extern void fast_data_access_mmu_miss(unsigned int, istate_t *);
+extern void fast_data_access_protection(unsigned int, istate_t *);
 
 extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
Index: kernel/arch/sparc64/include/arch/trap/sun4u/mmu.h
===================================================================
--- kernel/arch/sparc64/include/arch/trap/sun4u/mmu.h	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/include/arch/trap/sun4u/mmu.h	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -74,5 +74,8 @@
 0:
 	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
-	PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
+	mov TT_FAST_INSTRUCTION_ACCESS_MMU_MISS, %g2
+	mov VA_IMMU_TAG_ACCESS, %g5
+	ldxa [%g5] ASI_IMMU, %g5			! read the faulting Context and VPN
+	PREEMPTIBLE_HANDLER exc_dispatch 
 .endm
 
@@ -107,5 +110,5 @@
 	wr %g0, ASI_DMMU, %asi
 	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1		! read the faulting Context and VPN
-	set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
+	ldx [%g7 + %lo(tlb_tag_access_context_mask)], %g2
 	andcc %g1, %g2, %g3				! get Context
 	bnz %xcc, 0f					! Context is non-zero
@@ -138,14 +141,7 @@
 	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
-	/*
-	 * Read the Tag Access register for the higher-level handler.
-	 * This is necessary to survive nested DTLB misses.
-	 */	
-	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
-
-	/*
-	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
-	 */
-	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
+	mov TT_FAST_DATA_ACCESS_MMU_MISS, %g2
+	ldxa [VA_DMMU_TAG_ACCESS] %asi, %g5		! read the faulting Context and VPN
+	PREEMPTIBLE_HANDLER exc_dispatch 
 .endm
 
@@ -164,15 +160,8 @@
 	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
-	/*
-	 * Read the Tag Access register for the higher-level handler.
-	 * This is necessary to survive nested DTLB misses.
-	 */	
-	mov VA_DMMU_TAG_ACCESS, %g2
-	ldxa [%g2] ASI_DMMU, %g2
-
-	/*
-	 * g2 will be passed as an argument to fast_data_access_mmu_miss().
-	 */
-	PREEMPTIBLE_HANDLER fast_data_access_protection
+	mov TT_FAST_DATA_ACCESS_PROTECTION, %g2
+	mov VA_DMMU_TAG_ACCESS, %g5
+	ldxa [%g5] ASI_DMMU, %g5			! read the faulting Context and VPN
+	PREEMPTIBLE_HANDLER exc_dispatch 
 .endm
 
Index: kernel/arch/sparc64/include/arch/trap/trap_table.h
===================================================================
--- kernel/arch/sparc64/include/arch/trap/trap_table.h	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/include/arch/trap/trap_table.h	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -43,29 +43,4 @@
 #define TRAP_TABLE_SIZE		(TRAP_TABLE_ENTRY_COUNT * TRAP_TABLE_ENTRY_SIZE)
 
-#define ISTATE_END_OFFSET(o)	((o) - ISTATE_SIZE)
-
-/*
- * The one STACK_ITEM_SIZE is counted for space holding the 7th
- * argument to syscall_handler (i.e. syscall number) and the other
- * STACK_ITEM_SIZE is counted because of the required alignment.
- */
-#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE \
-    (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE + \
-    (2 * STACK_ITEM_SIZE) + (ISTATE_SIZE + 9 * 8))
-/* <-- istate_t ends here */
-#define SAVED_TSTATE	ISTATE_END_OFFSET(ISTATE_OFFSET_TSTATE)	
-#define SAVED_TPC	ISTATE_END_OFFSET(ISTATE_OFFSET_TPC)
-#define SAVED_TNPC	ISTATE_END_OFFSET(ISTATE_OFFSET_TNPC)
-/* <-- istate_t begins here */
-#define SAVED_Y		-(1 * 8 + ISTATE_SIZE)
-#define SAVED_I0	-(2 * 8 + ISTATE_SIZE)
-#define SAVED_I1	-(3 * 8 + ISTATE_SIZE)
-#define SAVED_I2	-(4 * 8 + ISTATE_SIZE)
-#define SAVED_I3	-(5 * 8 + ISTATE_SIZE)
-#define SAVED_I4	-(6 * 8 + ISTATE_SIZE)
-#define SAVED_I5	-(7 * 8 + ISTATE_SIZE)
-#define SAVED_I6	-(8 * 8 + ISTATE_SIZE)
-#define SAVED_I7	-(9 * 8 + ISTATE_SIZE)
-
 #ifndef __ASM__
 
@@ -80,4 +55,5 @@
 extern trap_table_entry_t trap_table[TRAP_TABLE_ENTRY_COUNT];
 extern trap_table_entry_t trap_table_save[TRAP_TABLE_ENTRY_COUNT];
+
 #endif /* !__ASM__ */
 
Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -42,4 +42,6 @@
 #include <arch/trap/trap_table.h>
 
+#include <arch/istate_struct.h>
+
 #if defined(SUN4V)
 #include <arch/sun4v/arch.h>
@@ -62,5 +64,5 @@
 
 	kstack += STACK_BIAS;
-	kstack -= PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE;
+	kstack -= ISTATE_SIZE;
 
 	if (THREAD && (ctx->fp == kstack))
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -194,5 +194,5 @@
 
 /** ITLB miss handler. */
-void fast_instruction_access_mmu_miss(sysarg_t unused, istate_t *istate)
+void fast_instruction_access_mmu_miss(unsigned int tt, istate_t *istate)
 {
 	size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
@@ -224,12 +224,10 @@
  * low-level, assembly language part of the fast_data_access_mmu_miss handler.
  *
- * @param tag		Content of the TLB Tag Access register as it existed
- * 			when the trap happened. This is to prevent confusion
- * 			created by clobbered Tag Access register during a nested
- * 			DTLB miss.
+ * @param tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
-{
+void fast_data_access_mmu_miss(unsigned int tt, istate_t *istate)
+{
+	tlb_tag_access_reg_t tag;
 	uintptr_t page_8k;
 	uintptr_t page_16k;
@@ -238,4 +236,5 @@
 	as_t *as = AS;
 
+	tag.value = istate->tlb_tag_access;
 	page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
 	page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
@@ -276,12 +275,10 @@
 /** DTLB protection fault handler.
  *
- * @param tag		Content of the TLB Tag Access register as it existed
- * 			when the trap happened. This is to prevent confusion
- * 			created by clobbered Tag Access register during a nested
- * 			DTLB miss.
+ * @param tt		Trap type.
  * @param istate	Interrupted state saved on the stack.
  */
-void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
-{
+void fast_data_access_protection(unsigned int tt, istate_t *istate)
+{
+	tlb_tag_access_reg_t tag;
 	uintptr_t page_16k;
 	size_t index;
@@ -289,4 +286,5 @@
 	as_t *as = AS;
 
+	tag.value = istate->tlb_tag_access;
 	page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
 	index = tag.vpn % MMU_PAGES_PER_PAGE;	/* 16K-page emulation */
Index: kernel/arch/sparc64/src/sun4u/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/start.S	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/src/sun4u/start.S	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -401,13 +401,14 @@
 
 /*
- * The fast_data_access_mmu_miss_data_hi label and the end_of_identity and
- * kernel_8k_tlb_data_template variables are meant to stay together,
- * aligned on 16B boundary.
+ * The fast_data_access_mmu_miss_data_hi label, the end_of_identity,
+ * kernel_8k_tlb_data_template and tlb_tag_access_context_mask variables
+ * are meant to stay together, aligned on a 32B boundary.
  */
 .global fast_data_access_mmu_miss_data_hi
 .global end_of_identity 
 .global kernel_8k_tlb_data_template
-
-.align 16
+.global tlb_tag_access_context_mask
+
+.align 32 
 /*
  * This label is used by the fast_data_access_MMU_miss trap handler.
@@ -435,2 +436,9 @@
 #endif /* CONFIG_VIRT_IDX_DCACHE */
 
+/*
+ * This variable is used by the fast_data_access_MMU_miss trap handler.
+ * It allows us to save one precious instruction slot of this handler.
+ */
+tlb_tag_access_context_mask:
+	.quad TLB_TAG_ACCESS_CONTEXT_MASK
+
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -37,4 +37,5 @@
 #include <arch/trap/interrupt.h>
 #include <arch/trap/exception.h>
+#include <arch/trap/mmu.h>
 #include <arch/sparc64.h>
 #include <interrupt.h>
@@ -120,5 +121,14 @@
 	    interrupt);
 #endif
-	
+
+	exc_register(TT_FAST_INSTRUCTION_ACCESS_MMU_MISS,
+	    "fast_instruction_access_mmu_miss", true,
+	    fast_instruction_access_mmu_miss);
+	exc_register(TT_FAST_DATA_ACCESS_MMU_MISS,
+	    "fast_data_access_mmu_miss", true,
+	    fast_data_access_mmu_miss);
+	exc_register(TT_FAST_DATA_ACCESS_PROTECTION,
+	    "fast_data_access_protection", true,
+	    fast_data_access_protection);	
 }
 
Index: kernel/arch/sparc64/src/trap/sun4u/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision ec443d53cc8411f6b71e18809a8bf0563e29e90a)
+++ kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision d70ebffee4c682353339148a2a7591029a0ed40c)
@@ -64,4 +64,5 @@
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
 	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -71,4 +72,5 @@
 instruction_access_error_tl0:
 	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -78,4 +80,5 @@
 illegal_instruction_tl0:
 	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -85,4 +88,5 @@
 privileged_opcode_tl0:
 	mov TT_PRIVILEGED_OPCODE, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -92,4 +96,5 @@
 unimplemented_LDD_tl0:
 	mov TT_UNIMPLEMENTED_LDD, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -99,4 +104,5 @@
 unimplemented_STD_tl0:
 	mov TT_UNIMPLEMENTED_STD, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -106,4 +112,5 @@
 fp_disabled_tl0:
 	mov TT_FP_DISABLED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -113,4 +120,5 @@
 fp_exception_ieee_754_tl0:
 	mov TT_FP_EXCEPTION_IEEE_754, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -120,4 +128,5 @@
 fp_exception_other_tl0:
 	mov TT_FP_EXCEPTION_OTHER, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -127,4 +136,5 @@
 tag_overflow_tl0:
 	mov TT_TAG_OVERFLOW, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -140,4 +150,5 @@
 division_by_zero_tl0:
 	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -148,4 +159,5 @@
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
 	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -155,4 +167,5 @@
 data_access_error_tl0:
 	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -162,4 +175,5 @@
 mem_address_not_aligned_tl0:
 	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -169,4 +183,5 @@
 LDDF_mem_address_not_aligned_tl0:
 	mov TT_LDDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -176,4 +191,5 @@
 STDF_mem_address_not_aligned_tl0:
 	mov TT_STDF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -183,4 +199,5 @@
 privileged_action_tl0:
 	mov TT_PRIVILEGED_ACTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -190,4 +207,5 @@
 LDQF_mem_address_not_aligned_tl0:
 	mov TT_LDQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -197,4 +215,5 @@
 STQF_mem_address_not_aligned_tl0:
 	mov TT_STQF_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -204,4 +223,5 @@
 interrupt_level_1_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_1, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -211,4 +231,5 @@
 interrupt_level_2_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_2, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -218,4 +239,5 @@
 interrupt_level_3_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_3, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -225,4 +247,5 @@
 interrupt_level_4_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_4, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -232,4 +255,5 @@
 interrupt_level_5_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_5, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -239,4 +263,5 @@
 interrupt_level_6_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_6, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -246,4 +271,5 @@
 interrupt_level_7_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_7, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -253,4 +279,5 @@
 interrupt_level_8_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_8, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -260,4 +287,5 @@
 interrupt_level_9_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_9, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -267,4 +295,5 @@
 interrupt_level_10_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_10, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -274,4 +303,5 @@
 interrupt_level_11_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_11, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -281,4 +311,5 @@
 interrupt_level_12_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_12, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -288,4 +319,5 @@
 interrupt_level_13_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_13, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -295,4 +327,5 @@
 interrupt_level_14_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_14, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -302,4 +335,5 @@
 interrupt_level_15_handler_tl0:
 	mov TT_INTERRUPT_LEVEL_15, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -309,4 +343,5 @@
 interrupt_vector_trap_handler_tl0:
 	mov TT_INTERRUPT_VECTOR_TRAP, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -377,6 +412,7 @@
 .global trap_instruction_\cur\()_tl0
 trap_instruction_\cur\()_tl0:
+	mov \cur, %g2
 	ba %xcc, trap_instruction_handler
-	mov \cur, %g2
+	clr %g5
 .endr
 
@@ -392,4 +428,5 @@
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
 	mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch 
 
@@ -400,4 +437,5 @@
 	wrpr %g0, 1, %tl
 	mov TT_INSTRUCTION_ACCESS_ERROR, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -408,4 +446,5 @@
 	wrpr %g0, 1, %tl
 	mov TT_ILLEGAL_INSTRUCTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -422,4 +461,5 @@
 	wrpr %g0, 1, %tl
 	mov TT_DIVISION_BY_ZERO, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -431,4 +471,5 @@
 	wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
 	mov TT_DATA_ACCESS_EXCEPTION, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -439,4 +480,5 @@
 	wrpr %g0, 1, %tl
 	mov TT_DATA_ACCESS_ERROR, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -447,4 +489,5 @@
 	wrpr %g0, 1, %tl
 	mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
+	clr %g5
 	PREEMPTIBLE_HANDLER exc_dispatch
 
@@ -512,19 +555,9 @@
  *	%g1		Address of function to call if this is not a syscall.
  * 	%g2	 	First argument for the function.
+ *	%g5		I/DTLB_TAG_ACCESS register if applicable.
  *	%g6		Pre-set as kernel stack base if trap from userspace.
  *	%g7		Pre-set as address of the userspace window buffer.
  */
 .macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
-	/*
-	 * ASSERT(%tl == 1)
-	 */
-	rdpr %tl, %g3
-	cmp %g3, 1
-	be %xcc, 1f
-	nop
-	! this is for debugging, if we ever get here it will be easy to find
-0:	ba,a %xcc, 0b
-
-1:
 .if NOT(\is_syscall)
 	rdpr %tstate, %g3
@@ -544,6 +577,6 @@
 	bnz %xcc, 0f				! ...skip setting of kernel stack and primary context
 	nop
-	
 .endif
+
 	/*
 	 * Normal window spills will go to the userspace window buffer.
@@ -558,5 +591,5 @@
 	 * and the new window's %fp.
 	 */
-	save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %g6, -ISTATE_SIZE, %sp
 
 .if \is_syscall
@@ -590,5 +623,5 @@
 	ba,a %xcc, 1f
 0:
-	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
+	save %sp, -ISTATE_SIZE, %sp
 
 	/*
@@ -612,9 +645,9 @@
 .else
 	! store the syscall number on the stack as 7th argument
-	stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6] 
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_ARG6] 
 .endif
 
 	/*
-	 * Save TSTATE, TPC and TNPC aside.
+	 * Save TSTATE, TPC, TNPC and I/DTLB_TAG_ACCESS aside.
 	 */
 	rdpr %tstate, %g1
@@ -623,16 +656,13 @@
 	rd %y, %g4
 
-	stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
-	stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
-	stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
+	stx %g1, [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE]
+	stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_TPC]
+	stx %g3, [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC]
+	stx %g5, [%sp + STACK_BIAS + ISTATE_OFFSET_TLB_TAG_ACCESS]
 
 	/*
 	 * Save the Y register.
-	 * This register is deprecated according to SPARC V9 specification
-	 * and is only present for backward compatibility with previous
-	 * versions of the SPARC architecture.
-	 * Surprisingly, gcc makes use of this register without a notice.
-	 */
-	stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
+	 */
+	stx %g4, [%sp + STACK_BIAS + ISTATE_OFFSET_Y]
 	
 	wrpr %g0, 0, %tl
@@ -645,5 +675,5 @@
 	 */
 	call %l0
-	add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
+	add %sp, STACK_BIAS, %o1
 .else
 	/*
@@ -663,7 +693,7 @@
 	 * Read TSTATE, TPC and TNPC from saved copy.
 	 */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE], %g1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TPC], %g2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC], %g3
 
 	/*
@@ -686,5 +716,5 @@
 	 * Restore Y.
 	 */
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_Y], %g4
 	wr %g4, %y
 
@@ -726,22 +756,22 @@
 	 */
 	mov %sp, %g2
-	stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
-	stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
-	stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
-	stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
-	stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
-	stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
-	stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
-	stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
+	stx %i0, [%sp + STACK_BIAS + ISTATE_OFFSET_O0]
+	stx %i1, [%sp + STACK_BIAS + ISTATE_OFFSET_O1]
+	stx %i2, [%sp + STACK_BIAS + ISTATE_OFFSET_O2]
+	stx %i3, [%sp + STACK_BIAS + ISTATE_OFFSET_O3]
+	stx %i4, [%sp + STACK_BIAS + ISTATE_OFFSET_O4]
+	stx %i5, [%sp + STACK_BIAS + ISTATE_OFFSET_O5]
+	stx %i6, [%sp + STACK_BIAS + ISTATE_OFFSET_O6]
+	stx %i7, [%sp + STACK_BIAS + ISTATE_OFFSET_O7]
 	wrpr %l0, 0, %cwp
 	mov %g2, %sp
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
-	ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O0], %i0
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O1], %i1
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O2], %i2
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O3], %i3
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O4], %i4
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O5], %i5
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O6], %i6
+	ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O7], %i7
 
 	/*
