aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-08-25 20:32:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-08-25 20:32:35 -0400
commit42e6d5e5ee05a0a4fa6f71ffeeafc367a1483740 (patch)
treea2c243decfdbd6136cb95e405313266840822bd5
parent105065c3f7164d756ee5495b8670e57f2bcf65c3 (diff)
parent1a92a80ad386a1a6e3b36d576d52a1a456394b70 (diff)
Merge tag 'powerpc-4.13-8' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fix from Michael Ellerman: "Just one fix, to add a barrier in the switch_mm() code to make sure the mm cpumask update is ordered vs the MMU starting to load translations. As far as we know no one's actually hit the bug, but that's just luck. Thanks to Benjamin Herrenschmidt, Nicholas Piggin" * tag 'powerpc-4.13-8' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/mm: Ensure cpumask update is ordered
-rw-r--r--arch/powerpc/include/asm/mmu_context.h18
-rw-r--r--arch/powerpc/include/asm/pgtable-be-types.h1
-rw-r--r--arch/powerpc/include/asm/pgtable-types.h1
3 files changed, 20 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index 0c76675394c5..35bec1c5bd5a 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -90,6 +90,24 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev,
90 /* Mark this context has been used on the new CPU */ 90 /* Mark this context has been used on the new CPU */
91 if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) { 91 if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) {
92 cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); 92 cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
93
94 /*
95 * This full barrier orders the store to the cpumask above vs
96 * a subsequent operation which allows this CPU to begin loading
97 * translations for next.
98 *
99 * When using the radix MMU that operation is the load of the
100 * MMU context id, which is then moved to SPRN_PID.
101 *
102 * For the hash MMU it is either the first load from slb_cache
103 * in switch_slb(), and/or the store of paca->mm_ctx_id in
104 * copy_mm_to_paca().
105 *
106 * On the read side the barrier is in pte_xchg(), which orders
107 * the store to the PTE vs the load of mm_cpumask.
108 */
109 smp_mb();
110
93 new_on_cpu = true; 111 new_on_cpu = true;
94 } 112 }
95 113
diff --git a/arch/powerpc/include/asm/pgtable-be-types.h b/arch/powerpc/include/asm/pgtable-be-types.h
index 9c0f5db5cf46..67e7e3d990f4 100644
--- a/arch/powerpc/include/asm/pgtable-be-types.h
+++ b/arch/powerpc/include/asm/pgtable-be-types.h
@@ -87,6 +87,7 @@ static inline bool pte_xchg(pte_t *ptep, pte_t old, pte_t new)
87 unsigned long *p = (unsigned long *)ptep; 87 unsigned long *p = (unsigned long *)ptep;
88 __be64 prev; 88 __be64 prev;
89 89
90 /* See comment in switch_mm_irqs_off() */
90 prev = (__force __be64)__cmpxchg_u64(p, (__force unsigned long)pte_raw(old), 91 prev = (__force __be64)__cmpxchg_u64(p, (__force unsigned long)pte_raw(old),
91 (__force unsigned long)pte_raw(new)); 92 (__force unsigned long)pte_raw(new));
92 93
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index 8bd3b13fe2fb..369a164b545c 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -62,6 +62,7 @@ static inline bool pte_xchg(pte_t *ptep, pte_t old, pte_t new)
62{ 62{
63 unsigned long *p = (unsigned long *)ptep; 63 unsigned long *p = (unsigned long *)ptep;
64 64
65 /* See comment in switch_mm_irqs_off() */
65 return pte_val(old) == __cmpxchg_u64(p, pte_val(old), pte_val(new)); 66 return pte_val(old) == __cmpxchg_u64(p, pte_val(old), pte_val(new));
66} 67}
67#endif 68#endif