Message ID | 20220822153413.4038052-5-panqinglin2020@iscas.ac.cn (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | riscv, mm: detect svnapot cpu support at runtime | expand |
On 22/08/2022 16:34, panqinglin2020@iscas.ac.cn wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > > From: Qinglin Pan <panqinglin2020@iscas.ac.cn> > > The HAVE_ARCH_HUGE_VMAP option can be used to help implement arch > special huge vmap size. This commit selects this option by default and > re-writes the arch_vmap_pte_range_map_size for Svnapot 64KB size. > > It can be tested when booting kernel in qemu with pci device, which > will make the kernel to call pci driver using ioremap, and the > re-written function will be called. > > Signed-off-by: Qinglin Pan <panqinglin2020@iscas.ac.cn> > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 9aaec147a860..a420325a24ac 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -70,6 +70,7 @@ config RISCV > select GENERIC_TIME_VSYSCALL if MMU && 64BIT > select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO > select HAVE_ARCH_AUDITSYSCALL > + select HAVE_ARCH_HUGE_VMAP > select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL > select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL > select HAVE_ARCH_KASAN if MMU && 64BIT > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h > index 37547dd04010..6d5caa1a6bd9 100644 > --- a/arch/riscv/include/asm/pgtable.h > +++ b/arch/riscv/include/asm/pgtable.h > @@ -750,6 +750,43 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, > } > #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ > > +static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) > +{ > + return 0; > +} > + > +static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) > +{ > + return 0; > +} > + > +static inline void p4d_clear_huge(p4d_t *p4d) { } > + > +static inline int pud_clear_huge(pud_t *pud) > +{ > + return 0; > +} > + > +static inline int pmd_clear_huge(pmd_t *pmd) > +{ > + return 0; > +} > + > +static inline int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) > +{ > + return 0; > +} > + > +static inline int pud_free_pmd_page(pud_t *pud, unsigned long addr) > +{ > + return 0; > +} > + > +static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) > +{ > + return 0; > +} > + > /* > * Encode and decode a swap entry > * > diff --git a/arch/riscv/include/asm/vmalloc.h b/arch/riscv/include/asm/vmalloc.h > index ff9abc00d139..d92880fbfcde 100644 > --- a/arch/riscv/include/asm/vmalloc.h > +++ b/arch/riscv/include/asm/vmalloc.h > @@ -1,4 +1,26 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > #ifndef _ASM_RISCV_VMALLOC_H > #define _ASM_RISCV_VMALLOC_H > > +#include <linux/pgtable.h> > + > +#ifdef CONFIG_SVNAPOT > +#define arch_vmap_pte_range_map_size vmap_pte_range_map_size > +static inline unsigned long vmap_pte_range_map_size(unsigned long addr, > + unsigned long end, > + u64 pfn, > + unsigned int max_page_shift) How about: static inline unsigned long vmap_pte_range_map_size(unsigned long addr, unsigned long end, u64 pfn, unsigned int max_page_shift) { ? > +{ > + bool is_napot_addr = !(addr & NAPOT_CONT64KB_MASK); > + bool pfn_align_napot = !(pfn & (NAPOT_64KB_PTE_NUM - 1UL)); > + bool space_enough = ((end - addr) >= NAPOT_CONT64KB_SIZE); > + tbh I would rather see this early return for each of these failed tests rather than lump them all into the below. Prob can do the same for each of them.. Personally I find that more readable than what you have here. /shrug Thanks, Conor. > + if (has_svnapot() && is_napot_addr && pfn_align_napot && > + space_enough && max_page_shift >= NAPOT_CONT64KB_SHIFT) > + return NAPOT_CONT64KB_SIZE; > + > + return PAGE_SIZE; > +} > +#endif /*CONFIG_SVNAPOT*/ > + > #endif /* _ASM_RISCV_VMALLOC_H */ > -- > 2.35.1 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 9aaec147a860..a420325a24ac 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -70,6 +70,7 @@ config RISCV select GENERIC_TIME_VSYSCALL if MMU && 64BIT select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_HUGE_VMAP select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL select HAVE_ARCH_KASAN if MMU && 64BIT diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 37547dd04010..6d5caa1a6bd9 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -750,6 +750,43 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma, } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) +{ + return 0; +} + +static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) +{ + return 0; +} + +static inline void p4d_clear_huge(p4d_t *p4d) { } + +static inline int pud_clear_huge(pud_t *pud) +{ + return 0; +} + +static inline int pmd_clear_huge(pmd_t *pmd) +{ + return 0; +} + +static inline int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) +{ + return 0; +} + +static inline int pud_free_pmd_page(pud_t *pud, unsigned long addr) +{ + return 0; +} + +static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) +{ + return 0; +} + /* * Encode and decode a swap entry * diff --git a/arch/riscv/include/asm/vmalloc.h b/arch/riscv/include/asm/vmalloc.h index ff9abc00d139..d92880fbfcde 100644 --- a/arch/riscv/include/asm/vmalloc.h +++ b/arch/riscv/include/asm/vmalloc.h @@ -1,4 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef _ASM_RISCV_VMALLOC_H #define _ASM_RISCV_VMALLOC_H +#include <linux/pgtable.h> + +#ifdef CONFIG_SVNAPOT +#define arch_vmap_pte_range_map_size vmap_pte_range_map_size +static inline unsigned long vmap_pte_range_map_size(unsigned long addr, + unsigned long end, + u64 pfn, + unsigned int max_page_shift) +{ + bool is_napot_addr = !(addr & NAPOT_CONT64KB_MASK); + bool pfn_align_napot = !(pfn & (NAPOT_64KB_PTE_NUM - 1UL)); + bool space_enough = ((end - addr) >= NAPOT_CONT64KB_SIZE); + + if (has_svnapot() && is_napot_addr && pfn_align_napot && + space_enough && max_page_shift >= NAPOT_CONT64KB_SHIFT) + return NAPOT_CONT64KB_SIZE; + + return PAGE_SIZE; +} +#endif /*CONFIG_SVNAPOT*/ + #endif /* _ASM_RISCV_VMALLOC_H */