powerpc/rtas: Implement reentrant rtas call
authorLeonardo Bras <leobras.c@gmail.com>
Mon, 18 May 2020 23:42:45 +0000 (20:42 -0300)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 2 Jun 2020 10:59:08 +0000 (20:59 +1000)
commitb664db8e3f976d9233cc9ea5e3f8a8c0bcabeb48
tree487ddb1404c7fd3029a5e72167fa4010d7ef002e
parent783a015b747f606e803b798eb8b50c73c548691d
powerpc/rtas: Implement reentrant rtas call

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: Leonardo Bras <leobras.c@gmail.com>
[mpe: Move under #ifdef PSERIES to avoid build breakage]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200518234245.200672-3-leobras.c@gmail.com
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/rtas.c
arch/powerpc/sysdev/xics/ics-rtas.c