• Andrew Morton's avatar
    [PATCH] ppc64: Fix SLB reload bug · f75bd853
    Andrew Morton authored
    From: Paul Mackerras <paulus@samba.org>
    
    Recently we found a particularly nasty bug in the segment handling in the
    ppc64 kernel.  It would only happen rarely under heavy load, but when it
    did the machine would lock up with the whole of memory filled with
    exception stack frames.
    
    The primary cause was that we were losing the translation for the kernel
    stack from the SLB, but we still had it in the ERAT for a while longer.
    Now, there is a critical region in various exception exit paths where we
    have loaded the SRR0 and SRR1 registers from GPRs and we are loading those
    GPRs and the stack pointer from the exception frame on the kernel stack.
    If we lose the ERAT entry for the kernel stack in that region, we take an
    SLB miss on the next access to the kernel stack.  Taking the exception
    overwrites the values we have put into SRR0 and SRR1, which means we lose
    state.  In fact we ended up repeating that last section of the exception
    exit path, but using the user stack pointer this time.  That caused another
    exception (or if it didn't, we loaded a new value from the user stack and
    then went around and tried to use that).  And it spiralled downwards from
    there.
    
    The patch below fixes the primary problem by making sure that we really
    never cast out the SLB entry for the kernel stack.  It also improves
    debuggability in case anything like this happens again by:
    
    - In our exception exit paths, we now check whether the RI bit in the
      SRR1 value is 0.  We already set the RI bit to 0 before starting the
      critical region, but we never checked it.  Now, if we do ever get an
      exception in one of the critical regions, we will detect it before
      returning to the critical region, and instead we will print a nasty
      message and oops.
    
    - In the exception entry code, we now check that the kernel stack pointer
      value we're about to use isn't a userspace address.  If it is, we print a
      nasty message and oops.
    
    This has been tested on G5 and pSeries (both with and without hypervisor)
    and compile-tested on iSeries.
    f75bd853
traps.c 12.7 KB