linux/arch/s390
Gerald Schaefer ce1bc448ba s390/mm: fix asce_bits handling with dynamic pagetable levels
commit 723cacbd9d upstream.

There is a race with multi-threaded applications between context switch and
pagetable upgrade. In switch_mm() a new user_asce is built from mm->pgd and
mm->context.asce_bits, w/o holding any locks. A concurrent mmap with a
pagetable upgrade on another thread in crst_table_upgrade() could already
have set new asce_bits, but not yet the new mm->pgd. This would result in a
corrupt user_asce in switch_mm(), and eventually in a kernel panic from a
translation exception.

Fix this by storing the complete asce instead of just the asce_bits, which
can then be read atomically from switch_mm(), so that it either sees the
old value or the new value, but no mixture. Both cases are OK. Having the
old value would result in a page fault on access to the higher level memory,
but the fault handler would see the new mm->pgd, if it was a valid access
after the mmap on the other thread has completed. So as worst-case scenario
we would have a page fault loop for the racing thread until the next time
slice.

Also remove dead code and simplify the upgrade/downgrade path, there are no
upgrades from 2 levels, and only downgrades from 3 levels for compat tasks.
There are also no concurrent upgrades, because the mmap_sem is held with
down_write() in do_mmap, so the flush and table checks during upgrade can
be removed.

Reported-by: Michael Munday <munday@ca.ibm.com>
Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-05-18 17:06:44 -07:00
..
appldata s390: appldata: drop owner assignment from platform_drivers 2014-10-20 16:20:13 +02:00
boot s390/boot/decompression: disable floating point in decompressor 2015-09-29 14:45:10 +02:00
configs s390/defconfig: set SCSI_DH=y 2015-10-01 10:48:36 +02:00
crypto crypto: s390/sha - replace raw value by their coresponding define 2015-10-15 21:05:11 +08:00
hypfs s390/diag: add a statistic for diagnose calls 2015-10-14 14:32:06 +02:00
include s390/mm: fix asce_bits handling with dynamic pagetable levels 2016-05-18 17:06:44 -07:00
kernel s390/cpumf: add missing lpp magic initialization 2016-04-12 09:08:36 -07:00
kvm KVM: s390: correct fprs on SIGP (STOP AND) STORE STATUS 2016-03-16 08:42:58 -07:00
lib s390/bitops: remove 31 bit related comments 2015-10-14 14:32:15 +02:00
mm s390/mm: fix asce_bits handling with dynamic pagetable levels 2016-05-18 17:06:44 -07:00
net ebpf: migrate bpf_prog's flags to bitfield 2015-10-03 05:02:39 -07:00
numa s390/numa: write kernel message when emu_size has been increased 2015-10-14 14:31:59 +02:00
oprofile s390/oprofile: fix compile error 2015-07-01 09:34:39 +02:00
pci s390/pci: enforce fmb page boundary rule 2016-04-12 09:08:37 -07:00
defconfig s390: new default configuration 2015-06-25 09:39:25 +02:00
Kbuild s390/numa: add core infrastructure 2015-08-03 18:40:25 +02:00
Kconfig IOMMU Updates for Linux v4.4 2015-11-05 16:12:10 -08:00
Kconfig.debug
Makefile s390/sclp: convert early sclp console code to C 2015-07-29 09:11:39 +02:00