powerpc: Fix unrecoverable SLB miss during restore_math()
authorCyril Bur <cyrilbur@gmail.com>
Wed, 16 Mar 2016 02:29:30 +0000 (13:29 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 16 Mar 2016 04:23:02 +0000 (15:23 +1100)
Commit 70fe3d9 "powerpc: Restore FPU/VEC/VSX if previously used" introduces a
call to restore_math() late in the syscall return path, after MSR_RI has been
cleared. The MSR_RI flag is used to indicate whether the kernel can take
another exception or not. A cleared MSR_RI flag indicates that the kernel
cannot.

Unfortunately when a machine is under SLB pressure an SLB miss can occur
in restore_math() which (with MSR_RI cleared) leads to an unrecoverable
exception.

  Unrecoverable exception 4100 at c0000000000088d8
  cpu 0x0: Vector: 4100  at [c0000003fa473b20]
      pc: c0000000000088d8: .load_vr_state+0x70/0x110
      lr: c00000000000f710: .restore_math+0x130/0x188
      sp: c0000003fa473da0
     msr: 9000000002003030
    current = 0xc0000007f876f180
    paca    = 0xc00000000fff0000  softe: 0  irq_happened: 0x01
      pid   = 1944, comm = K08umountfs
  [link register   ] c00000000000f710 .restore_math+0x130/0x188
  [c0000003fa473da0c0000003fa473e30 (unreliable)
  [c0000003fa473e30c000000000007b6c system_call+0x84/0xfc

The clearing of MSR_RI is actually an optimisation to avoid multiple MSR
writes, what must be disabled are interrupts. See comment in entry_64.S:

  /*
   * For performance reasons we clear RI the same time that we
   * clear EE. We only need to clear RI just before we restore r13
   * below, but batching it with EE saves us one expensive mtmsrd call.
   * We have to be careful to restore RI if we branch anywhere from
   * here (eg syscall_exit_work).
   */

At the point of calling restore_math() r13 has not been restored, as such, the
quick fix of turning MSR_RI back on for the call to restore_math() will
eliminate the occurrence of an unrecoverable exception.

We'd like to do a better fix in future.

Fixes: 70fe3d980f5f ("powerpc: Restore FPU/VEC/VSX if previously used")
Signed-off-by: Cyril Bur <cyrilbur@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/entry_64.S

index b9b125327f27c7e6ee4aea6498267f477d665c0d..9916d150b28c151bac0920aeb822545a41c40738 100644 (file)
@@ -218,7 +218,16 @@ system_call:                       /* label this so stack traces look sane */
        bne     3f
 #endif
 2:     addi    r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_BOOK3S
+       mtmsrd  r10,1           /* Restore RI */
+#endif
        bl      restore_math
+#ifdef CONFIG_PPC_BOOK3S
+       ld      r10,PACAKMSR(r13)
+       li      r9,MSR_RI
+       andc    r11,r10,r9 /* Re-clear RI */
+       mtmsrd  r11,1
+#endif
        ld      r8,_MSR(r1)
        ld      r3,RESULT(r1)
        li      r11,-MAX_ERRNO