linux/arch/s390/mm
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>
History 2016-05-18 17:06:44 -07:00
..
cmm.c s390: convert use of typedef ctl_table to struct ctl_table 2013-10-28 08:36:25 +01:00
dump_pagetables.c s390: remove 31 bit support 2015-03-25 11:49:33 +01:00
extable.c s390: fix normalization bug in exception table sorting 2016-03-03 15:07:12 -08:00
extmem.c s390/diag: add a statistic for diagnose calls 2015-10-14 14:32:06 +02:00
fault.c s390/cpumf: rework program parameter setting to detect guest samples 2015-10-14 14:32:12 +02:00
gup.c s390/mm: enable gup code for NUMA 2015-08-03 10:06:12 +02:00
hugetlbpage.c s390/mm: implement soft-dirty bits for user memory change tracking 2015-10-14 14:32:05 +02:00
init.c s390/mm: fix asce_bits handling with dynamic pagetable levels 2016-05-18 17:06:44 -07:00
maccess.c s390/maccess: improve s390_kernel_write() 2015-03-25 11:49:44 +01:00
Makefile s390/mem_detect: move memory detection code to mm folder 2013-05-02 15:50:22 +02:00
mem_detect.c s390/sclp: unify basic sclp access by exposing "struct sclp" 2015-05-13 09:58:17 +02:00
mmap.c s390/mm: fix asce_bits handling with dynamic pagetable levels 2016-05-18 17:06:44 -07:00
page-states.c s390/cmma: remove "cmma disable" code in case of dump again 2014-05-20 08:58:42 +02:00
pageattr.c s390: remove 31 bit support 2015-03-25 11:49:33 +01:00
pgtable.c s390/mm: fix asce_bits handling with dynamic pagetable levels 2016-05-18 17:06:44 -07:00
vmem.c s390: remove 31 bit support 2015-03-25 11:49:33 +01:00