Unverified Commit ff689fd2 authored by Heiko Stuebner's avatar Heiko Stuebner Committed by Palmer Dabbelt
Browse files

riscv: add RISC-V Svpbmt extension support



Svpbmt (the S should be capitalized) is the
"Supervisor-mode: page-based memory types" extension
that specifies attributes for cacheability, idempotency
and ordering.

The relevant settings are done in special bits in PTEs:

Here is the svpbmt PTE format:
| 63 | 62-61 | 60-8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
  N     MT     RSW    D   A   G   U   X   W   R   V
        ^

Of the Reserved bits [63:54] in a leaf PTE, the high bit is already
allocated (as the N bit), so bits [62:61] are used as the MT (aka
MemType) field. This field specifies one of three memory types that
are close equivalents (or equivalent in effect) to the three main x86
and ARMv8 memory types - as shown in the following table.

RISC-V
Encoding &
MemType     RISC-V Description
----------  ------------------------------------------------
00 - PMA    Normal Cacheable, No change to implied PMA memory type
01 - NC     Non-cacheable, idempotent, weakly-ordered Main Memory
10 - IO     Non-cacheable, non-idempotent, strongly-ordered I/O memory
11 - Rsvd   Reserved for future standard use

As the extension will not be present on all implementations,
implement a method to handle cpufeatures via alternatives
to not incur runtime penalties on cpu variants not supporting
specific extensions and patch relevant code parts at runtime.

Co-developed-by: default avatarWei Fu <wefu@redhat.com>
Signed-off-by: default avatarWei Fu <wefu@redhat.com>
Co-developed-by: default avatarLiu Shaohua <liush@allwinnertech.com>
Signed-off-by: default avatarLiu Shaohua <liush@allwinnertech.com>
Co-developed-by: default avatarGuo Ren <guoren@kernel.org>
Signed-off-by: default avatarGuo Ren <guoren@kernel.org>
[moved to use the alternatives mechanism]
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Reviewed-by: default avatarPhilipp Tomsich <philipp.tomsich@vrull.eu>
Link: https://lore.kernel.org/r/20220511192921.2223629-10-heiko@sntech.de


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 100631b4
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -343,6 +343,19 @@ config RISCV_ISA_C

	   If you don't know what to do here, say Y.

config RISCV_ISA_SVPBMT
	bool "SVPBMT extension support"
	depends on 64BIT && MMU
	select RISCV_ALTERNATIVE
	default y
	help
	   Adds support to dynamically detect the presence of the SVPBMT extension
	   (Supervisor-mode: page-based memory types) and enable its usage.

	   The SVPBMT extension is only available on 64Bit cpus.

	   If you don't know what to do here, say Y.

config FPU
	bool "FPU support"
	default y
+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
			      unsigned long archid, unsigned long impid,
			      unsigned int stage);

void riscv_cpufeature_patch_func(struct alt_entry *begin, struct alt_entry *end,
				 unsigned int stage);

#else /* CONFIG_RISCV_ALTERNATIVE */

static inline void apply_boot_alternatives(void) { }
+15 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
#define	ERRATA_SIFIVE_NUMBER 2
#endif

#define	CPUFEATURE_SVPBMT 0
#define	CPUFEATURE_NUMBER 1

#ifdef __ASSEMBLY__

#define ALT_INSN_FAULT(x)						\
@@ -34,6 +37,18 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
		: : "r" (addr) : "memory")

/*
 * _val is marked as "will be overwritten", so need to set it to 0
 * in the default case.
 */
#define ALT_SVPBMT_SHIFT 61
#define ALT_SVPBMT(_val, prot)						\
asm(ALTERNATIVE("li %0, 0\t\nnop", "li %0, %1\t\nslli %0,%0,%2", 0,	\
		CPUFEATURE_SVPBMT, CONFIG_RISCV_ISA_SVPBMT)		\
		: "=r"(_val)						\
		: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),		\
		  "I"(ALT_SVPBMT_SHIFT))

#endif /* __ASSEMBLY__ */

#endif
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ extern unsigned long elf_hwcap;
 */
enum riscv_isa_ext_id {
	RISCV_ISA_EXT_SSCOFPMF = RISCV_ISA_EXT_BASE,
	RISCV_ISA_EXT_SVPBMT,
	RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
};

+9 −0
Original line number Diff line number Diff line
@@ -24,4 +24,13 @@
 */
#define _PAGE_PFN_MASK  GENMASK(31, 10)

#define _PAGE_NOCACHE		0
#define _PAGE_IO		0
#define _PAGE_MTMASK		0

/* Set of bits to preserve across pte_modify() */
#define _PAGE_CHG_MASK  (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ |	\
					  _PAGE_WRITE | _PAGE_EXEC |	\
					  _PAGE_USER | _PAGE_GLOBAL))

#endif /* _ASM_RISCV_PGTABLE_32_H */
Loading