Skip to content
  • Michael Ellerman's avatar
    powerpc/64s: Fix crash in load_fp_state() due to fpexc_mode · b91eb518
    Michael Ellerman authored
    The recent commit 01eb0187 ("powerpc/64s: Fix restore_math
    unnecessarily changing MSR") changed some of the handling of floating
    point/vector restore.
    
    In particular it caused current->thread.fpexc_mode to be copied into
    the current MSR (via msr_check_and_set()), rather than just into
    regs->msr (which is moved into MSR on return to userspace).
    
    This can lead to a crash in the kernel if we take a floating point
    exception when restoring FPSCR:
    
      Oops: Exception in kernel mode, sig: 8 [#1]
      LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV
      Modules linked in:
      CPU: 3 PID: 101213 Comm: ld64.so.2 Not tainted 5.9.0-rc1-00098-g18445bf4-dirty #9
      NIP:  c00000000000fbb4 LR: c00000000001a7ac CTR: c000000000183570
      REGS: c0000016b7cfb3b0 TRAP: 0700   Not tainted  (5.9.0-rc1-00098-g18445bf4-dirty)
      MSR:  900000000290b933 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE>  CR: 44002444  XER: 00000000
      CFAR: c00000000001a7a8 IRQMASK: 1
      GPR00: c00000000001ae40 c0000016b7cfb640 c0000000011b7f00 c000001542a0f740
      GPR04: c000001542a0f720 c000001542a0eb00 0000000000000900 c000001542a0eb00
      GPR08: 000000000000000a 0000000000002000 9000000000009033 0000000000000000
      GPR12: 0000000000004000 c0000017ffffd900 0000000000000001 c000000000df5a58
      GPR16: c000000000e19c18 c0000000010e1123 0000000000000001 c000000000e1a638
      GPR20: 0000000000000000 c0000000044b1d00 0000000000000000 c000001542a0f2a0
      GPR24: 00000016c7fe0000 c000001542a0f720 c000000001c93da0 c000000000fe5f28
      GPR28: c000001542a0f720 0000000000800000 c0000016b7cfbe90 0000000002802900
      NIP load_fp_state+0x4/0x214
      LR  restore_math+0x17c/0x1f0
      Call Trace:
        0xc0000016b7cfb680 (unreliable)
        __switch_to+0x330/0x460
        __schedule+0x318/0x920
        schedule+0x74/0x140
        schedule_timeout+0x318/0x3f0
        wait_for_completion+0xc8/0x210
        call_usermodehelper_exec+0x234/0x280
        do_coredump+0xedc/0x13c0
        get_signal+0x1d4/0xbe0
        do_notify_resume+0x1a0/0x490
        interrupt_exit_user_prepare+0x1c4/0x230
        interrupt_return+0x14/0x1c0
      Instruction dump:
      ebe10168 e88101a0 7c8ff120 382101e0 e8010010 7c0803a6 4e800020 790605c4
      782905c4 7c0008a8 7c0008a8 c8030200 <fffe058e> 48000088 c8030000 c8230010
    
    Fix it by only loading the fpexc_mode value into regs->msr.
    
    Also add a comment to explain that although VSX is subject to the
    value of fpexc_mode, we don't have to handle that separately because
    we only allow VSX to be enabled if FP is also enabled.
    
    Fixes: 01eb0187
    
     ("powerpc/64s: Fix restore_math unnecessarily changing MSR")
    Reported-by: default avatarMilton Miller <miltonm@us.ibm.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Reviewed-by: default avatarNicholas Piggin <npiggin@gmail.com>
    Link: https://lore.kernel.org/r/20200825093424.3967813-1-mpe@ellerman.id.au
    b91eb518