Commit 1660e9d3 authored by Paul Mackerras's avatar Paul Mackerras

powerpc/32: Always order writes to halves of 64-bit PTEs

On 32-bit systems with 64-bit PTEs, the PTEs have to be written in two
32-bit halves.  On SMP we write the higher-order half and then the
lower-order half, with a write barrier between the two halves, but on
UP there was no particular ordering of the writes to the two halves.

This extends the ordering that we already do on SMP to the UP case as
well.  The reason is that with the perf_counter subsystem potentially
accessing user memory at interrupt time to get stack traces, we have
to be careful not to create an incorrect but apparently valid PTE even
on UP.
Acked-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 64f1607f
...@@ -104,8 +104,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, ...@@ -104,8 +104,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
else else
pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) #elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
/* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we /* Second case is 32-bit with 64-bit PTE. In this case, we
* can just store as long as we do the two halves in the right order * can just store as long as we do the two halves in the right order
* with a barrier in between. This is possible because we take care, * with a barrier in between. This is possible because we take care,
* in the hash code, to pre-invalidate if the PTE was already hashed, * in the hash code, to pre-invalidate if the PTE was already hashed,
...@@ -140,7 +140,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, ...@@ -140,7 +140,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
#else #else
/* Anything else just stores the PTE normally. That covers all 64-bit /* Anything else just stores the PTE normally. That covers all 64-bit
* cases, and 32-bit non-hash with 64-bit PTEs in UP mode * cases, and 32-bit non-hash with 32-bit PTEs.
*/ */
*ptep = pte; *ptep = pte;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment