| #ifndef _ASM_RISCV_VMALLOC_H |
| #define _ASM_RISCV_VMALLOC_H |
| |
| #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP |
| |
| extern bool pgtable_l4_enabled, pgtable_l5_enabled; |
| |
| #define IOREMAP_MAX_ORDER (PUD_SHIFT) |
| |
| #define arch_vmap_pud_supported arch_vmap_pud_supported |
| static inline bool arch_vmap_pud_supported(pgprot_t prot) |
| { |
| return pgtable_l4_enabled || pgtable_l5_enabled; |
| } |
| |
| #define arch_vmap_pmd_supported arch_vmap_pmd_supported |
| static inline bool arch_vmap_pmd_supported(pgprot_t prot) |
| { |
| return true; |
| } |
| |
| #ifdef CONFIG_RISCV_ISA_SVNAPOT |
| #include <linux/pgtable.h> |
| |
| #define arch_vmap_pte_range_map_size arch_vmap_pte_range_map_size |
| static inline unsigned long arch_vmap_pte_range_map_size(unsigned long addr, unsigned long end, |
| u64 pfn, unsigned int max_page_shift) |
| { |
| unsigned long map_size = PAGE_SIZE; |
| unsigned long size, order; |
| |
| if (!has_svnapot()) |
| return map_size; |
| |
| for_each_napot_order_rev(order) { |
| if (napot_cont_shift(order) > max_page_shift) |
| continue; |
| |
| size = napot_cont_size(order); |
| if (end - addr < size) |
| continue; |
| |
| if (!IS_ALIGNED(addr, size)) |
| continue; |
| |
| if (!IS_ALIGNED(PFN_PHYS(pfn), size)) |
| continue; |
| |
| map_size = size; |
| break; |
| } |
| |
| return map_size; |
| } |
| |
| #define arch_vmap_pte_supported_shift arch_vmap_pte_supported_shift |
| static inline int arch_vmap_pte_supported_shift(unsigned long size) |
| { |
| int shift = PAGE_SHIFT; |
| unsigned long order; |
| |
| if (!has_svnapot()) |
| return shift; |
| |
| WARN_ON_ONCE(size >= PMD_SIZE); |
| |
| for_each_napot_order_rev(order) { |
| if (napot_cont_size(order) > size) |
| continue; |
| |
| if (!IS_ALIGNED(size, napot_cont_size(order))) |
| continue; |
| |
| shift = napot_cont_shift(order); |
| break; |
| } |
| |
| return shift; |
| } |
| |
| #endif /* CONFIG_RISCV_ISA_SVNAPOT */ |
| #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ |
| #endif /* _ASM_RISCV_VMALLOC_H */ |