Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Apr 2003 01:46:04 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 29400 for review
Message-ID:  <200304220846.h3M8k41u035759@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=29400

Change 29400 by marcel@marcel_nfs on 2003/04/22 01:45:08

	Improve handling of nested TLB faults:
	o  Make sure interrupts are disabled to avoid being interrupted
	   while constructing the trapframe. We may loose our TLB entry
	   when that happens and thus have nested TLB faults when we
	   cannot deal with it.
	o  Add a seatbelt: we put a magic value in r22 prior to crossing
	   the restart point. This register is checked by the nested TLB
	   handler and if it contains the magic value, we branch back to
	   the restart point. Otherwise we hit a breakpoint. This way we
	   can better diagnose problems caused by double nested TLB faults.
	o  Do not disable interrupt collection too early when we restore
	   from a trapframe, because that can cause a nested TLB fault.
	   Delay disabling interrupt collection until after we've loaded
	   everything from the trapframe in registers, but prior to
	   moving the values to their actual destination.
	o  Use physical addressing in the nested TLB handler. We only
	   have to deal with region 7 addresses, which are direct mapped
	   virtual addresses, so we don't have any problems constructing
	   the physical addresses. The prime advantage is that we're now
	   unaffected by missing TLB entries for the page table pages
	   themselves.
	o  Do not use a translation cache entry when we insert a mapping
	   in the nested TLB handler. Use a translation register. This
	   avoids getting caught in a TLB miss storm caused by TC purges
	   for the "wrong" translations. This causes us to overflow our
	   kernel stack and thus crash and burn. Translation registers
	   do not affect translation caches, which means that the chance
	   of a chain reaction is very small, of not zero. We run
	   multi-user with as little as 16 translation cache entries
	   this way.

Affected files ...

.. //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#16 edit

Differences ...

==== //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#16 (text+ko) ====

@@ -80,6 +80,13 @@
 	sub		r19=r31,sp
 	;;
 }
+{	.mmi
+	rsm		psr.i
+	;;
+	srlz.d
+	mov		r22=ip
+	;;
+}
 
 	/*
 	 * We have a 1KB aligned trapframe, pointed to by sp. If we write
@@ -91,7 +98,7 @@
 	 * have to be careful what we use here. The registers that must
 	 * not be clobbered by the data nested TLB fault handler on top
 	 * of any interrupted state we haven't saved yet (ie almost all
-	 * of it) are: p14, p15, sp and r16-r21.
+	 * of it) are: p14, p15, sp and r16-r22.
 	 */
 exception_save_restart:
 {	.mmi
@@ -354,7 +361,7 @@
 	 * been flushed.
 	 */
 {	.mmi
-	rsm		psr.ic|psr.i
+	rsm		psr.i
 	;;
 	srlz.d
 	add		sp=16,sp
@@ -528,6 +535,12 @@
 
 1:
 {	.mmi
+	rsm		psr.ic
+	;;
+	srlz.d
+	nop		0
+}
+{	.mmi
 	mov		ar.unat=r17
 	mov		cr.iip=r27
 	mov		ar.pfs=r19
@@ -813,61 +826,86 @@
 
 IVT_ENTRY(Data_Nested_TLB, 0x1400)
 	// See exception_save. Things get tricky here. Don't use p14, p15,
-	// sp and r16-r21.
+	// sp and r16-r22. We use physical addressing to avoid double
+	// nested faults. Since all virtual addresses we encounter here
+	// are direct mapped region 7 addresses, we will have no problem
+	// constructing physical addresses.
 {	.mlx
-	mov		r22=cr.ifa
-	movl		r24=ia64_kptdir
+	mov		r23=cr.ifa
+	movl		r25=ia64_kptdir
+	;;
+}
+{	.mii
+	mov		r24=cr.itir
+	dep		r25=0,r25,61,3
+	extr.u		r26=sp,PAGE_SHIFT,61-PAGE_SHIFT
+	;;
+}
+{	.mii
+	rsm		psr.dt
+	shr.u		r27=r26,PAGE_SHIFT-5	// dir index
+	extr.u		r28=r26,0,PAGE_SHIFT-5	// pte index
 	;;
 }
 {	.mmi
-	mov		r23=cr.itir
-	ld8		r24=[r24]
-	extr.u		r25=sp,PAGE_SHIFT,61-PAGE_SHIFT
+	srlz.d
+	ld8		r25=[r25]
+	shl		r28=r28,5
 	;;
 }
-{	.mii
+{	.mmi
 	mov		cr.ifa=sp
-	shr.u		r26=r25,PAGE_SHIFT-5	// dir index
-	extr.u		r27=r25,0,PAGE_SHIFT-5	// pte index
+	shladd		r25=r27,3,r25
+	add		r22=16,r22
 	;;
 }
-{	.mmi
-	shladd		r24=r26,3,r24
+{	.mii
+	mov		r27=rr[sp]
+	dep		r25=0,r25,61,3
 	;;
-	ld8		r24=[r24]
-	shl		r27=r27,5
+	dep		r27=0,r27,0,2
+}
+{	.mlx
+	ld8		r25=[r25]
+	movl		r29=exception_save_restart
 	;;
 }
-{	.mmi
-	add		r24=r24,r27		// address of pte
+{	.mii
+	mov		cr.itir=r27
+	add		r25=r25,r28		// address of pte
 	;;
-	ld8		r25=[r24]
-	extr.u		r26=sp,61,3
+	dep		r25=0,r25,61,3
 	;;
 }
 {	.mmi
-	mov		r26=rr[r26]
+	ld8		r26=[r25]
 	;;
-	or		r25=PTE_D|PTE_A,r25
-	dep		r26=0,r26,0,2
+	or		r26=PTE_D|PTE_A,r26
+	cmp.eq		p13,p0=r22,r29		// exception_save triggered?
 	;;
 }
 {	.mmi
-	st8		[r24]=r25
-	mov		cr.itir=r26
-	nop		0
+	st8		[r25]=r26
 	;;
+	ssm		psr.dt
+	mov		r28=4
 }
 {	.mmi
-	itc.d		r25
+	itr.d		dtr[r28]=r26
 	;;
 	srlz.d
 	nop		0
 }
 {	.mmb
-	mov		cr.ifa=r22
-	mov		cr.itir=r23
-	br.sptk		exception_save_restart
+	mov		cr.ifa=r23
+	mov		cr.itir=r24
+(p13)	br.sptk		exception_save_restart
+	;;
+}
+{	.mfb
+	break		0x80100
+	break		0x80100
+	break		0x80100
 	;;
 }
 IVT_END(Data_Nested_TLB)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304220846.h3M8k41u035759>