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>