PERFORCE change 29400 for review
Marcel Moolenaar
marcel at FreeBSD.org
Tue Apr 22 01:46:07 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=29400
Change 29400 by marcel at 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)
More information about the p4-projects
mailing list