OSDN Git Service

Merge patch series "riscv: Use PUD/P4D/PGD pages for the linear mapping"
authorPalmer Dabbelt <palmer@rivosinc.com>
Wed, 19 Apr 2023 03:43:07 +0000 (20:43 -0700)
committerPalmer Dabbelt <palmer@rivosinc.com>
Wed, 19 Apr 2023 03:43:07 +0000 (20:43 -0700)
Alexandre Ghiti <alexghiti@rivosinc.com> says:

This patchset intends to improve tlb utilization by using hugepages for
the linear mapping.

As reported by Anup in v6, when STRICT_KERNEL_RWX is enabled, we must
take care of isolating the kernel text and rodata so that they are not
mapped with a PUD mapping which would then assign wrong permissions to
the whole region: it is achieved the same way as arm64 by using the
memblock nomap API which isolates those regions and re-merge them afterwards
thus avoiding any issue with the system resources tree creation.

arch/riscv/include/asm/page.h |  19 ++++++-
 arch/riscv/mm/init.c          | 102 ++++++++++++++++++++++++++--------
 arch/riscv/mm/physaddr.c      |  16 ++++++
 drivers/of/fdt.c              |  11 ++--
 4 files changed, 118 insertions(+), 30 deletions(-)

* b4-shazam-merge:
  riscv: Use PUD/P4D/PGD pages for the linear mapping
  riscv: Move the linear mapping creation in its own function
  riscv: Get rid of riscv_pfn_base variable

Link: https://lore.kernel.org/r/20230324155421.271544-1-alexghiti@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1  2 
arch/riscv/include/asm/page.h

  #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))
  
  #ifndef __ASSEMBLY__
  
 +#ifdef CONFIG_RISCV_ISA_ZICBOZ
 +void clear_page(void *page);
 +#else
  #define clear_page(pgaddr)                    memset((pgaddr), 0, PAGE_SIZE)
 +#endif
  #define copy_page(to, from)                   memcpy((to), (from), PAGE_SIZE)
  
 -#define clear_user_page(pgaddr, vaddr, page)  memset((pgaddr), 0, PAGE_SIZE)
 +#define clear_user_page(pgaddr, vaddr, page)  clear_page(pgaddr)
  #define copy_user_page(vto, vfrom, vaddr, topg) \
                        memcpy((vto), (vfrom), PAGE_SIZE)
  
@@@ -89,9 -90,16 +89,16 @@@ typedef struct page *pgtable_t
  #define PTE_FMT "%08lx"
  #endif
  
+ #ifdef CONFIG_64BIT
+ /*
+  * We override this value as its generic definition uses __pa too early in
+  * the boot process (before kernel_map.va_pa_offset is set).
+  */
+ #define MIN_MEMBLOCK_ADDR      0
+ #endif
  #ifdef CONFIG_MMU
- extern unsigned long riscv_pfn_base;
- #define ARCH_PFN_OFFSET               (riscv_pfn_base)
+ #define ARCH_PFN_OFFSET               (PFN_DOWN((unsigned long)phys_ram_base))
  #else
  #define ARCH_PFN_OFFSET               (PAGE_OFFSET >> PAGE_SHIFT)
  #endif /* CONFIG_MMU */
@@@ -121,7 -129,11 +128,11 @@@ extern phys_addr_t phys_ram_base
  #define is_linear_mapping(x)  \
        ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < PAGE_OFFSET + KERN_VIRT_SIZE))
  
+ #ifndef CONFIG_DEBUG_VIRTUAL
  #define linear_mapping_pa_to_va(x)    ((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
+ #else
+ void *linear_mapping_pa_to_va(unsigned long x);
+ #endif
  #define kernel_mapping_pa_to_va(y)    ({                                      \
        unsigned long _y = (unsigned long)(y);                                  \
        (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ?                 \
        })
  #define __pa_to_va_nodebug(x)         linear_mapping_pa_to_va(x)
  
+ #ifndef CONFIG_DEBUG_VIRTUAL
  #define linear_mapping_va_to_pa(x)    ((unsigned long)(x) - kernel_map.va_pa_offset)
+ #else
+ phys_addr_t linear_mapping_va_to_pa(unsigned long x);
+ #endif
  #define kernel_mapping_va_to_pa(y) ({                                         \
        unsigned long _y = (unsigned long)(y);                                  \
        (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \