Unverified Commit 4a4c4598 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge patch series "riscv, mm: detect svnapot cpu support at runtime"

Qinglin Pan <panqinglin00@gmail.com> says:

Svnapot is a RISC-V extension for marking contiguous 4K pages as a non-4K
page. This patch set is for using Svnapot in hugetlb fs and huge vmap.

This patchset adds a Kconfig item for using Svnapot in
"Platform type"->"SVNAPOT extension support". Its default value is on,
and people can set it off if they don't allow kernel to detect Svnapot
hardware support and leverage it.

Tested on:
  - qemu rv64 with "Svnapot support" off and svnapot=true.
  - qemu rv64 with "Svnapot support" on and svnapot=true.
  - qemu rv64 with "Svnapot support" off and svnapot=false.
  - qemu rv64 with "Svnapot support" on and svnapot=false.

* b4-shazam-merge:
  riscv: mm: support Svnapot in huge vmap
  riscv: mm: support Svnapot in hugetlb page
  riscv: mm: modify pte format for Svnapot

Link: https://lore.kernel.org/r/20230209131647.17245-1-panqinglin00@gmail.com


[Palmer: fix up the feature ordering in the merge]
Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents fe15c26e ce173474
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ config RISCV
	select ARCH_USE_QUEUED_RWLOCKS
	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
	select ARCH_WANT_FRAME_POINTERS
	select ARCH_WANT_GENERAL_HUGETLB
	select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT
	select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
	select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
	select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL
@@ -398,6 +398,25 @@ config RISCV_ISA_C

	  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
	bool "SVPBMT extension support"
	depends on 64BIT && MMU
+33 −1
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@
#ifndef _ASM_RISCV_HUGETLB_H
#define _ASM_RISCV_HUGETLB_H

#include <asm-generic/hugetlb.h>
#include <asm/page.h>

static inline void arch_clear_hugepage_flags(struct page *page)
@@ -11,4 +10,37 @@ static inline void arch_clear_hugepage_flags(struct page *page)
}
#define arch_clear_hugepage_flags arch_clear_hugepage_flags

#ifdef CONFIG_RISCV_ISA_SVNAPOT
#define __HAVE_ARCH_HUGE_PTE_CLEAR
void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
		    pte_t *ptep, unsigned long sz);

#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT
void set_huge_pte_at(struct mm_struct *mm,
		     unsigned long addr, pte_t *ptep, pte_t pte);

#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
			      unsigned long addr, pte_t *ptep);

#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH
pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
			    unsigned long addr, pte_t *ptep);

#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT
void huge_ptep_set_wrprotect(struct mm_struct *mm,
			     unsigned long addr, pte_t *ptep);

#define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS
int huge_ptep_set_access_flags(struct vm_area_struct *vma,
			       unsigned long addr, pte_t *ptep,
			       pte_t pte, int dirty);

pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags);
#define arch_make_huge_pte arch_make_huge_pte

#endif /*CONFIG_RISCV_ISA_SVNAPOT*/

#include <asm-generic/hugetlb.h>

#endif /* _ASM_RISCV_HUGETLB_H */
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#define RISCV_ISA_EXT_ZBB		30
#define RISCV_ISA_EXT_ZICBOM		31
#define RISCV_ISA_EXT_ZIHINTPAUSE	32
#define RISCV_ISA_EXT_SVNAPOT		33

#define RISCV_ISA_EXT_MAX		64
#define RISCV_ISA_EXT_NAME_LEN_MAX	32
+0 −5
Original line number Diff line number Diff line
@@ -16,11 +16,6 @@
#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
#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_SIZE		(_AC(1, UL) << HPAGE_SHIFT)
#define HPAGE_MASK              (~(HPAGE_SIZE - 1))
+34 −0
Original line number Diff line number Diff line
@@ -78,6 +78,40 @@ typedef struct {
 */
#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:
 *
Loading