powerpc/mm: Use read barrier when creating real_pte

On ppc64 we support 4K hash pte with 64K page size. That requires
us to track the hash pte slot information on a per 4k basis. We do that
by storing the slot details in the second half of pte page. The pte bit
_PAGE_COMBO is used to indicate whether the second half need to be
looked while building real_pte. We need to use read memory barrier while
doing that so that load of hidx is not reordered w.r.t _PAGE_COMBO
check. On the store side we already do a lwsync in __hash_page_4K

CC: <stable@vger.kernel.org>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Aneesh Kumar K.V 2014-08-13 12:32:03 +05:30 committed by Benjamin Herrenschmidt
parent 7e467245bf
commit 85c1fafd72

View file

@ -46,11 +46,31 @@
* in order to deal with 64K made of 4K HW pages. Thus we override the * in order to deal with 64K made of 4K HW pages. Thus we override the
* generic accessors and iterators here * generic accessors and iterators here
*/ */
#define __real_pte(e,p) ((real_pte_t) { \ #define __real_pte __real_pte
(e), (pte_val(e) & _PAGE_COMBO) ? \ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
(pte_val(*((p) + PTRS_PER_PTE))) : 0 }) {
#define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ real_pte_t rpte;
(((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
rpte.pte = pte;
rpte.hidx = 0;
if (pte_val(pte) & _PAGE_COMBO) {
/*
* Make sure we order the hidx load against the _PAGE_COMBO
* check. The store side ordering is done in __hash_page_4K
*/
smp_rmb();
rpte.hidx = pte_val(*((ptep) + PTRS_PER_PTE));
}
return rpte;
}
static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
{
if ((pte_val(rpte.pte) & _PAGE_COMBO))
return (rpte.hidx >> (index<<2)) & 0xf;
return (pte_val(rpte.pte) >> 12) & 0xf;
}
#define __rpte_to_pte(r) ((r).pte) #define __rpte_to_pte(r) ((r).pte)
#define __rpte_sub_valid(rpte, index) \ #define __rpte_sub_valid(rpte, index) \
(pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index))) (pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))