changeset 3687:96d6b6ad3918

6244343 sun4v mmu code should support 16-bit context and correctly mask mmu fault addresses
author jb145095
date Tue, 20 Feb 2007 16:06:22 -0800
parents 5fd6740801a2
children bd23485682e4
files usr/src/uts/sfmmu/ml/sfmmu_asm.s usr/src/uts/sfmmu/vm/hat_sfmmu.c usr/src/uts/sfmmu/vm/hat_sfmmu.h usr/src/uts/sun4v/ml/trap_table.s usr/src/uts/sun4v/sys/mmu.h usr/src/uts/sun4v/vm/mach_sfmmu.h
diffstat 6 files changed, 136 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/sfmmu/ml/sfmmu_asm.s	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sfmmu/ml/sfmmu_asm.s	Tue Feb 20 16:06:22 2007 -0800
@@ -2114,7 +2114,7 @@
  *       the first zero mapping we find.
  *
  * Parameters:
- * tagacc	= tag access register (vaddr + ctx) (in)
+ * tagacc	= (pseudo-)tag access register (vaddr + ctx) (in)
  * tsbmiss	= address of tsb miss area (in)
  * ismseg	= contents of ism_seg for this ism map (out)
  * ismhat	= physical address of imap_ismhat for this ism map (out)
@@ -2163,7 +2163,7 @@
  * Returns the hme hash bucket (hmebp) given the vaddr, and the hatid
  * It also returns the virtual pg for vaddr (ie. vaddr << hmeshift)
  * Parameters:
- * vaddr = reg containing virtual address
+ * tagacc = reg containing virtual address
  * hatid = reg containing sfmmu pointer
  * hmeshift = constant/register to shift vaddr to obtain vapg
  * hmebp = register where bucket pointer will be stored
@@ -2268,7 +2268,7 @@
 /*
  * GET_TTE is a macro that returns a TTE given a tag and hatid.
  *
- * tagacc	= tag access register (vaddr + ctx) (in)
+ * tagacc	= (pseudo-)tag access register (in)
  * hatid	= sfmmu pointer for TSB miss (in)
  * tte		= tte for TLB miss if found, otherwise clobbered (out)
  * hmeblkpa	= PA of hment if found, otherwise clobbered (out)
@@ -2883,7 +2883,7 @@
 	 * The miss wasn't in an ISM segment.
 	 *
 	 * %g1 %g3, %g4, %g5, %g7 all clobbered
-	 * %g2 = tag access (vaddr + ctx)
+	 * %g2 = (pseudo) tag access
 	 */
 
 	ba,pt	%icc, 2f
@@ -3259,7 +3259,8 @@
 	 * This is an ISM [i|d]tlb miss.  We optimize for largest
 	 * page size down to smallest.
 	 *
-	 * g2 = vaddr + ctx	aka tag access register
+	 * g2 = vaddr + ctx(or ctxtype (sun4v)) aka (pseudo-)tag access
+	 *	register
 	 * g3 = ismmap->ism_seg
 	 * g4 = physical address of ismmap->ism_sfmmu
 	 * g6 = tsbmiss area
@@ -3271,12 +3272,12 @@
 	sub	%g4, (IMAP_ISMHAT - IMAP_VB_SHIFT), %g5
 	lduha	[%g5]ASI_MEM, %g4		/* g4 = imap_vb_shift */
 	srlx	%g3, %g4, %g3			/* clr size field */
-	set	TAGACC_CTX_MASK, %g1		/* mask off ctx number */
+	set	TAGACC_CTX_MASK, %g1		/* mask off ctx number/type */
 	sllx	%g3, %g4, %g3			/* g3 = ism vbase */
 	and	%g2, %g1, %g4			/* g4 = ctx number */
 	andn	%g2, %g1, %g1			/* g1 = tlb miss vaddr */
 	sub	%g1, %g3, %g2			/* g2 = offset in ISM seg */	
-	or	%g2, %g4, %g2			/* g2 = tagacc (vaddr + ctx) */
+	or	%g2, %g4, %g2			/* g2 = (pseudo-)tagacc */
 
 	/*
 	 * ISM pages are always locked down.
@@ -4402,7 +4403,7 @@
 	 * MMU fault area contains miss address and context.
 	 */
 	ALTENTRY(sfmmu_slow_dmmu_miss)
