• Laurent Dufour's avatar
    powerpc/rtas: Keep MSR[RI] set when calling RTAS · b6b1c3ce
    Laurent Dufour authored
    RTAS runs in real mode (MSR[DR] and MSR[IR] unset) and in 32-bit big
    endian mode (MSR[SF,LE] unset).
    
    The change in MSR is done in enter_rtas() in a relatively complex way,
    since the MSR value could be hardcoded.
    
    Furthermore, a panic has been reported when hitting the watchdog interrupt
    while running in RTAS, this leads to the following stack trace:
    
      watchdog: CPU 24 Hard LOCKUP
      watchdog: CPU 24 TB:997512652051031, last heartbeat TB:997504470175378 (15980ms ago)
      ...
      Supported: No, Unreleased kernel
      CPU: 24 PID: 87504 Comm: drmgr Kdump: loaded Tainted: G            E  X    5.14.21-150400.71.1.bz196362_2-default #1 SLE15-SP4 (unreleased) 0d821077ef4faa8dfaf370efb5fdca1fa35f4e2c
      NIP:  000000001fb41050 LR: 000000001fb4104c CTR: 0000000000000000
      REGS: c00000000fc33d60 TRAP: 0100   Tainted: G            E  X     (5.14.21-150400.71.1.bz196362_2-default)
      MSR:  8000000002981000 <SF,VEC,VSX,ME>  CR: 48800002  XER: 20040020
      CFAR: 000000000000011c IRQMASK: 1
      GPR00: 0000000000000003 ffffffffffffffff 0000000000000001 00000000000050dc
      GPR04: 000000001ffb6100 0000000000000020 0000000000000001 000000001fb09010
      GPR08: 0000000020000000 0000000000000000 0000000000000000 0000000000000000
      GPR12: 80040000072a40a8 c00000000ff8b680 0000000000000007 0000000000000034
      GPR16: 000000001fbf6e94 000000001fbf6d84 000000001fbd1db0 000000001fb3f008
      GPR20: 000000001fb41018 ffffffffffffffff 000000000000017f fffffffffffff68f
      GPR24: 000000001fb18fe8 000000001fb3e000 000000001fb1adc0 000000001fb1cf40
      GPR28: 000000001fb26000 000000001fb460f0 000000001fb17f18 000000001fb17000
      NIP [000000001fb41050] 0x1fb41050
      LR [000000001fb4104c] 0x1fb4104c
      Call Trace:
      Instruction dump:
      XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
      XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
      Oops: Unrecoverable System Reset, sig: 6 [#1]
      LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
      ...
      Supported: No, Unreleased kernel
      CPU: 24 PID: 87504 Comm: drmgr Kdump: loaded Tainted: G            E  X    5.14.21-150400.71.1.bz196362_2-default #1 SLE15-SP4 (unreleased) 0d821077ef4faa8dfaf370efb5fdca1fa35f4e2c
      NIP:  000000001fb41050 LR: 000000001fb4104c CTR: 0000000000000000
      REGS: c00000000fc33d60 TRAP: 0100   Tainted: G            E  X     (5.14.21-150400.71.1.bz196362_2-default)
      MSR:  8000000002981000 <SF,VEC,VSX,ME>  CR: 48800002  XER: 20040020
      CFAR: 000000000000011c IRQMASK: 1
      GPR00: 0000000000000003 ffffffffffffffff 0000000000000001 00000000000050dc
      GPR04: 000000001ffb6100 0000000000000020 0000000000000001 000000001fb09010
      GPR08: 0000000020000000 0000000000000000 0000000000000000 0000000000000000
      GPR12: 80040000072a40a8 c00000000ff8b680 0000000000000007 0000000000000034
      GPR16: 000000001fbf6e94 000000001fbf6d84 000000001fbd1db0 000000001fb3f008
      GPR20: 000000001fb41018 ffffffffffffffff 000000000000017f fffffffffffff68f
      GPR24: 000000001fb18fe8 000000001fb3e000 000000001fb1adc0 000000001fb1cf40
      GPR28: 000000001fb26000 000000001fb460f0 000000001fb17f18 000000001fb17000
      NIP [000000001fb41050] 0x1fb41050
      LR [000000001fb4104c] 0x1fb4104c
      Call Trace:
      Instruction dump:
      XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
      XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
      ---[ end trace 3ddec07f638c34a2 ]---
    
    This happens because MSR[RI] is unset when entering RTAS but there is no
    valid reason to not set it here.
    
    RTAS is expected to be called with MSR[RI] as specified in PAPR+ section
    "7.2.1 Machine State":
    
      R1–7.2.1–9. If called with MSR[RI] equal to 1, then RTAS must protect
      its own critical regions from recursion by setting the MSR[RI] bit to
      0 when in the critical regions.
    
    Fixing this by reviewing the way MSR is compute before calling RTAS. Now a
    hardcoded value meaning real mode, 32 bits big endian mode and Recoverable
    Interrupt is loaded. In the case MSR[S] is set, it will remain set while
    entering RTAS as only urfid can unset it (thanks Fabiano).
    
    In addition a check is added in do_enter_rtas() to detect calls made with
    MSR[RI] unset, as we are forcing it on later.
    
    This patch has been tested on the following machines:
    Power KVM Guest
      P8 S822L (host Ubuntu kernel 5.11.0-49-generic)
    PowerVM LPAR
      P8 9119-MME (FW860.A1)
      p9 9008-22L (FW950.00)
      P10 9080-HEX (FW1010.00)
    Suggested-by: default avatarNicholas Piggin <npiggin@gmail.com>
    Signed-off-by: default avatarLaurent Dufour <ldufour@linux.ibm.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20220504101244.12107-1-ldufour@linux.ibm.com
    b6b1c3ce
entry_64.S 12.1 KB