Subject: Re: locore.S question about [fs]uswintr
To: port-mips@netbsd.org <port-mips@netbsd.org>
From: Ethan Solomita <ethan@geocast.com>
List: port-mips
Date: 08/07/2000 19:52:05
	I've received a couple of replies which agree that what I describe
below is a bug, namely, [fs]uswintr should preserve U_PCB_ONFAULT, in
case it's in an interrupt which interrupted one of the copy routines
that relies on U_PCB_ONFAULT.

	So here's the diff I'm thinking of. If there's any problems, speak up
RSN or forever hold your peace.

	Thanks!
	-- Ethan

***************
*** 831,841 ****
  LEAF(fuswintr)
        lw      v1, _C_LABEL(curpcb)
        la      v0, _C_LABEL(fswintrberr)
        blt     a0, zero, _C_LABEL(fswintrberr)
        sw      v0, U_PCB_ONFAULT(v1)
        lhu     v0, 0(a0)                       # fetch short
        j       ra
!       sw      zero, U_PCB_ONFAULT(v1)
  END(fuswintr)

  /*
--- 845,856 ----
  LEAF(fuswintr)
        lw      v1, _C_LABEL(curpcb)
        la      v0, _C_LABEL(fswintrberr)
+       lw      a2, U_PCB_ONFAULT(v1)
        blt     a0, zero, _C_LABEL(fswintrberr)
        sw      v0, U_PCB_ONFAULT(v1)
        lhu     v0, 0(a0)                       # fetch short
        j       ra
!       sw      a2, U_PCB_ONFAULT(v1)
  END(fuswintr)

  /*
***************
*** 846,855 ****
  LEAF(suswintr)
        lw      v1, _C_LABEL(curpcb)
        la      v0, _C_LABEL(fswintrberr)
        blt     a0, zero, _C_LABEL(fswintrberr)
        sw      v0, U_PCB_ONFAULT(v1)
        sh      a1, 0(a0)                       # store short
!       sw      zero, U_PCB_ONFAULT(v1)
        j       ra
        move    v0, zero
  END(suswintr)
--- 861,871 ----
  LEAF(suswintr)
        lw      v1, _C_LABEL(curpcb)
        la      v0, _C_LABEL(fswintrberr)
+       lw      a2, U_PCB_ONFAULT(v1)
        blt     a0, zero, _C_LABEL(fswintrberr)
        sw      v0, U_PCB_ONFAULT(v1)
        sh      a1, 0(a0)                       # store short
!       sw      a2, U_PCB_ONFAULT(v1)
        j       ra
        move    v0, zero
  END(suswintr)
***************
*** 996,1002 ****
   */
  LEAF(fswintrberr)
        nop
! XLEAF(fswberr)
  XLEAF(baderr)
        sw      zero, U_PCB_ONFAULT(v1)
        j       ra
--- 1012,1023 ----
   */
  LEAF(fswintrberr)
        nop
!       sw      a2, U_PCB_ONFAULT(v1)
!       j       ra
!       li      v0, -1
! END(fswintrberr)
!
! LEAF(fswberr)
  XLEAF(baderr)
        sw      zero, U_PCB_ONFAULT(v1)
        j       ra


Ethan Solomita wrote:
> 
>         In locore.S, the comments before [fs]uswintr claim that they are safe
> to be called from an interrupt context. I think that they aren't, and I
> was hoping someone could either confirm what I see, or give me the
> missing clues.
> 
>         If they're called from an interrupt, then it is possible that another
> of these user-data routines could have been running at the time that the
> interrupt was received. When [fs]uswintr run, they set U_PCB_ONFAULT,
> and then clear it when they're done. So when the interrupt returns, and
> we resume running something like copyout (for example), it is running
> with a 0 in U_PCB_ONFAULT. If you get a fault, the kernel panics.
> 
>         I know that this all sounds very theoretical, but it came up with some
> improvements to user profiling that I've been looking into. The result
> is that the profiling code can be called from interrupt (namely,
> setrunnable()), and in particular can be called at splclock. So we're
> processing a disk interrupt and doing a copyout() to the user, then a
> clock interrupt happens and the profiling code calls [fs]uswintr.
> 
>         So, is this a bug? I eliminated the problem by changing [fs]uswintr to
> be like kcopy, which saves the old value of U_PCB_ONFAULT.
> 
>         Thanks!
>         -- Ethan