Skip to content

Commit 23ad288

Browse files
PanQLpalmer-dabbelt
authored andcommitted
riscv: mm: modify pte format for Svnapot
Add one alternative to enable/disable svnapot support, enable this static key when "svnapot" is in the "riscv,isa" field of fdt and SVNAPOT compile option is set. It will influence the behavior of has_svnapot. All code dependent on svnapot should make sure that has_svnapot return true firstly. Modify PTE definition for Svnapot, and creates some functions in pgtable.h to mark a PTE as napot and check if it is a Svnapot PTE. Until now, only 64KB napot size is supported in spec, so some macros has only 64KB version. Signed-off-by: Qinglin Pan <panqinglin00@gmail.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/20230209131647.17245-2-panqinglin00@gmail.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 9daca9a commit 23ad288

7 files changed

Lines changed: 98 additions & 10 deletions

File tree

arch/riscv/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
400419
config RISCV_ISA_SVPBMT
401420
bool "SVPBMT extension support"
402421
depends on 64BIT && MMU

arch/riscv/include/asm/hwcap.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@
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

arch/riscv/include/asm/page.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
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))

arch/riscv/include/asm/pgtable-64.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff 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
*

arch/riscv/include/asm/pgtable.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff 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 */
268300
static 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))

arch/riscv/kernel/cpu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff 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
};

arch/riscv/kernel/cpufeature.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff 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);

0 commit comments

Comments
 (0)