[PATCH v1 1/4] mm: modify pte format for Svnapot
panqinglin2020 at iscas.ac.cn
panqinglin2020 at iscas.ac.cn
Mon Apr 11 07:15:33 PDT 2022
From: Qinglin Pan <panqinglin2020 at iscas.ac.cn>
This patch modifies 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 draft spec, so some macros
has only 64KB version.
Yours,
Qinglin
Signed-off-by: Qinglin Pan <panqinglin2020 at iscas.ac.cn>
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 00fd9c548f26..b86033f67610 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -343,6 +343,13 @@ config FPU
If you don't know what to do here, say Y.
+config SVNAPOT
+ bool "Svnapot support"
+ default n
+ help
+ Select if your CPU supports Svnapot and you want to enable it when
+ kernel is booting.
+
endmenu
menu "Kernel features"
diff --git a/arch/riscv/include/asm/pgtable-bits.h b/arch/riscv/include/asm/pgtable-bits.h
index a6b0c89824c2..b37934c60c4d 100644
--- a/arch/riscv/include/asm/pgtable-bits.h
+++ b/arch/riscv/include/asm/pgtable-bits.h
@@ -35,6 +35,37 @@
#define _PAGE_PFN_SHIFT 10
+#ifdef CONFIG_SVNAPOT
+#define _PAGE_RESERVE_0_SHIFT 54
+#define _PAGE_RESERVE_1_SHIFT 55
+#define _PAGE_RESERVE_2_SHIFT 56
+#define _PAGE_RESERVE_3_SHIFT 57
+#define _PAGE_RESERVE_4_SHIFT 58
+#define _PAGE_RESERVE_5_SHIFT 59
+#define _PAGE_RESERVE_6_SHIFT 60
+#define _PAGE_RESERVE_7_SHIFT 61
+#define _PAGE_RESERVE_8_SHIFT 62
+#define _PAGE_NAPOT_SHIFT 63
+#define _PAGE_RESERVE_0 (1UL << 54)
+#define _PAGE_RESERVE_1 (1UL << 55)
+#define _PAGE_RESERVE_2 (1UL << 56)
+#define _PAGE_RESERVE_3 (1UL << 57)
+#define _PAGE_RESERVE_4 (1UL << 58)
+#define _PAGE_RESERVE_5 (1UL << 59)
+#define _PAGE_RESERVE_6 (1UL << 60)
+#define _PAGE_RESERVE_7 (1UL << 61)
+#define _PAGE_RESERVE_8 (1UL << 62)
+#define _PAGE_PFN_MASK (_PAGE_RESERVE_0 - (1UL << _PAGE_PFN_SHIFT))
+/* now Svnapot only supports 64KB*/
+#define NAPOT_CONT64KB_ORDER 4UL
+#define NAPOT_CONT64KB_SHIFT (NAPOT_CONT64KB_ORDER + PAGE_SHIFT)
+#define NAPOT_CONT64KB_SIZE (1UL << NAPOT_CONT64KB_SHIFT)
+#define NAPOT_CONT64KB_MASK (NAPOT_CONT64KB_SIZE - 1)
+#define NAPOT_64KB_PTE_NUM (1UL << NAPOT_CONT64KB_ORDER)
+#define _PAGE_NAPOT (1UL << _PAGE_NAPOT_SHIFT)
+#define NAPOT_64KB_MASK (7UL << _PAGE_PFN_SHIFT)
+#endif /*CONFIG_SVNAPOT*/
+
/* Set of bits to preserve across pte_modify() */
#define _PAGE_CHG_MASK (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ | \
_PAGE_WRITE | _PAGE_EXEC | \
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 046b44225623..f72cdb64f427 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -279,11 +279,39 @@ static inline pte_t pud_pte(pud_t pud)
return __pte(pud_val(pud));
}
+#ifdef CONFIG_SVNAPOT
+/* Yields the page frame number (PFN) of a page table entry */
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ unsigned long val = pte_val(pte);
+ unsigned long is_napot = val >> _PAGE_NAPOT_SHIFT;
+ unsigned long pfn_field = (val & _PAGE_PFN_MASK) >> _PAGE_PFN_SHIFT;
+ unsigned long res = (pfn_field - is_napot) & pfn_field;
+ return res;
+}
+
+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)
+{
+ unsigned long napot_bits = (1UL << (order - 1)) << _PAGE_PFN_SHIFT;
+ unsigned long lower_prot =
+ pte_val(pte) & ((1UL << _PAGE_PFN_SHIFT) - 1UL);
+ unsigned long upper_prot = (pte_val(pte) >> _PAGE_PFN_SHIFT)
+ << _PAGE_PFN_SHIFT;
+
+ return __pte(upper_prot | napot_bits | lower_prot | _PAGE_NAPOT);
+}
+#else /* CONFIG_SVNAPOT */
/* Yields the page frame number (PFN) of a page table entry */
static inline unsigned long pte_pfn(pte_t pte)
{
return (pte_val(pte) >> _PAGE_PFN_SHIFT);
}
+#endif /* CONFIG_SVNAPOT */
#define pte_page(x) pfn_to_page(pte_pfn(x))
--
2.35.1
More information about the linux-riscv
mailing list