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

next in thread | previous in thread | raw e-mail | index | archive | help
On Oct 10, 2014, at 8:23 AM, Nathan Whitehorn <nwhitehorn@freebsd.org> =
wrote:

> 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.

If I read the above right you have answered for when "bf 17,k_trap" is =
taken in realtrap and so realtrap's "ba s_strap" is not even executed. =
But I specified that my worry was for when "presuming that the original =
'bd 17,k_trap' in realtrap is not taken".

May be showing the flow in sequential order (for both reading and =
execution) starting at realtrap when "bf 17, k_trap" is not taken in the =
following manor will help with interpretation of my point: Read =
sequentially down the listing below where the conditional branches do =
not jump to k_trap. It only flows there (no jump) after the code shown =
for s_trap below for the case/context I was asking about unless I've =
missed something. I've also added to the comments to help identify my =
intended case.

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 PRESUME PSL_PR IS =
TRUE INSTEAD */
        GET_CPUINFO(%r1)
        ld      %r1,PC_CURPCB(%r1)
        mr      %r27,%r28               /* Save LR, r29 */
        mtsprg2 %r29
        bl      restore_kernsrs /* enable kernel mapping <=3D=3D=3D =
FIRST CALL */
        mfsprg2 %r29
        mr      %r28,%r27
        ba s_trap


s_trap:
        bf      17,k_trap /* branch if PSL_PR is false STILL NO BRANCH? =
*/
        GET_CPUINFO(%r1)
        ld      %r1,PC_CURPCB(%r1)
        mr      %r27,%r28               /* Save LR, r29 */
        mtsprg2 %r29
        bl      restore_kernsrs /* enable kernel mapping <=3D=3D=3D =
SECOND CALL */
        mfsprg2 %r29
        mr      %r28,%r27

This would then finally flow into k_trap but my point has already =
happened by this point. I see two calls to restore_kernsrs when I read =
the above execution sequence when PSL_PR is TRUE for the first "bf =
17,k_trap" (so no jump). So far I do not see code executed for this =
sequence that would make the second "bf 17,k_trap" jump when the first =
one above did not. Did I miss something in restore_kernsrs that makes =
the 2nd "bf 17,k_trap" jump when the first one does not?


(I saw the logic for the kernel debugger vs. normal. I did not challenge =
why the two alternatives exist. It just appears to me that there is some =
redundant work done by one path through the code.)



=3D=3D=3D
Mark Millard
markmi at dsl-only.net





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?0780902E-CF13-402A-A17B-4A2484CE008F>