File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -397,6 +397,25 @@ config RISCV_ISA_C
397397
398398 If you don't know what to do here, say Y.
399399
400+ config RISCV_ISA_SVNAPOT
401+ bool "SVNAPOT extension support"
402+ depends on 64BIT && MMU
403+ default y
404+ select RISCV_ALTERNATIVE
405+ help
406+ Allow kernel to detect the SVNAPOT ISA-extension dynamically at boot
407+ time and enable its usage.
408+
409+ The SVNAPOT extension is used to mark contiguous PTEs as a range
410+ of contiguous virtual-to-physical translations for a naturally
411+ aligned power-of-2 (NAPOT) granularity larger than the base 4KB page
412+ size. When HUGETLBFS is also selected this option unconditionally
413+ allocates some memory for each NAPOT page size supported by the kernel.
414+ When optimizing for low memory consumption and for platforms without
415+ the SVNAPOT extension, it may be better to say N here.
416+
417+ If you don't know what to do here, say Y.
418+
400419config RISCV_ISA_SVPBMT
401420 bool "SVPBMT extension support"
402421 depends on 64BIT && MMU
Original file line number Diff line number Diff line change 4343#define RISCV_ISA_EXT_SSCOFPMF 26
4444#define RISCV_ISA_EXT_SSTC 27
4545#define RISCV_ISA_EXT_SVINVAL 28
46- #define RISCV_ISA_EXT_SVPBMT 29
47- #define RISCV_ISA_EXT_ZBB 30
48- #define RISCV_ISA_EXT_ZICBOM 31
49- #define RISCV_ISA_EXT_ZIHINTPAUSE 32
46+ #define RISCV_ISA_EXT_SVNAPOT 29
47+ #define RISCV_ISA_EXT_SVPBMT 30
48+ #define RISCV_ISA_EXT_ZBB 31
49+ #define RISCV_ISA_EXT_ZICBOM 32
50+ #define RISCV_ISA_EXT_ZIHINTPAUSE 33
5051
5152#ifndef __ASSEMBLY__
5253
Original file line number Diff line number Diff line change 1616#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
1717#define PAGE_MASK (~(PAGE_SIZE - 1))
1818
19- #ifdef CONFIG_64BIT
20- #define HUGE_MAX_HSTATE 2
21- #else
22- #define HUGE_MAX_HSTATE 1
23- #endif
2419#define HPAGE_SHIFT PMD_SHIFT
2520#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
2621#define HPAGE_MASK (~(HPAGE_SIZE - 1))
Original file line number Diff line number Diff line change @@ -78,6 +78,40 @@ typedef struct {
7878 */
7979#define _PAGE_PFN_MASK GENMASK(53, 10)
8080
81+ /*
82+ * [63] Svnapot definitions:
83+ * 0 Svnapot disabled
84+ * 1 Svnapot enabled
85+ */
86+ #define _PAGE_NAPOT_SHIFT 63
87+ #define _PAGE_NAPOT BIT(_PAGE_NAPOT_SHIFT)
88+ /*
89+ * Only 64KB (order 4) napot ptes supported.
90+ */
91+ #define NAPOT_CONT_ORDER_BASE 4
92+ enum napot_cont_order {
93+ NAPOT_CONT64KB_ORDER = NAPOT_CONT_ORDER_BASE ,
94+ NAPOT_ORDER_MAX ,
95+ };
96+
97+ #define for_each_napot_order (order ) \
98+ for (order = NAPOT_CONT_ORDER_BASE; order < NAPOT_ORDER_MAX; order++)
99+ #define for_each_napot_order_rev (order ) \
100+ for (order = NAPOT_ORDER_MAX - 1; \
101+ order >= NAPOT_CONT_ORDER_BASE; order--)
102+ #define napot_cont_order (val ) (__builtin_ctzl((val.pte >> _PAGE_PFN_SHIFT) << 1))
103+
104+ #define napot_cont_shift (order ) ((order) + PAGE_SHIFT)
105+ #define napot_cont_size (order ) BIT(napot_cont_shift(order))
106+ #define napot_cont_mask (order ) (~(napot_cont_size(order) - 1UL))
107+ #define napot_pte_num (order ) BIT(order)
108+
109+ #ifdef CONFIG_RISCV_ISA_SVNAPOT
110+ #define HUGE_MAX_HSTATE (2 + (NAPOT_ORDER_MAX - NAPOT_CONT_ORDER_BASE))
111+ #else
112+ #define HUGE_MAX_HSTATE 2
113+ #endif
114+
81115/*
82116 * [62:61] Svpbmt Memory Type definitions:
83117 *
Original file line number Diff line number Diff line change @@ -264,10 +264,47 @@ static inline pte_t pud_pte(pud_t pud)
264264 return __pte (pud_val (pud ));
265265}
266266
267+ #ifdef CONFIG_RISCV_ISA_SVNAPOT
268+
269+ static __always_inline bool has_svnapot (void )
270+ {
271+ return riscv_has_extension_likely (RISCV_ISA_EXT_SVNAPOT );
272+ }
273+
274+ static inline unsigned long pte_napot (pte_t pte )
275+ {
276+ return pte_val (pte ) & _PAGE_NAPOT ;
277+ }
278+
279+ static inline pte_t pte_mknapot (pte_t pte , unsigned int order )
280+ {
281+ int pos = order - 1 + _PAGE_PFN_SHIFT ;
282+ unsigned long napot_bit = BIT (pos );
283+ unsigned long napot_mask = ~GENMASK (pos , _PAGE_PFN_SHIFT );
284+
285+ return __pte ((pte_val (pte ) & napot_mask ) | napot_bit | _PAGE_NAPOT );
286+ }
287+
288+ #else
289+
290+ static __always_inline bool has_svnapot (void ) { return false; }
291+
292+ static inline unsigned long pte_napot (pte_t pte )
293+ {
294+ return 0 ;
295+ }
296+
297+ #endif /* CONFIG_RISCV_ISA_SVNAPOT */
298+
267299/* Yields the page frame number (PFN) of a page table entry */
268300static inline unsigned long pte_pfn (pte_t pte )
269301{
270- return __page_val_to_pfn (pte_val (pte ));
302+ unsigned long res = __page_val_to_pfn (pte_val (pte ));
303+
304+ if (has_svnapot () && pte_napot (pte ))
305+ res = res & (res - 1UL );
306+
307+ return res ;
271308}
272309
273310#define pte_page (x ) pfn_to_page(pte_pfn(x))
Original file line number Diff line number Diff line change @@ -191,6 +191,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
191191 __RISCV_ISA_EXT_DATA (sscofpmf , RISCV_ISA_EXT_SSCOFPMF ),
192192 __RISCV_ISA_EXT_DATA (sstc , RISCV_ISA_EXT_SSTC ),
193193 __RISCV_ISA_EXT_DATA (svinval , RISCV_ISA_EXT_SVINVAL ),
194+ __RISCV_ISA_EXT_DATA (svnapot , RISCV_ISA_EXT_SVNAPOT ),
194195 __RISCV_ISA_EXT_DATA (svpbmt , RISCV_ISA_EXT_SVPBMT ),
195196 __RISCV_ISA_EXT_DATA ("" , RISCV_ISA_EXT_MAX ),
196197};
Original file line number Diff line number Diff line change @@ -223,6 +223,7 @@ void __init riscv_fill_hwcap(void)
223223 SET_ISA_EXT_MAP ("sscofpmf" , RISCV_ISA_EXT_SSCOFPMF );
224224 SET_ISA_EXT_MAP ("sstc" , RISCV_ISA_EXT_SSTC );
225225 SET_ISA_EXT_MAP ("svinval" , RISCV_ISA_EXT_SVINVAL );
226+ SET_ISA_EXT_MAP ("svnapot" , RISCV_ISA_EXT_SVNAPOT );
226227 SET_ISA_EXT_MAP ("svpbmt" , RISCV_ISA_EXT_SVPBMT );
227228 SET_ISA_EXT_MAP ("zbb" , RISCV_ISA_EXT_ZBB );
228229 SET_ISA_EXT_MAP ("zicbom" , RISCV_ISA_EXT_ZICBOM );
You can’t perform that action at this time.
0 commit comments