Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: add barrier after writing kernel PTE

There is no barrier between something like ioremap() writing to
a PTE, and returning the value to a caller that may then store the
pointer in a place that is visible to other CPUs. Such callers
generally don't perform barriers of their own.

Even if callers of ioremap() and similar things did use barriers,
the most logical choise would be smp_wmb(), which is not
architecturally sufficient when BookE hardware tablewalk is used. A
full sync is specified by the architecture.

For userspace mappings, OTOH, we generally already have an lwsync due
to locking, and if we occasionally take a spurious fault due to not
having a full sync with hardware tablewalk, it will not be fatal
because we will retry rather than oops.

Signed-off-by: Scott Wood <scottwood@freescale.com>

+13
+1
arch/powerpc/mm/pgtable_32.c
··· 299 299 set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, 300 300 __pgprot(flags))); 301 301 } 302 + smp_wmb(); 302 303 return err; 303 304 } 304 305
+12
arch/powerpc/mm/pgtable_64.c
··· 153 153 } 154 154 #endif /* !CONFIG_PPC_MMU_NOHASH */ 155 155 } 156 + 157 + #ifdef CONFIG_PPC_BOOK3E_64 158 + /* 159 + * With hardware tablewalk, a sync is needed to ensure that 160 + * subsequent accesses see the PTE we just wrote. Unlike userspace 161 + * mappings, we can't tolerate spurious faults, so make sure 162 + * the new PTE will be seen the first time. 163 + */ 164 + mb(); 165 + #else 166 + smp_wmb(); 167 + #endif 156 168 return 0; 157 169 } 158 170