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>
This commit is contained in:
parent
9daca9a5b9
commit
23ad288aaf
|
@ -397,6 +397,25 @@ config RISCV_ISA_C
|
||||||
|
|
||||||
If you don't know what to do here, say Y.
|
If you don't know what to do here, say Y.
|
||||||
|
|
||||||
|
config RISCV_ISA_SVNAPOT
|
||||||
|
bool "SVNAPOT extension support"
|
||||||
|
depends on 64BIT && MMU
|
||||||
|
default y
|
||||||
|
select RISCV_ALTERNATIVE
|
||||||
|
help
|
||||||
|
Allow kernel to detect the SVNAPOT ISA-extension dynamically at boot
|
||||||
|
time and enable its usage.
|
||||||
|
|
||||||
|
The SVNAPOT extension is used to mark contiguous PTEs as a range
|
||||||
|
of contiguous virtual-to-physical translations for a naturally
|
||||||
|
aligned power-of-2 (NAPOT) granularity larger than the base 4KB page
|
||||||
|
size. When HUGETLBFS is also selected this option unconditionally
|
||||||
|
allocates some memory for each NAPOT page size supported by the kernel.
|
||||||
|
When optimizing for low memory consumption and for platforms without
|
||||||
|
the SVNAPOT extension, it may be better to say N here.
|
||||||
|
|
||||||
|
If you don't know what to do here, say Y.
|
||||||
|
|
||||||
config RISCV_ISA_SVPBMT
|
config RISCV_ISA_SVPBMT
|
||||||
bool "SVPBMT extension support"
|
bool "SVPBMT extension support"
|
||||||
depends on 64BIT && MMU
|
depends on 64BIT && MMU
|
||||||
|
|
|
@ -43,10 +43,11 @@
|
||||||
#define RISCV_ISA_EXT_SSCOFPMF 26
|
#define RISCV_ISA_EXT_SSCOFPMF 26
|
||||||
#define RISCV_ISA_EXT_SSTC 27
|
#define RISCV_ISA_EXT_SSTC 27
|
||||||
#define RISCV_ISA_EXT_SVINVAL 28
|
#define RISCV_ISA_EXT_SVINVAL 28
|
||||||
#define RISCV_ISA_EXT_SVPBMT 29
|
#define RISCV_ISA_EXT_SVNAPOT 29
|
||||||
#define RISCV_ISA_EXT_ZBB 30
|
#define RISCV_ISA_EXT_SVPBMT 30
|
||||||
#define RISCV_ISA_EXT_ZICBOM 31
|
#define RISCV_ISA_EXT_ZBB 31
|
||||||
#define RISCV_ISA_EXT_ZIHINTPAUSE 32
|
#define RISCV_ISA_EXT_ZICBOM 32
|
||||||
|
#define RISCV_ISA_EXT_ZIHINTPAUSE 33
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,6 @@
|
||||||
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
|
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
|
||||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
|
||||||
#define HUGE_MAX_HSTATE 2
|
|
||||||
#else
|
|
||||||
#define HUGE_MAX_HSTATE 1
|
|
||||||
#endif
|
|
||||||
#define HPAGE_SHIFT PMD_SHIFT
|
#define HPAGE_SHIFT PMD_SHIFT
|
||||||
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
|
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
|
||||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||||
|
|
|
@ -78,6 +78,40 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
#define _PAGE_PFN_MASK GENMASK(53, 10)
|
#define _PAGE_PFN_MASK GENMASK(53, 10)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [63] Svnapot definitions:
|
||||||
|
* 0 Svnapot disabled
|
||||||
|
* 1 Svnapot enabled
|
||||||
|
*/
|
||||||
|
#define _PAGE_NAPOT_SHIFT 63
|
||||||
|
#define _PAGE_NAPOT BIT(_PAGE_NAPOT_SHIFT)
|
||||||
|
/*
|
||||||
|
* Only 64KB (order 4) napot ptes supported.
|
||||||
|
*/
|
||||||
|
#define NAPOT_CONT_ORDER_BASE 4
|
||||||
|
enum napot_cont_order {
|
||||||
|
NAPOT_CONT64KB_ORDER = NAPOT_CONT_ORDER_BASE,
|
||||||
|
NAPOT_ORDER_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define for_each_napot_order(order) \
|
||||||
|
for (order = NAPOT_CONT_ORDER_BASE; order < NAPOT_ORDER_MAX; order++)
|
||||||
|
#define for_each_napot_order_rev(order) \
|
||||||
|
for (order = NAPOT_ORDER_MAX - 1; \
|
||||||
|
order >= NAPOT_CONT_ORDER_BASE; order--)
|
||||||
|
#define napot_cont_order(val) (__builtin_ctzl((val.pte >> _PAGE_PFN_SHIFT) << 1))
|
||||||
|
|
||||||
|
#define napot_cont_shift(order) ((order) + PAGE_SHIFT)
|
||||||
|
#define napot_cont_size(order) BIT(napot_cont_shift(order))
|
||||||
|
#define napot_cont_mask(order) (~(napot_cont_size(order) - 1UL))
|
||||||
|
#define napot_pte_num(order) BIT(order)
|
||||||
|
|
||||||
|
#ifdef CONFIG_RISCV_ISA_SVNAPOT
|
||||||
|
#define HUGE_MAX_HSTATE (2 + (NAPOT_ORDER_MAX - NAPOT_CONT_ORDER_BASE))
|
||||||
|
#else
|
||||||
|
#define HUGE_MAX_HSTATE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* [62:61] Svpbmt Memory Type definitions:
|
* [62:61] Svpbmt Memory Type definitions:
|
||||||
*
|
*
|
||||||
|
|
|
@ -264,10 +264,47 @@ static inline pte_t pud_pte(pud_t pud)
|
||||||
return __pte(pud_val(pud));
|
return __pte(pud_val(pud));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_RISCV_ISA_SVNAPOT
|
||||||
|
|
||||||
|
static __always_inline bool has_svnapot(void)
|
||||||
|
{
|
||||||
|
return riscv_has_extension_likely(RISCV_ISA_EXT_SVNAPOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long pte_napot(pte_t pte)
|
||||||
|
{
|
||||||
|
return pte_val(pte) & _PAGE_NAPOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pte_t pte_mknapot(pte_t pte, unsigned int order)
|
||||||
|
{
|
||||||
|
int pos = order - 1 + _PAGE_PFN_SHIFT;
|
||||||
|
unsigned long napot_bit = BIT(pos);
|
||||||
|
unsigned long napot_mask = ~GENMASK(pos, _PAGE_PFN_SHIFT);
|
||||||
|
|
||||||
|
return __pte((pte_val(pte) & napot_mask) | napot_bit | _PAGE_NAPOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static __always_inline bool has_svnapot(void) { return false; }
|
||||||
|
|
||||||
|
static inline unsigned long pte_napot(pte_t pte)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_RISCV_ISA_SVNAPOT */
|
||||||
|
|
||||||
/* Yields the page frame number (PFN) of a page table entry */
|
/* Yields the page frame number (PFN) of a page table entry */
|
||||||
static inline unsigned long pte_pfn(pte_t pte)
|
static inline unsigned long pte_pfn(pte_t pte)
|
||||||
{
|
{
|
||||||
return __page_val_to_pfn(pte_val(pte));
|
unsigned long res = __page_val_to_pfn(pte_val(pte));
|
||||||
|
|
||||||
|
if (has_svnapot() && pte_napot(pte))
|
||||||
|
res = res & (res - 1UL);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define pte_page(x) pfn_to_page(pte_pfn(x))
|
#define pte_page(x) pfn_to_page(pte_pfn(x))
|
||||||
|
|
|
@ -191,6 +191,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {
|
||||||
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
|
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
|
||||||
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
|
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
|
||||||
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
|
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
|
||||||
|
__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
|
||||||
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
|
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
|
||||||
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
|
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
|
||||||
};
|
};
|
||||||
|
|
|
@ -223,6 +223,7 @@ void __init riscv_fill_hwcap(void)
|
||||||
SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF);
|
SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF);
|
||||||
SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
|
SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
|
||||||
SET_ISA_EXT_MAP("svinval", RISCV_ISA_EXT_SVINVAL);
|
SET_ISA_EXT_MAP("svinval", RISCV_ISA_EXT_SVINVAL);
|
||||||
|
SET_ISA_EXT_MAP("svnapot", RISCV_ISA_EXT_SVNAPOT);
|
||||||
SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
|
SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
|
||||||
SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
|
SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
|
||||||
SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
|
SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
|
||||||
|
|
Loading…
Reference in New Issue