Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Oct 2014 08:23:23 -0700
From:      Nathan Whitehorn <nwhitehorn@freebsd.org>
To:        Mark Millard <markmi@dsl-only.net>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>
Cc:        Justin Hibbits <chmeeedalf@gmail.com>
Subject:   Re: powerpc64/GENERIC64: s_trap vs. realtrap, why does realtrap possibly execute restore_kernsrs twice in a row overall?
Message-ID:  <5437F9EB.3050302@freebsd.org>
In-Reply-To: <511C0B85-173F-4863-ACA5-0274C381E005@dsl-only.net>
References:  <511C0B85-173F-4863-ACA5-0274C381E005@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
How does this end up being called twice? k_trap does not return (note no 
"l" in the branch instruction). They are separated, by the way, due to 
some slightly different logic for handling faults that need to end up in 
the kernel debugger.
-Nathan

On 10/10/14 08:04, Mark Millard wrote:
> Based on 10.1-RC1 sources but probably long true..
>
> s_trap in /usr/src/sys/powerpc/aim/trap_subr64.S starts with the following sequence of 8 lines of source immediately after the s_trap label (ignoring the unused u_trap label line, not shown below):
>
> s_trap:
>          bf      17,k_trap               /* branch if PSL_PR is false */
>          GET_CPUINFO(%r1)
>          ld      %r1,PC_CURPCB(%r1)
>          mr      %r27,%r28               /* Save LR, r29 */
>          mtsprg2 %r29
>          bl      restore_kernsrs         /* enable kernel mapping */
>          mfsprg2 %r29
>          mr      %r28,%r27
>
>
> realtrap also has that exact instruction sequence starting a few instructions down in its code --but immeadiately followed by a branch to s_strap that ends up reexecuting that same instruction sequence (but in/at s_trap), presuming that the original "bd 17,k_trap" in realtrap is not taken:
>
> realtrap:
> /* Test whether we already had PR set */
>          mfsrr1  %r1
>          mtcr    %r1
>          mfsprg1 %r1                     /* restore SP (might have been
>                                             overwritten) */
>          bf      17,k_trap               /* branch if PSL_PR is false */
>          GET_CPUINFO(%r1)
>          ld      %r1,PC_CURPCB(%r1)
>          mr      %r27,%r28               /* Save LR, r29 */
>          mtsprg2 %r29
>          bl      restore_kernsrs         /* enable kernel mapping */
>          mfsprg2 %r29
>          mr      %r28,%r27
>          ba s_trap
>
> Why would this code for possibly calling restore_kernsrs possibly be executed twice back-to-back for realtrap's execution overall? Is this deliberate for some reason? Could the realtrap code validly avoid the doubled activity when it does not immediately jump to k_trap?
>
> Note that if it was possible for s_trap to take the "bf 17,k_trap" branch after realtrap did its "ba s_trap" then %r1 for that s_trap use would not have the stack pointer in it for k_trap's potential use (e.g., in its use of FRAME_SETUP). restore_kernsrs does not touch %r1 and k_trap takes %r1 as-is for use as a stack pointer in FRAME_SETUP. Luckily it appears that s_trap would not take that branch in this context.
>
> But if that last is true that means that s_trap's code definitely always does call restore_kernsrs a second time when used from realtrap. Wasteful?
>
>
> [And for realtrap it would seem that the "mfsrr1 %r1" definitely "might have" overwritten %r1 (a.k.a. the Stack Pointer): The "might have" comment seems a little odd. It is more like the SP would be needed in the branch to k_trap case and so had to be put back in %r1 to cover that.]
>
>
>
>
>
>
> ===
> Mark Millard
> markmi at dsl-only.net
>
>




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