From: Martin Schwidefsky <schwidefsky@de.ibm.com>
Date: Tue, 8 Jan 2019 12:44:57 +0100
Subject: s390/mm: always force a load of the primary ASCE on context switch
Git-commit: a38662084c8bdb829ff486468c7ea801c13fcc34
Patch-mainline: v5.0 or v5.0-rc3 (next release)
References: git-fixes
The ASCE of an mm_struct can be modified after a task has been created,
e.g. via crst_table_downgrade for a compat process. The active_mm logic
to avoid the switch_mm call if the next task is a kernel thread can
lead to a situation where switch_mm is called where 'prev == next' is
true but 'prev->context.asce == next->context.asce' is not.
This can lead to a situation where a CPU uses the outdated ASCE to run
a task. The result can be a crash, endless loops and really subtle
problem due to TLBs being created with an invalid ASCE.
Cc: stable@kernel.org # v3.15+
Fixes: 53e857f30867 ("s390/mm,tlb: race of lazy TLB flush vs. recreation")
Reported-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
[ ptesarik: Adjusted context, because SLE15 does not contain upstream
commit a38662084c8bdb829ff486468c7ea801c13fcc34. ]
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
arch/s390/include/asm/mmu_context.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -96,13 +96,12 @@ static inline void switch_mm(struct mm_s
int cpu = smp_processor_id();
S390_lowcore.user_asce = next->context.asce;
- if (prev == next)
- return;
cpumask_set_cpu(cpu, &next->context.cpu_attach_mask);
/* Clear old ASCE by loading the kernel ASCE. */
__ctl_load(S390_lowcore.kernel_asce, 1, 1);
__ctl_load(S390_lowcore.kernel_asce, 7, 7);
- cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
+ if (prev != next)
+ cpumask_clear_cpu(cpu, &prev->context.cpu_attach_mask);
}
#define finish_arch_post_lock_switch finish_arch_post_lock_switch