• Leonardo Bras's avatar
    powerpc/rtas: Implement reentrant rtas call · b664db8e
    Leonardo Bras authored
    Implement rtas_call_reentrant() for reentrant rtas-calls:
    "ibm,int-on", "ibm,int-off",ibm,get-xive" and  "ibm,set-xive".
    
    On LoPAPR Version 1.1 (March 24, 2016), from 7.3.10.1 to 7.3.10.4,
    items 2 and 3 say:
    
    2 - For the PowerPC External Interrupt option: The * call must be
    reentrant to the number of processors on the platform.
    3 - For the PowerPC External Interrupt option: The * argument call
    buffer for each simultaneous call must be physically unique.
    
    So, these rtas-calls can be called in a lockless way, if using
    a different buffer for each cpu doing such rtas call.
    
    For this, it was suggested to add the buffer (struct rtas_args)
    in the PACA struct, so each cpu can have it's own buffer.
    The PACA struct received a pointer to rtas buffer, which is
    allocated in the memory range available to rtas 32-bit.
    
    Reentrant rtas calls are useful to avoid deadlocks in crashing,
    where rtas-calls are needed, but some other thread crashed holding
    the rtas.lock.
    
    This is a backtrace of a deadlock from a kdump testing environment:
    
      #0 arch_spin_lock
      #1  lock_rtas ()
      #2  rtas_call (token=8204, nargs=1, nret=1, outputs=0x0)
      #3  ics_rtas_mask_real_irq (hw_irq=4100)
      #4  machine_kexec_mask_interrupts
      #5  default_machine_crash_shutdown
      #6  machine_crash_shutdown
      #7  __crash_kexec
      #8  crash_kexec
      #9  oops_end
    Signed-off-by: default avatarLeonardo Bras <leobras.c@gmail.com>
    [mpe: Move under #ifdef PSERIES to avoid build breakage]
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20200518234245.200672-3-leobras.c@gmail.com
    b664db8e
ics-rtas.c 6.03 KB