Commit 59aa31fd authored by Ram Pai's avatar Ram Pai Committed by Michael Ellerman

powerpc: introduce pte_set_hidx() helper

Introduce pte_set_hidx().It sets the (H_PAGE_F_SECOND|H_PAGE_F_GIX) bits
at the appropriate location in the PTE of 4K PTE. For 64K PTE, it sets
the bits in the second part of the PTE. Though the implementation for
the former just needs the slot parameter, it does take some additional
parameters to keep the prototype consistent.

This function will be handy as we work towards re-arranging the bits in
the subsequent patches.
Acked-by: default avatarBalbir Singh <bsingharora@gmail.com>
Reviewed-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarRam Pai <linuxram@us.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent f36dbfe1
...@@ -49,6 +49,20 @@ static inline int hash__hugepd_ok(hugepd_t hpd) ...@@ -49,6 +49,20 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
} }
#endif #endif
/*
* 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
* a matter of returning the PTE bits that need to be modified. On 64K PTE,
* things are a little more involved and hence needs many more parameters to
* accomplish the same. However we want to abstract this out from the caller by
* keeping the prototype consistent across the two formats.
*/
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
unsigned int subpg_index, unsigned long hidx)
{
return (hidx << H_PAGE_F_GIX_SHIFT) &
(H_PAGE_F_SECOND | H_PAGE_F_GIX);
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE
static inline char *get_hpte_slot_array(pmd_t *pmdp) static inline char *get_hpte_slot_array(pmd_t *pmdp)
......
...@@ -68,6 +68,8 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep) ...@@ -68,6 +68,8 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
return rpte; return rpte;
} }
#define HIDX_BITS(x, index) (x << (index << 2))
static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
{ {
if ((pte_val(rpte.pte) & H_PAGE_COMBO)) if ((pte_val(rpte.pte) & H_PAGE_COMBO))
...@@ -75,6 +77,29 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) ...@@ -75,6 +77,29 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
return (pte_val(rpte.pte) >> H_PAGE_F_GIX_SHIFT) & 0xf; return (pte_val(rpte.pte) >> H_PAGE_F_GIX_SHIFT) & 0xf;
} }
/*
* Commit the hidx and return PTE bits that needs to be modified. The caller is
* expected to modify the PTE bits accordingly and commit the PTE to memory.
*/
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
unsigned int subpg_index, unsigned long hidx)
{
unsigned long *hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
rpte.hidx &= ~HIDX_BITS(0xfUL, subpg_index);
*hidxp = rpte.hidx | HIDX_BITS(hidx, subpg_index);
/*
* Anyone reading PTE must ensure hidx bits are read after reading the
* PTE by using the read-side barrier smp_rmb(). __real_pte() can be
* used for that.
*/
smp_wmb();
/* No PTE bits to be modified, return 0x0UL */
return 0x0UL;
}
#define __rpte_to_pte(r) ((r).pte) #define __rpte_to_pte(r) ((r).pte)
extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index);
/* /*
......
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