-	GET_MMU_D_TAGACC_CTX(%g2, %g3)	! %g2 = tagacc, %g3 = ctx 
+	GET_MMU_D_PTAGACC_CTXTYPE(%g2, %g3)	! %g2 = ptagacc, %g3 = ctx type
 
 slow_miss_common:
 	/*
@@ -4468,13 +4469,8 @@
 	 * MMU fault area contains miss address and context.
 	 */
 	ALTENTRY(sfmmu_slow_immu_miss)
-	MMU_FAULT_STATUS_AREA(%g2)
-	ldx	[%g2 + MMFSA_I_CTX], %g3
-	ldx	[%g2 + MMFSA_I_ADDR], %g2
-	srlx	%g2, MMU_PAGESHIFT, %g2	! align address to page boundry 	
-	sllx	%g2, MMU_PAGESHIFT, %g2
-	ba,pt	%xcc, slow_miss_common
-	or	%g2, %g3, %g2
+	GET_MMU_I_PTAGACC_CTXTYPE(%g2, %g3)
+	ba,a,pt	%xcc, slow_miss_common
 	SET_SIZE(sfmmu_slow_immu_miss)
 
 #endif /* sun4v */
--- a/usr/src/uts/sfmmu/vm/hat_sfmmu.c	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sfmmu/vm/hat_sfmmu.c	Tue Feb 20 16:06:22 2007 -0800
@@ -10601,7 +10601,7 @@
 sfmmu_tsbmiss_exception(struct regs *rp, uintptr_t tagaccess, uint_t traptype)
 {
 	sfmmu_t *sfmmup;
-	uint_t ctxnum;
+	uint_t ctxtype;
 	klwp_id_t lwp;
 	char lwp_save_state;
 	hatlock_t *hatlockp;
@@ -10610,9 +10610,13 @@
 	SFMMU_STAT(sf_tsb_exceptions);
 	SFMMU_MMU_STAT(mmu_tsb_exceptions);
 	sfmmup = astosfmmu(curthread->t_procp->p_as);
-	ctxnum = tagaccess & TAGACC_CTX_MASK;
-
-	ASSERT(sfmmup != ksfmmup && ctxnum != KCONTEXT);
+	/*
+	 * note that in sun4u, tagacces register contains ctxnum
+	 * while sun4v passes ctxtype in the tagaccess register.
+	 */
+	ctxtype = tagaccess & TAGACC_CTX_MASK;
+
+	ASSERT(sfmmup != ksfmmup && ctxtype != KCONTEXT);
 	ASSERT(sfmmup->sfmmu_ismhat == 0);
 	/*
 	 * First, make sure we come out of here with a valid ctx,
@@ -10629,9 +10633,9 @@
 	 * reader temporarily.
 	 */
 	ASSERT(!SFMMU_FLAGS_ISSET(sfmmup, HAT_SWAPPED) ||
-	    ctxnum == INVALID_CONTEXT);
-
-	if (ctxnum == INVALID_CONTEXT) {
+	    ctxtype == INVALID_CONTEXT);
+
+	if (ctxtype == INVALID_CONTEXT) {
 		/*
 		 * Must set lwp state to LWP_SYS before
 		 * trying to acquire any adaptive lock
--- a/usr/src/uts/sfmmu/vm/hat_sfmmu.h	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sfmmu/vm/hat_sfmmu.h	Tue Feb 20 16:06:22 2007 -0800
@@ -575,10 +575,18 @@
  * only context that needs to be locked is context 0 (the kernel
  * context), and context 1 (reserved for stolen context). So this constant
  * was originally defined to be 2.
+ *
+ * For sun4v only, USER_CONTEXT_TYPE represents any user context.  Many
+ * routines only care whether the context is kernel, invalid or user.
  */
+
 #define	NUM_LOCKED_CTXS 2
 #define	INVALID_CONTEXT	1
 
+#ifdef sun4v
+#define	USER_CONTEXT_TYPE	NUM_LOCKED_CTXS
+#endif
+
 #ifndef	_ASM
 
 /*
--- a/usr/src/uts/sun4v/ml/trap_table.s	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sun4v/ml/trap_table.s	Tue Feb 20 16:06:22 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -897,10 +897,6 @@
 	ba,a,pt	%xcc, .dmmu_exc_stdf_not_aligned			;\
 	.align	32
 
-#if TAGACC_CTX_MASK != CTXREG_CTX_MASK
-#error "TAGACC_CTX_MASK != CTXREG_CTX_MASK"
-#endif
-
 #if defined(cscope)
 /*
  * Define labels to direct cscope quickly to labels that
@@ -929,24 +925,20 @@
  */
 
 /*
- * synthesize for miss handler: TAG_ACCESS in %g2
+ * synthesize for miss handler: pseudo-tag access in %g2 (with context "type"
+ * (0=kernel, 1=invalid, or 2=user) rather than context ID)
  */
 #define	DTLB_MISS(table_name)						;\
 	.global	table_name/**/_dtlbmiss					;\
 table_name/**/_dtlbmiss:						;\
 	HAT_PERCPU_DBSTAT(TSBMISS_DTLBMISS) /* 3 instr ifdef DEBUG */	;\
-	MMU_FAULT_STATUS_AREA(%g7)					;\
-	ldx	[%g7 + MMFSA_D_ADDR], %g2	/* address */		;\
-	ldx	[%g7 + MMFSA_D_CTX], %g3	/* g3 = ctx */		;\
-	srlx	%g2, MMU_PAGESHIFT, %g2		/* align address */	;\
-	sllx	%g2, MMU_PAGESHIFT, %g2					;\
-	or	%g2, %g3, %g2			/* TAG_ACCESS */	;\
+	GET_MMU_D_PTAGACC_CTXTYPE(%g2, %g3)	/* 8 instr */		;\
 	cmp	%g3, INVALID_CONTEXT					;\
 	ble,pn	%xcc, sfmmu_kdtlb_miss					;\
 	  srlx	%g2, TAG_VALO_SHIFT, %g7	/* g7 = tsb tag */	;\
 	mov	SCRATCHPAD_UTSBREG2, %g1				;\
 	ldxa	[%g1]ASI_SCRATCHPAD, %g1	/* get 2nd tsbreg */	;\
-	brgez,pn %g1, sfmmu_udtlb_slowpath	/* brnach if 2 TSBs */	;\
+	brgez,pn %g1, sfmmu_udtlb_slowpath	/* branch if 2 TSBs */	;\
 	  nop								;\
 	GET_1ST_TSBE_PTR(%g2, %g1, %g4, %g5)	/* 11 instr */		;\
 	ba,pt	%xcc, sfmmu_udtlb_fastpath	/* no 4M TSB, miss */	;\
@@ -978,24 +970,20 @@
  */
 
 /*
- * synthesize for miss handler: TAG_ACCESS in %g2
+ * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type"
+ * (0=kernel, 1=invalid, or 2=user) rather than context ID)
  */
 #define	ITLB_MISS(table_name)						 \
 	.global	table_name/**/_itlbmiss					;\
 table_name/**/_itlbmiss:						;\
 	HAT_PERCPU_DBSTAT(TSBMISS_ITLBMISS) /* 3 instr ifdef DEBUG */	;\
-	MMU_FAULT_STATUS_AREA(%g7)					;\
-	ldx	[%g7 + MMFSA_I_ADDR], %g2	/* g2 = address */	;\
-	ldx	[%g7 + MMFSA_I_CTX], %g3	/* g3 = ctx */		;\
-	srlx	%g2, MMU_PAGESHIFT, %g2		/* align address */	;\
-	sllx	%g2, MMU_PAGESHIFT, %g2					;\
-	or	%g2, %g3, %g2			/* TAG_ACCESS */	;\
+	GET_MMU_I_PTAGACC_CTXTYPE(%g2, %g3)	/* 8 instr */		;\
 	cmp	%g3, INVALID_CONTEXT					;\
 	ble,pn	%xcc, sfmmu_kitlb_miss					;\
 	  srlx	%g2, TAG_VALO_SHIFT, %g7	/* g7 = tsb tag */	;\
 	mov	SCRATCHPAD_UTSBREG2, %g1				;\
 	ldxa	[%g1]ASI_SCRATCHPAD, %g1	/* get 2nd tsbreg */	;\
-	brgez,pn %g1, sfmmu_uitlb_slowpath	/* branch if 2 TSBS */	;\
+	brgez,pn %g1, sfmmu_uitlb_slowpath	/* branch if 2 TSBs */	;\
 	  nop								;\
 	GET_1ST_TSBE_PTR(%g2, %g1, %g4, %g5)	/* 11 instr */		;\
 	ba,pt	%xcc, sfmmu_uitlb_fastpath	/* no 4M TSB, miss */	;\
@@ -1015,18 +1003,14 @@
  * exactly 32 instructions.
  */
 /*
- * synthesize for miss handler: TAG_ACCESS in %g2
+ * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type"
+ * (0=kernel, 1=invalid, or 2=user) rather than context ID)
  */
 #define	DTLB_PROT							 \
-	MMU_FAULT_STATUS_AREA(%g7)					;\
-	ldx	[%g7 + MMFSA_D_ADDR], %g2	/* address */		;\
-	ldx	[%g7 + MMFSA_D_CTX], %g3	/* %g3 = ctx */		;\
-	srlx	%g2, MMU_PAGESHIFT, %g2		/* align address */	;\
-	sllx	%g2, MMU_PAGESHIFT, %g2					;\
-	or	%g2, %g3, %g2			/* TAG_ACCESS */	;\
+	GET_MMU_D_PTAGACC_CTXTYPE(%g2, %g3)	/* 8 instr */		;\
 	/*								;\
-	 *   g2 = tag access register					;\
-	 *   g3 = ctx number						;\
+	 *   g2 = pseudo-tag access register (ctx type rather than ctx ID) ;\
+	 *   g3 = ctx type (0, 1, or 2)					;\
 	 */								;\
 	TT_TRACE(trace_dataprot)	/* 2 instr ifdef TRAPTRACE */	;\
 					/* clobbers g1 and g6 XXXQ? */	;\
@@ -1399,7 +1383,8 @@
  * g7 = pc we jumped here from (in)
  */
 /*
- * synthesize for trap(): TAG_ACCESS in %g2
+ * synthesize for miss handler: TAG_ACCESS in %g2 (with context "type"
+ * (0=kernel, 1=invalid, or 2=user) rather than context ID)
  */
 	ALTENTRY(exec_fault)
 	TRACE_TSBHIT(TT_MMU_EXEC)
@@ -1407,7 +1392,9 @@
 	ldx	[%g4 + MMFSA_I_ADDR], %g2	/* g2 = address */
 	ldx	[%g4 + MMFSA_I_CTX], %g3	/* g3 = ctx */
 	srlx	%g2, MMU_PAGESHIFT, %g2		! align address to page boundry
+	cmp	%g3, USER_CONTEXT_TYPE
 	sllx	%g2, MMU_PAGESHIFT, %g2
+	movgu	%icc, USER_CONTEXT_TYPE, %g3
 	or	%g2, %g3, %g2			/* TAG_ACCESS */
 	mov	T_INSTR_MMU_MISS, %g3		! arg2 = traptype
 	set	trap, %g1
@@ -2481,7 +2468,9 @@
 	ldx	[%g7 + MMFSA_D_ADDR], %g6
 	ldx	[%g7 + MMFSA_D_CTX], %g7
 	srlx	%g6, MMU_PAGESHIFT, %g6		/* align address */
+	cmp	%g7, USER_CONTEXT_TYPE
 	sllx	%g6, MMU_PAGESHIFT, %g6
+	movgu	%icc, USER_CONTEXT_TYPE, %g7
 	or	%g6, %g7, %g6			/* TAG_ACCESS */
 1:
 	done
@@ -2642,8 +2631,6 @@
 	rdpr	%tnpc, %g6
 	stna	%g6, [%g5 + TRAP_ENT_F2]%asi
 	stna	%g1, [%g5 + TRAP_ENT_F3]%asi		! tsb8k pointer
-	srlx	%g1, 32, %g6
-	stna	%g6, [%g5 + TRAP_ENT_F4]%asi		! huh?
 	rdpr	%tpc, %g6
 	stna	%g6, [%g5 + TRAP_ENT_TPC]%asi
 	TRACE_SAVE_TL_GL_REGS(%g5, %g6)
@@ -2658,6 +2645,12 @@
 	MMU_FAULT_STATUS_AREA(%g6)
 	ldx	[%g6 + %g4], %g6
 	stxa	%g6, [%g5 + TRAP_ENT_TSTATE]%asi	! tag target
+	cmp	%g4, MMFSA_D_ADDR
+	move	%xcc, MMFSA_D_CTX, %g4
+	movne	%xcc, MMFSA_I_CTX, %g4
+	MMU_FAULT_STATUS_AREA(%g6)
+	ldx	[%g6 + %g4], %g6
+	stxa	%g6, [%g5 + TRAP_ENT_F4]%asi		! context ID
 	stna	%g3, [%g5 + TRAP_ENT_TR]%asi		! tsb4m pointer
 	TRACE_NEXT(%g5, %g4, %g6)
 	jmp	%g7 + 4
@@ -2665,7 +2658,7 @@
 
 /*
  * g2 = tag access register (in)
- * g3 = ctx number (in)
+ * g3 = ctx type (0, 1 or 2) (in) (not used)
  */
 trace_dataprot:
 	membar	#Sync
@@ -2679,7 +2672,6 @@
 	rdpr	%tstate, %g6
 	stxa	%g6, [%g1 + TRAP_ENT_TSTATE]%asi
 	stna	%g2, [%g1 + TRAP_ENT_SP]%asi		! tag access reg
-	stna	%g0, [%g1 + TRAP_ENT_TR]%asi
 	stna	%g0, [%g1 + TRAP_ENT_F1]%asi
 	stna	%g0, [%g1 + TRAP_ENT_F2]%asi
 	stna	%g0, [%g1 + TRAP_ENT_F3]%asi
@@ -2687,6 +2679,14 @@
 	TRACE_SAVE_TL_GL_REGS(%g1, %g6)
 	rdpr	%tt, %g6
 	stha	%g6, [%g1 + TRAP_ENT_TT]%asi
+	mov	MMFSA_D_CTX, %g4
+	cmp	%g6, FAST_IMMU_MISS_TT
+	move	%xcc, MMFSA_I_CTX, %g4
+	cmp	%g6, T_INSTR_MMU_MISS
+	move	%xcc, MMFSA_I_CTX, %g4
+	MMU_FAULT_STATUS_AREA(%g6)
+	ldx	[%g6 + %g4], %g6
+	stxa	%g6, [%g1 + TRAP_ENT_TR]%asi	! context ID
 	TRACE_NEXT(%g1, %g4, %g5)
 	jmp	%g7 + 4
 	nop
@@ -2746,12 +2746,14 @@
 	MMU_FAULT_STATUS_AREA(%g3)
 	ldx	[%g3 + MMFSA_D_ADDR], %g2
 	ldx	[%g3 + MMFSA_D_TYPE], %g1
-	ldx	[%g3 + MMFSA_D_CTX], %g3
+	ldx	[%g3 + MMFSA_D_CTX], %g4
 	srlx	%g2, MMU_PAGESHIFT, %g2		/* align address */
 	sllx	%g2, MMU_PAGESHIFT, %g2
-	or	%g2, %g3, %g2			/* TAG_ACCESS */
-	sllx	%g3, SFSR_CTX_SHIFT, %g3
+	sllx	%g4, SFSR_CTX_SHIFT, %g3
 	or	%g3, %g1, %g3			/* SFSR */
+	cmp	%g4, USER_CONTEXT_TYPE
+	movgeu	%icc, USER_CONTEXT_TYPE, %g4
+	or	%g2, %g4, %g2			/* TAG_ACCESS */
 	ba,pt	%xcc, .mmu_exception_end
 	mov	T_DATA_EXCEPTION, %g1
 	SET_SIZE(.dmmu_exception)
--- a/usr/src/uts/sun4v/sys/mmu.h	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sun4v/sys/mmu.h	Tue Feb 20 16:06:22 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -100,21 +100,30 @@
 /*
  * MMU TAG TARGET register Layout
  *
- * +-----+---------+------+-------------------------+
- * | 000 | context |  --  | virtual address [63:22] |
- * +-----+---------+------+-------------------------+
- *  63 61 60	 48 47	42 41			   0
+ * +---------------+------+-------------------------+
+ * |    context    |  --  | virtual address [63:22] |
+ * +---------------+------+-------------------------+
+ *  63           48 47  42 41                      0
+ *
+ * Some sun4v processors only use a 13-bit context ID, so bits 61-63 will be
+ * zero in that case.  This layout allows us to use the same code for any sun4v
+ * processors, whether they support 13 bit or 16 bit context IDs (or something
+ * in between).
  */
 #define	TTARGET_CTX_SHIFT	48
 #define	TTARGET_VA_SHIFT	22
 
 /*
- * MMU TAG ACCESS register Layout
+ * Pseudo MMU TAG ACCESS register Layout
  *
  * +-------------------------+------------------+
- * | virtual address [63:13] |  context [12:0]  |
+ * | virtual address [63:13] |     0     | type |
  * +-------------------------+------------------+
- *  63			  13	12		0
+ *  63			  13	12      2 1    0
+ *
+ * 16-bit context IDs don't fit into the 13 bit field as they did on sun4u,
+ * so we use a context type, 0 = kernel context, 1 = invalid context,
+ * 2 = user context.
  */
 #define	TAGACC_CTX_MASK		0x1FFF
 #define	TAGACC_SHIFT		13
@@ -124,7 +133,7 @@
 /*
  * MMU PRIMARY/SECONDARY CONTEXT register
  */
-#define	CTXREG_CTX_MASK		0x1FFF
+#define	CTXREG_CTX_MASK		0xFFFF
 
 /*
  * The kernel always runs in KCONTEXT, and no user mappings
--- a/usr/src/uts/sun4v/vm/mach_sfmmu.h	Tue Feb 20 14:08:22 2007 -0800
+++ b/usr/src/uts/sun4v/vm/mach_sfmmu.h	Tue Feb 20 16:06:22 2007 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -108,22 +107,25 @@
 	wrpr	%g0, val, %gl
 
 /*
- * Synthesize/get data tag access register value and context from the
- * MMU fault area
+ * Get pseudo-tagacc value and context from the MMU fault area.  Pseudo-tagacc
+ * is the faulting virtual address OR'd with 0 for KCONTEXT, INVALID_CONTEXT
+ * (1) for invalid context, and USER_CONTEXT (2) for user context.
  *
  * In:
- *   tagacc, ctx = scratch registers
+ *   tagacc, ctxtype = scratch registers
  * Out:
  *   tagacc = MMU data tag access register value
- *   ctx = context
+ *   ctx = context type (KCONTEXT, INVALID_CONTEXT or USER_CONTEXT)
  */
-#define	GET_MMU_D_TAGACC_CTX(tagacc, ctx)				\
-	MMU_FAULT_STATUS_AREA(ctx);					\
-	ldx	[ctx + MMFSA_D_ADDR], tagacc;				\
-	ldx	[ctx + MMFSA_D_CTX], ctx;				\
-	srlx	tagacc, MMU_PAGESHIFT, tagacc;	/* align to page boundry */ \
-	sllx	tagacc, MMU_PAGESHIFT, tagacc;				\
-	or	tagacc, ctx, tagacc
+#define	GET_MMU_D_PTAGACC_CTXTYPE(ptagacc, ctxtype)			\
+	MMU_FAULT_STATUS_AREA(ctxtype);					\
+	ldx	[ctxtype + MMFSA_D_ADDR], ptagacc;			\
+	ldx	[ctxtype + MMFSA_D_CTX], ctxtype;			\
+	srlx	ptagacc, MMU_PAGESHIFT, ptagacc; /* align to page boundary */ \
+	cmp	ctxtype, USER_CONTEXT_TYPE;				\
+	sllx	ptagacc, MMU_PAGESHIFT, ptagacc;			\
+	movgu	%icc, USER_CONTEXT_TYPE, ctxtype;			\
+	or	ptagacc, ctxtype, ptagacc
 
 /*
  * Synthesize/get data tag access register value from the MMU fault area
@@ -134,7 +136,7 @@
  *   tagacc = MMU data tag access register value
  */
 #define	GET_MMU_D_TAGACC(tagacc, scr1)				\
-	GET_MMU_D_TAGACC_CTX(tagacc, scr1)
+	GET_MMU_D_PTAGACC_CTXTYPE(tagacc, scr1)
 
 /*
  * Synthesize/get data tag target register value from the MMU fault area
@@ -153,26 +155,30 @@
 	or	ttarget, scr1, ttarget
 
 /*
- * Synthesize/get data/instruction tag access register values
- * from the MMU fault area.
+ * Synthesize/get data/instruction psuedo tag access register values
+ * from the MMU fault area (context is 0 for kernel, 1 for invalid, 2 for user)
  *
  * In:
  *   dtagacc, itagacc, scr1, scr2 = scratch registers
  * Out:
- *   dtagacc = MMU data tag access register value
- *   itagacc = MMU instruction tag access register value
+ *   dtagacc = MMU data tag access register value w/psuedo-context
+ *   itagacc = MMU instruction tag access register value w/pseudo-context
  */
 #define	GET_MMU_BOTH_TAGACC(dtagacc, itagacc, scr1, scr2)	\
 	MMU_FAULT_STATUS_AREA(scr1);				\
 	ldx	[scr1 + MMFSA_D_ADDR], scr2;			\
 	ldx	[scr1 + MMFSA_D_CTX], dtagacc;			\
-	srlx	scr2, MMU_PAGESHIFT, scr2;	/* align to page boundry */ \
+	srlx	scr2, MMU_PAGESHIFT, scr2;	/* align to page boundary */ \
+	cmp	dtagacc, USER_CONTEXT_TYPE;			\
 	sllx	scr2, MMU_PAGESHIFT, scr2;			\
+	movgu	%icc, USER_CONTEXT_TYPE, dtagacc;		\
 	or	scr2, dtagacc, dtagacc;				\
 	ldx	[scr1 + MMFSA_I_ADDR], scr2;			\
 	ldx	[scr1 + MMFSA_I_CTX], itagacc;			\
 	srlx	scr2, MMU_PAGESHIFT, scr2;	/* align to page boundry */ \
+	cmp	itagacc, USER_CONTEXT_TYPE;			\
 	sllx	scr2, MMU_PAGESHIFT, scr2;			\
+	movgu	%icc, USER_CONTEXT_TYPE, itagacc;		\
 	or	scr2, itagacc, itagacc
 
 /*
@@ -188,6 +194,27 @@
 	ldx	[scr1 + MMFSA_D_ADDR], daddr
 
 /*
+ * Get pseudo-tagacc value and context from the MMU fault area.  Pseudo-tagacc
+ * is the faulting virtual address OR'd with 0 for KCONTEXT, INVALID_CONTEXT
+ * (1) for invalid context, and USER_CONTEXT (2) for user context.
+ *
+ * In:
+ *   tagacc, ctxtype = scratch registers
+ * Out:
+ *   tagacc = MMU instruction tag access register value
+ *   ctxtype = context type (KCONTEXT, INVALID_CONTEXT or USER_CONTEXT)
+ */
+#define	GET_MMU_I_PTAGACC_CTXTYPE(ptagacc, ctxtype)			\
+	MMU_FAULT_STATUS_AREA(ctxtype);					\
+	ldx	[ctxtype + MMFSA_I_ADDR], ptagacc;			\
+	ldx	[ctxtype + MMFSA_I_CTX], ctxtype;			\
+	srlx	ptagacc, MMU_PAGESHIFT, ptagacc; /* align to page boundary */ \
+	cmp	ctxtype, USER_CONTEXT_TYPE;				\
+	sllx	ptagacc, MMU_PAGESHIFT, ptagacc;			\
+	movgu	%icc, USER_CONTEXT_TYPE, ctxtype;			\
+	or	ptagacc, ctxtype, ptagacc
+
+/*
  * Load ITLB entry
  *
  * In: