88
99#include <linux/const.h>
1010
11- #define PGDIR_SHIFT 30
11+ extern bool pgtable_l4_enabled ;
12+
13+ #define PGDIR_SHIFT_L3 30
14+ #define PGDIR_SHIFT_L4 39
15+ #define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3)
16+
17+ #define PGDIR_SHIFT (pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3)
1218/* Size of region mapped by a page global directory */
1319#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
1420#define PGDIR_MASK (~(PGDIR_SIZE - 1))
1521
22+ /* pud is folded into pgd in case of 3-level page table */
23+ #define PUD_SHIFT 30
24+ #define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
25+ #define PUD_MASK (~(PUD_SIZE - 1))
26+
1627#define PMD_SHIFT 21
1728/* Size of region mapped by a page middle directory */
1829#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
1930#define PMD_MASK (~(PMD_SIZE - 1))
2031
32+ /* Page Upper Directory entry */
33+ typedef struct {
34+ unsigned long pud ;
35+ } pud_t ;
36+
37+ #define pud_val (x ) ((x).pud)
38+ #define __pud (x ) ((pud_t) { (x) })
39+ #define PTRS_PER_PUD (PAGE_SIZE / sizeof(pud_t))
40+
2141/* Page Middle Directory entry */
2242typedef struct {
2343 unsigned long pmd ;
@@ -59,6 +79,16 @@ static inline void pud_clear(pud_t *pudp)
5979 set_pud (pudp , __pud (0 ));
6080}
6181
82+ static inline pud_t pfn_pud (unsigned long pfn , pgprot_t prot )
83+ {
84+ return __pud ((pfn << _PAGE_PFN_SHIFT ) | pgprot_val (prot ));
85+ }
86+
87+ static inline unsigned long _pud_pfn (pud_t pud )
88+ {
89+ return pud_val (pud ) >> _PAGE_PFN_SHIFT ;
90+ }
91+
6292static inline pmd_t * pud_pgtable (pud_t pud )
6393{
6494 return (pmd_t * )pfn_to_virt (pud_val (pud ) >> _PAGE_PFN_SHIFT );
@@ -69,6 +99,17 @@ static inline struct page *pud_page(pud_t pud)
6999 return pfn_to_page (pud_val (pud ) >> _PAGE_PFN_SHIFT );
70100}
71101
102+ #define mm_pud_folded mm_pud_folded
103+ static inline bool mm_pud_folded (struct mm_struct * mm )
104+ {
105+ if (pgtable_l4_enabled )
106+ return false;
107+
108+ return true;
109+ }
110+
111+ #define pmd_index (addr ) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
112+
72113static inline pmd_t pfn_pmd (unsigned long pfn , pgprot_t prot )
73114{
74115 return __pmd ((pfn << _PAGE_PFN_SHIFT ) | pgprot_val (prot ));
@@ -84,4 +125,69 @@ static inline unsigned long _pmd_pfn(pmd_t pmd)
84125#define pmd_ERROR (e ) \
85126 pr_err("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
86127
128+ #define pud_ERROR (e ) \
129+ pr_err("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
130+
131+ static inline void set_p4d (p4d_t * p4dp , p4d_t p4d )
132+ {
133+ if (pgtable_l4_enabled )
134+ * p4dp = p4d ;
135+ else
136+ set_pud ((pud_t * )p4dp , (pud_t ){ p4d_val (p4d ) });
137+ }
138+
139+ static inline int p4d_none (p4d_t p4d )
140+ {
141+ if (pgtable_l4_enabled )
142+ return (p4d_val (p4d ) == 0 );
143+
144+ return 0 ;
145+ }
146+
147+ static inline int p4d_present (p4d_t p4d )
148+ {
149+ if (pgtable_l4_enabled )
150+ return (p4d_val (p4d ) & _PAGE_PRESENT );
151+
152+ return 1 ;
153+ }
154+
155+ static inline int p4d_bad (p4d_t p4d )
156+ {
157+ if (pgtable_l4_enabled )
158+ return !p4d_present (p4d );
159+
160+ return 0 ;
161+ }
162+
163+ static inline void p4d_clear (p4d_t * p4d )
164+ {
165+ if (pgtable_l4_enabled )
166+ set_p4d (p4d , __p4d (0 ));
167+ }
168+
169+ static inline pud_t * p4d_pgtable (p4d_t p4d )
170+ {
171+ if (pgtable_l4_enabled )
172+ return (pud_t * )pfn_to_virt (p4d_val (p4d ) >> _PAGE_PFN_SHIFT );
173+
174+ return (pud_t * )pud_pgtable ((pud_t ) { p4d_val (p4d ) });
175+ }
176+
177+ static inline struct page * p4d_page (p4d_t p4d )
178+ {
179+ return pfn_to_page (p4d_val (p4d ) >> _PAGE_PFN_SHIFT );
180+ }
181+
182+ #define pud_index (addr ) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
183+
184+ #define pud_offset pud_offset
185+ static inline pud_t * pud_offset (p4d_t * p4d , unsigned long address )
186+ {
187+ if (pgtable_l4_enabled )
188+ return p4d_pgtable (* p4d ) + pud_index (address );
189+
190+ return (pud_t * )p4d ;
191+ }
192+
87193#endif /* _ASM_RISCV_PGTABLE_64_H */
0 commit comments