]> www.infradead.org Git - linux.git/commitdiff
RISC-V: Add Svade and Svadu Extensions Support
authorYong-Xuan Wang <yongxuan.wang@sifive.com>
Fri, 26 Jul 2024 08:49:26 +0000 (16:49 +0800)
committerAnup Patel <anup@brainfault.org>
Thu, 21 Nov 2024 12:10:06 +0000 (17:40 +0530)
Svade and Svadu extensions represent two schemes for managing the PTE A/D
bits. When the PTE A/D bits need to be set, Svade extension intdicates
that a related page fault will be raised. In contrast, the Svadu extension
supports hardware updating of PTE A/D bits. Since the Svade extension is
mandatory and the Svadu extension is optional in RVA23 profile, by default
the M-mode firmware will enable the Svadu extension in the menvcfg CSR
when only Svadu is present in DT.

This patch detects Svade and Svadu extensions from DT and adds
arch_has_hw_pte_young() to enable optimization in MGLRU and
__wp_page_copy_user() when we have the PTE A/D bits hardware updating
support.

Co-developed-by: Jinyu Tang <tjytimi@163.com>
Signed-off-by: Jinyu Tang <tjytimi@163.com>
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
Link: https://lore.kernel.org/r/20240726084931.28924-2-yongxuan.wang@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
arch/riscv/Kconfig
arch/riscv/include/asm/csr.h
arch/riscv/include/asm/hwcap.h
arch/riscv/include/asm/pgtable.h
arch/riscv/kernel/cpufeature.c

index 62545946ecf432df5b41e235ba66438cd3743c06..2e499918e15ea726ff1272ba5c6076051d0cd16c 100644 (file)
@@ -32,6 +32,7 @@ config RISCV
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_HAS_GIGANTIC_PAGE
+       select ARCH_HAS_HW_PTE_YOUNG
        select ARCH_HAS_KCOV
        select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && FPU
        select ARCH_HAS_MEMBARRIER_CALLBACKS
index 25966995da04e090ff22a11e35be9bc24712f1a8..524cd4131c713d46200c1859d1c403a0c4c802a0 100644 (file)
 /* xENVCFG flags */
 #define ENVCFG_STCE                    (_AC(1, ULL) << 63)
 #define ENVCFG_PBMTE                   (_AC(1, ULL) << 62)
+#define ENVCFG_ADUE                    (_AC(1, ULL) << 61)
 #define ENVCFG_CBZE                    (_AC(1, UL) << 7)
 #define ENVCFG_CBCFE                   (_AC(1, UL) << 6)
 #define ENVCFG_CBIE_SHIFT              4
index 46d9de54179ed40aa7b1ea0ec011fd6eea7218df..7f72789ba3d5daec2414faefea38f52efb9145f1 100644 (file)
@@ -93,6 +93,8 @@
 #define RISCV_ISA_EXT_ZCMOP            84
 #define RISCV_ISA_EXT_ZAWRS            85
 #define RISCV_ISA_EXT_SVVPTC           86
+#define RISCV_ISA_EXT_SVADE            87
+#define RISCV_ISA_EXT_SVADU            88
 
 #define RISCV_ISA_EXT_XLINUXENVCFG     127
 
index e79f15293492d5dba31666d0d134cde9648abe4c..02aa7ee6def8b0b0dd0a3f9289ca4bf819b94aff 100644 (file)
 #include <asm/tlbflush.h>
 #include <linux/mm_types.h>
 #include <asm/compat.h>
+#include <asm/cpufeature.h>
 
 #define __page_val_to_pfn(_val)  (((_val) & _PAGE_PFN_MASK) >> _PAGE_PFN_SHIFT)
 
@@ -284,7 +285,6 @@ static inline pte_t pud_pte(pud_t pud)
 }
 
 #ifdef CONFIG_RISCV_ISA_SVNAPOT
-#include <asm/cpufeature.h>
 
 static __always_inline bool has_svnapot(void)
 {
@@ -655,6 +655,17 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
        return __pgprot(prot);
 }
 
+/*
+ * Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By
+ * default the M-mode firmware enables the hardware updating scheme when only Svadu is present in
+ * DT.
+ */
+#define arch_has_hw_pte_young arch_has_hw_pte_young
+static inline bool arch_has_hw_pte_young(void)
+{
+       return riscv_has_extension_unlikely(RISCV_ISA_EXT_SVADU);
+}
+
 /*
  * THP functions
  */
index 3a8eeaa9310c32fce2141aff534dc4432b32abbe..06ca264d481012669c50f582b8f8a63d48ab9724 100644 (file)
@@ -132,6 +132,16 @@ static int riscv_ext_zcf_validate(const struct riscv_isa_ext_data *data,
        return -EPROBE_DEFER;
 }
 
+static int riscv_ext_svadu_validate(const struct riscv_isa_ext_data *data,
+                                   const unsigned long *isa_bitmap)
+{
+       /* SVADE has already been detected, use SVADE only */
+       if (__riscv_isa_extension_available(isa_bitmap, RISCV_ISA_EXT_SVADE))
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
 static const unsigned int riscv_zk_bundled_exts[] = {
        RISCV_ISA_EXT_ZBKB,
        RISCV_ISA_EXT_ZBKC,
@@ -378,6 +388,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
        __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
        __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
        __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+       __RISCV_ISA_EXT_DATA(svade, RISCV_ISA_EXT_SVADE),
+       __RISCV_ISA_EXT_DATA_VALIDATE(svadu, RISCV_ISA_EXT_SVADU, riscv_ext_svadu_validate),
        __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),