Skip to content

Commit 59aa31f

Browse files
Ram Paimpe
authored andcommitted
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: Balbir Singh <[email protected]> Reviewed-by: Aneesh Kumar K.V <[email protected]> Signed-off-by: Ram Pai <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent f36dbfe commit 59aa31f

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

arch/powerpc/include/asm/book3s/64/hash-4k.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
4949
}
5050
#endif
5151

52+
/*
53+
* 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
54+
* a matter of returning the PTE bits that need to be modified. On 64K PTE,
55+
* things are a little more involved and hence needs many more parameters to
56+
* accomplish the same. However we want to abstract this out from the caller by
57+
* keeping the prototype consistent across the two formats.
58+
*/
59+
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
60+
unsigned int subpg_index, unsigned long hidx)
61+
{
62+
return (hidx << H_PAGE_F_GIX_SHIFT) &
63+
(H_PAGE_F_SECOND | H_PAGE_F_GIX);
64+
}
65+
5266
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
5367

5468
static inline char *get_hpte_slot_array(pmd_t *pmdp)

arch/powerpc/include/asm/book3s/64/hash-64k.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,38 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
6868
return rpte;
6969
}
7070

71+
#define HIDX_BITS(x, index) (x << (index << 2))
72+
7173
static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
7274
{
7375
if ((pte_val(rpte.pte) & H_PAGE_COMBO))
7476
return (rpte.hidx >> (index<<2)) & 0xf;
7577
return (pte_val(rpte.pte) >> H_PAGE_F_GIX_SHIFT) & 0xf;
7678
}
7779

80+
/*
81+
* Commit the hidx and return PTE bits that needs to be modified. The caller is
82+
* expected to modify the PTE bits accordingly and commit the PTE to memory.
83+
*/
84+
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
85+
unsigned int subpg_index, unsigned long hidx)
86+
{
87+
unsigned long *hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
88+
89+
rpte.hidx &= ~HIDX_BITS(0xfUL, subpg_index);
90+
*hidxp = rpte.hidx | HIDX_BITS(hidx, subpg_index);
91+
92+
/*
93+
* Anyone reading PTE must ensure hidx bits are read after reading the
94+
* PTE by using the read-side barrier smp_rmb(). __real_pte() can be
95+
* used for that.
96+
*/
97+
smp_wmb();
98+
99+
/* No PTE bits to be modified, return 0x0UL */
100+
return 0x0UL;
101+
}
102+
78103
#define __rpte_to_pte(r) ((r).pte)
79104
extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index);
80105
/*

0 commit comments

Comments
 (0)