https://github.com/torvalds/linux
Revision b91eb5182405b01a8aeb42e9b5207831767e97ee authored by Michael Ellerman on 25 August 2020, 09:34:24 UTC, committed by Michael Ellerman on 27 August 2020, 07:41:39 UTC
The recent commit 01eb01877f33 ("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-g18445bf405cb-dirty #9
  NIP:  c00000000000fbb4 LR: c00000000001a7ac CTR: c000000000183570
  REGS: c0000016b7cfb3b0 TRAP: 0700   Not tainted  (5.9.0-rc1-00098-g18445bf405cb-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: 01eb01877f33 ("powerpc/64s: Fix restore_math unnecessarily changing MSR")
Reported-by: Milton Miller <miltonm@us.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Link: https://lore.kernel.org/r/20200825093424.3967813-1-mpe@ellerman.id.au
1 parent e5fe560
History
Tip revision: b91eb5182405b01a8aeb42e9b5207831767e97ee authored by Michael Ellerman on 25 August 2020, 09:34:24 UTC
powerpc/64s: Fix crash in load_fp_state() due to fpexc_mode
Tip revision: b91eb51
File Mode Size
kasan
Kconfig -rw-r--r-- 28.0 KB
Kconfig.debug -rw-r--r-- 6.2 KB
Makefile -rw-r--r-- 4.4 KB
backing-dev.c -rw-r--r-- 25.1 KB
balloon_compaction.c -rw-r--r-- 8.2 KB
cleancache.c -rw-r--r-- 9.8 KB
cma.c -rw-r--r-- 14.3 KB
cma.h -rw-r--r-- 671 bytes
cma_debug.c -rw-r--r-- 4.5 KB
compaction.c -rw-r--r-- 80.3 KB
debug.c -rw-r--r-- 8.4 KB
debug_page_ref.c -rw-r--r-- 1.4 KB
debug_vm_pgtable.c -rw-r--r-- 29.2 KB
dmapool.c -rw-r--r-- 13.8 KB
early_ioremap.c -rw-r--r-- 6.8 KB
fadvise.c -rw-r--r-- 5.3 KB
failslab.c -rw-r--r-- 1.4 KB
filemap.c -rw-r--r-- 99.7 KB
frame_vector.c -rw-r--r-- 6.4 KB
frontswap.c -rw-r--r-- 14.2 KB
gup.c -rw-r--r-- 85.0 KB
gup_benchmark.c -rw-r--r-- 4.3 KB
highmem.c -rw-r--r-- 11.7 KB
hmm.c -rw-r--r-- 16.6 KB
huge_memory.c -rw-r--r-- 80.9 KB
hugetlb.c -rw-r--r-- 156.2 KB
hugetlb_cgroup.c -rw-r--r-- 21.4 KB
hwpoison-inject.c -rw-r--r-- 2.8 KB
init-mm.c -rw-r--r-- 1.2 KB
internal.h -rw-r--r-- 19.0 KB
interval_tree.c -rw-r--r-- 3.1 KB
ioremap.c -rw-r--r-- 6.5 KB
khugepaged.c -rw-r--r-- 57.7 KB
kmemleak-test.c -rw-r--r-- 2.6 KB
kmemleak.c -rw-r--r-- 56.2 KB
ksm.c -rw-r--r-- 89.2 KB
list_lru.c -rw-r--r-- 14.4 KB
maccess.c -rw-r--r-- 8.7 KB
madvise.c -rw-r--r-- 29.4 KB
mapping_dirty_helpers.c -rw-r--r-- 10.3 KB
memblock.c -rw-r--r-- 58.4 KB
memcontrol.c -rw-r--r-- 190.2 KB
memfd.c -rw-r--r-- 7.9 KB
memory-failure.c -rw-r--r-- 53.1 KB
memory.c -rw-r--r-- 137.3 KB
memory_hotplug.c -rw-r--r-- 49.3 KB
mempolicy.c -rw-r--r-- 76.2 KB
mempool.c -rw-r--r-- 15.8 KB
memremap.c -rw-r--r-- 13.2 KB
memtest.c -rw-r--r-- 2.8 KB
migrate.c -rw-r--r-- 80.3 KB
mincore.c -rw-r--r-- 7.6 KB
mlock.c -rw-r--r-- 22.7 KB
mm_init.c -rw-r--r-- 5.3 KB
mmap.c -rw-r--r-- 101.5 KB
mmu_gather.c -rw-r--r-- 8.4 KB
mmu_notifier.c -rw-r--r-- 34.6 KB
mmzone.c -rw-r--r-- 2.4 KB
mprotect.c -rw-r--r-- 17.0 KB
mremap.c -rw-r--r-- 22.1 KB
msync.c -rw-r--r-- 2.6 KB
nommu.c -rw-r--r-- 45.0 KB
oom_kill.c -rw-r--r-- 30.2 KB
page-writeback.c -rw-r--r-- 84.8 KB
page_alloc.c -rw-r--r-- 242.4 KB
page_counter.c -rw-r--r-- 6.6 KB
page_ext.c -rw-r--r-- 10.8 KB
page_idle.c -rw-r--r-- 5.5 KB
page_io.c -rw-r--r-- 11.3 KB
page_isolation.c -rw-r--r-- 8.6 KB
page_owner.c -rw-r--r-- 16.0 KB
page_poison.c -rw-r--r-- 3.0 KB
page_reporting.c -rw-r--r-- 9.9 KB
page_reporting.h -rw-r--r-- 1.6 KB
page_vma_mapped.c -rw-r--r-- 7.7 KB
pagewalk.c -rw-r--r-- 14.2 KB
percpu-internal.h -rw-r--r-- 7.7 KB
percpu-km.c -rw-r--r-- 3.0 KB
percpu-stats.c -rw-r--r-- 6.0 KB
percpu-vm.c -rw-r--r-- 10.3 KB
percpu.c -rw-r--r-- 95.4 KB
pgalloc-track.h -rw-r--r-- 1.3 KB
pgtable-generic.c -rw-r--r-- 5.6 KB
process_vm_access.c -rw-r--r-- 9.9 KB
ptdump.c -rw-r--r-- 3.8 KB
readahead.c -rw-r--r-- 18.4 KB
rmap.c -rw-r--r-- 55.5 KB
rodata_test.c -rw-r--r-- 1.3 KB
shmem.c -rw-r--r-- 110.6 KB
shuffle.c -rw-r--r-- 4.7 KB
shuffle.h -rw-r--r-- 1.1 KB
slab.c -rw-r--r-- 105.1 KB
slab.h -rw-r--r-- 16.7 KB
slab_common.c -rw-r--r-- 29.3 KB
slob.c -rw-r--r-- 18.1 KB
slub.c -rw-r--r-- 140.3 KB
sparse-vmemmap.c -rw-r--r-- 6.8 KB
sparse.c -rw-r--r-- 26.4 KB
swap.c -rw-r--r-- 32.4 KB
swap_cgroup.c -rw-r--r-- 5.1 KB
swap_slots.c -rw-r--r-- 9.3 KB
swap_state.c -rw-r--r-- 24.0 KB
swapfile.c -rw-r--r-- 96.8 KB
truncate.c -rw-r--r-- 26.7 KB
usercopy.c -rw-r--r-- 9.5 KB
userfaultfd.c -rw-r--r-- 17.6 KB
util.c -rw-r--r-- 23.9 KB
vmacache.c -rw-r--r-- 2.7 KB
vmalloc.c -rw-r--r-- 90.6 KB
vmpressure.c -rw-r--r-- 13.9 KB
vmscan.c -rw-r--r-- 123.1 KB
vmstat.c -rw-r--r-- 53.1 KB
workingset.c -rw-r--r-- 21.7 KB
z3fold.c -rw-r--r-- 46.7 KB
zbud.c -rw-r--r-- 18.2 KB
zpool.c -rw-r--r-- 11.2 KB
zsmalloc.c -rw-r--r-- 62.2 KB
zswap.c -rw-r--r-- 35.1 KB

back to top