riscv: Introduce structure that group all variables regarding kernel mapping
authorAlexandre Ghiti <alex@ghiti.fr>
Thu, 17 Jun 2021 13:53:07 +0000 (15:53 +0200)
committerPalmer Dabbelt <palmerdabbelt@google.com>
Tue, 6 Jul 2021 01:04:00 +0000 (18:04 -0700)
We have a lot of variables that are used to hold kernel mapping addresses,
offsets between physical and virtual mappings and some others used for XIP
kernels: they are all defined at different places in mm/init.c, so group
them into a single structure with, for some of them, more explicit and concise
names.

Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
arch/riscv/include/asm/page.h
arch/riscv/kernel/asm-offsets.c
arch/riscv/kernel/head.S
arch/riscv/kernel/kexec_relocate.S
arch/riscv/kernel/machine_kexec.c
arch/riscv/mm/init.c
arch/riscv/mm/physaddr.c
arch/riscv/mm/ptdump.c

index 5d4622a..cca8764 100644 (file)
@@ -79,46 +79,52 @@ typedef struct page *pgtable_t;
 #endif
 
 #ifdef CONFIG_MMU
-extern unsigned long va_pa_offset;
-#ifdef CONFIG_64BIT
-extern unsigned long va_kernel_pa_offset;
-#endif
-extern unsigned long va_kernel_xip_pa_offset;
 extern unsigned long pfn_base;
-extern uintptr_t load_sz;
 #define ARCH_PFN_OFFSET                (pfn_base)
 #else
-#define va_pa_offset           0
-#ifdef CONFIG_64BIT
-#define va_kernel_pa_offset    0
-#endif
-#define va_kernel_xip_pa_offset 0
 #define ARCH_PFN_OFFSET                (PAGE_OFFSET >> PAGE_SHIFT)
 #endif /* CONFIG_MMU */
 
-extern unsigned long kernel_virt_addr;
+struct kernel_mapping {
+       unsigned long virt_addr;
+       uintptr_t phys_addr;
+       uintptr_t size;
+       /* Offset between linear mapping virtual address and kernel load address */
+       unsigned long va_pa_offset;
+#ifdef CONFIG_64BIT
+       /* Offset between kernel mapping virtual address and kernel load address */
+       unsigned long va_kernel_pa_offset;
+#endif
+       unsigned long va_kernel_xip_pa_offset;
+#ifdef CONFIG_XIP_KERNEL
+       uintptr_t xiprom;
+       uintptr_t xiprom_sz;
+#endif
+};
+
+extern struct kernel_mapping kernel_map;
 
 #ifdef CONFIG_64BIT
 #define is_kernel_mapping(x)   \
-       ((x) >= kernel_virt_addr && (x) < (kernel_virt_addr + load_sz))
+       ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
 #define is_linear_mapping(x)   \
-       ((x) >= PAGE_OFFSET && (x) < kernel_virt_addr)
+       ((x) >= PAGE_OFFSET && (x) < kernel_map.virt_addr)
 
-#define linear_mapping_pa_to_va(x)     ((void *)((unsigned long)(x) + va_pa_offset))
+#define linear_mapping_pa_to_va(x)     ((void *)((unsigned long)(x) + kernel_map.va_pa_offset))
 #define kernel_mapping_pa_to_va(y)     ({                                              \
        unsigned long _y = y;                                                           \
        (_y >= CONFIG_PHYS_RAM_BASE) ?                                                  \
-               (void *)((unsigned long)(_y) + va_kernel_pa_offset + XIP_OFFSET) :      \
-               (void *)((unsigned long)(_y) + va_kernel_xip_pa_offset);                \
+               (void *)((unsigned long)(_y) + kernel_map.va_kernel_pa_offset + XIP_OFFSET) :   \
+               (void *)((unsigned long)(_y) + kernel_map.va_kernel_xip_pa_offset);             \
        })
 #define __pa_to_va_nodebug(x)          linear_mapping_pa_to_va(x)
 
-#define linear_mapping_va_to_pa(x)     ((unsigned long)(x) - va_pa_offset)
+#define linear_mapping_va_to_pa(x)     ((unsigned long)(x) - kernel_map.va_pa_offset)
 #define kernel_mapping_va_to_pa(y) ({                                          \
        unsigned long _y = y;                                                   \
-       (_y < kernel_virt_addr + XIP_OFFSET) ?                                  \
-               ((unsigned long)(_y) - va_kernel_xip_pa_offset) :               \
-               ((unsigned long)(_y) - va_kernel_pa_offset - XIP_OFFSET);       \
+       (_y < kernel_map.virt_addr + XIP_OFFSET) ?                                      \
+               ((unsigned long)(_y) - kernel_map.va_kernel_xip_pa_offset) :            \
+               ((unsigned long)(_y) - kernel_map.va_kernel_pa_offset - XIP_OFFSET);    \
        })
 
 #define __va_to_pa_nodebug(x)  ({                                              \
@@ -128,12 +134,12 @@ extern unsigned long kernel_virt_addr;
        })
 #else
 #define is_kernel_mapping(x)   \
-       ((x) >= kernel_virt_addr && (x) < (kernel_virt_addr + load_sz))
+       ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
 #define is_linear_mapping(x)   \
        ((x) >= PAGE_OFFSET)
 
-#define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + va_pa_offset))
-#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - va_pa_offset)
+#define __pa_to_va_nodebug(x)  ((void *)((unsigned long) (x) + kernel_map.va_pa_offset))
+#define __va_to_pa_nodebug(x)  ((unsigned long)(x) - kernel_map.va_pa_offset)
 #endif /* CONFIG_64BIT */
 
 #ifdef CONFIG_DEBUG_VIRTUAL
index 9ef3334..90f8ce6 100644 (file)
@@ -311,4 +311,6 @@ void asm_offsets(void)
         * ensures the alignment is sane.
         */
        DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN));
+
+       OFFSET(KERNEL_MAP_VIRT_ADDR, kernel_mapping, virt_addr);
 }
index 89cc58a..fce5184 100644 (file)
@@ -81,9 +81,9 @@ pe_head_start:
 #ifdef CONFIG_MMU
 relocate:
        /* Relocate return address */
-       la a1, kernel_virt_addr
+       la a1, kernel_map
        XIP_FIXUP_OFFSET a1
-       REG_L a1, 0(a1)
+       REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
        la a2, _start
        sub a1, a1, a2
        add ra, ra, a1
index 88c3bea..a80b52a 100644 (file)
@@ -20,7 +20,7 @@ SYM_CODE_START(riscv_kexec_relocate)
         * s4: Pointer to the destination address for the relocation
         * s5: (const) Number of words per page
         * s6: (const) 1, used for subtraction
-        * s7: (const) va_pa_offset, used when switching MMU off
+        * s7: (const) kernel_map.va_pa_offset, used when switching MMU off
         * s8: (const) Physical address of the main loop
         * s9: (debug) indirection page counter
         * s10: (debug) entry counter
@@ -159,7 +159,7 @@ SYM_CODE_START(riscv_kexec_norelocate)
         * s0: (const) Phys address to jump to
         * s1: (const) Phys address of the FDT image
         * s2: (const) The hartid of the current hart
-        * s3: (const) va_pa_offset, used when switching MMU off
+        * s3: (const) kernel_map.va_pa_offset, used when switching MMU off
         */
        mv      s0, a1
        mv      s1, a2
index cc04814..3e39fd9 100644 (file)
@@ -188,6 +188,6 @@ machine_kexec(struct kimage *image)
        /* Jump to the relocation code */
        pr_notice("Bye...\n");
        kexec_method(first_ind_entry, jump_addr, fdt_addr,
-                    this_hart_id, va_pa_offset);
+                    this_hart_id, kernel_map.va_pa_offset);
        unreachable();
 }
index 12f956b..269fc64 100644 (file)
 
 #include "../kernel/head.h"
 
-unsigned long kernel_virt_addr = KERNEL_LINK_ADDR;
-EXPORT_SYMBOL(kernel_virt_addr);
+struct kernel_mapping kernel_map __ro_after_init;
+EXPORT_SYMBOL(kernel_map);
+#ifdef CONFIG_XIP_KERNEL
+#define kernel_map     (*(struct kernel_mapping *)XIP_FIXUP(&kernel_map))
+#endif
+
 #ifdef CONFIG_XIP_KERNEL
-#define kernel_virt_addr       (*((unsigned long *)XIP_FIXUP(&kernel_virt_addr)))
 extern char _xiprom[], _exiprom[];
 #endif
 
@@ -211,25 +214,6 @@ static struct pt_alloc_ops _pt_ops __initdata;
 #define pt_ops _pt_ops
 #endif
 
-/* Offset between linear mapping virtual address and kernel load address */
-unsigned long va_pa_offset __ro_after_init;
-EXPORT_SYMBOL(va_pa_offset);
-#ifdef CONFIG_XIP_KERNEL
-#define va_pa_offset   (*((unsigned long *)XIP_FIXUP(&va_pa_offset)))
-#endif
-/* Offset between kernel mapping virtual address and kernel load address */
-#ifdef CONFIG_64BIT
-unsigned long va_kernel_pa_offset __ro_after_init;
-EXPORT_SYMBOL(va_kernel_pa_offset);
-#endif
-#ifdef CONFIG_XIP_KERNEL
-#define va_kernel_pa_offset    (*((unsigned long *)XIP_FIXUP(&va_kernel_pa_offset)))
-#endif
-unsigned long va_kernel_xip_pa_offset __ro_after_init;
-EXPORT_SYMBOL(va_kernel_xip_pa_offset);
-#ifdef CONFIG_XIP_KERNEL
-#define va_kernel_xip_pa_offset        (*((unsigned long *)XIP_FIXUP(&va_kernel_xip_pa_offset)))
-#endif
 unsigned long pfn_base __ro_after_init;
 EXPORT_SYMBOL(pfn_base);
 
@@ -345,7 +329,7 @@ static pmd_t *__init get_pmd_virt_late(phys_addr_t pa)
 
 static phys_addr_t __init alloc_pmd_early(uintptr_t va)
 {
-       BUG_ON((va - kernel_virt_addr) >> PGDIR_SHIFT);
+       BUG_ON((va - kernel_map.virt_addr) >> PGDIR_SHIFT);
 
        return (uintptr_t)early_pmd;
 }
@@ -510,36 +494,24 @@ static __init pgprot_t pgprot_from_va(uintptr_t va)
 #error "setup_vm() is called from head.S before relocate so it should not use absolute addressing."
 #endif
 
-static uintptr_t load_pa __initdata;
-uintptr_t load_sz;
-#ifdef CONFIG_XIP_KERNEL
-#define load_pa        (*((uintptr_t *)XIP_FIXUP(&load_pa)))
-#define load_sz        (*((uintptr_t *)XIP_FIXUP(&load_sz)))
-#endif
-
 #ifdef CONFIG_XIP_KERNEL
-static uintptr_t xiprom __initdata;
-static uintptr_t xiprom_sz __initdata;
-#define xiprom_sz      (*((uintptr_t *)XIP_FIXUP(&xiprom_sz)))
-#define xiprom         (*((uintptr_t *)XIP_FIXUP(&xiprom)))
-
 static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size,
                                            __always_unused bool early)
 {
        uintptr_t va, end_va;
 
        /* Map the flash resident part */
-       end_va = kernel_virt_addr + xiprom_sz;
-       for (va = kernel_virt_addr; va < end_va; va += map_size)
+       end_va = kernel_map.virt_addr + kernel_map.xiprom_sz;
+       for (va = kernel_map.virt_addr; va < end_va; va += map_size)
                create_pgd_mapping(pgdir, va,
-                                  xiprom + (va - kernel_virt_addr),
+                                  kernel_map.xiprom + (va - kernel_map.virt_addr),
                                   map_size, PAGE_KERNEL_EXEC);
 
        /* Map the data in RAM */
-       end_va = kernel_virt_addr + XIP_OFFSET + load_sz;
-       for (va = kernel_virt_addr + XIP_OFFSET; va < end_va; va += map_size)
+       end_va = kernel_map.virt_addr + XIP_OFFSET + kernel_map.size;
+       for (va = kernel_map.virt_addr + XIP_OFFSET; va < end_va; va += map_size)
                create_pgd_mapping(pgdir, va,
-                                  load_pa + (va - (kernel_virt_addr + XIP_OFFSET)),
+                                  kernel_map.phys_addr + (va - (kernel_map.virt_addr + XIP_OFFSET)),
                                   map_size, PAGE_KERNEL);
 }
 #else
@@ -548,10 +520,10 @@ static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size,
 {
        uintptr_t va, end_va;
 
-       end_va = kernel_virt_addr + load_sz;
-       for (va = kernel_virt_addr; va < end_va; va += map_size)
+       end_va = kernel_map.virt_addr + kernel_map.size;
+       for (va = kernel_map.virt_addr; va < end_va; va += map_size)
                create_pgd_mapping(pgdir, va,
-                                  load_pa + (va - kernel_virt_addr),
+                                  kernel_map.phys_addr + (va - kernel_map.virt_addr),
                                   map_size,
                                   early ?
                                        PAGE_KERNEL_EXEC : pgprot_from_va(va));
@@ -566,25 +538,27 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
        pmd_t fix_bmap_spmd, fix_bmap_epmd;
 #endif
 
+       kernel_map.virt_addr = KERNEL_LINK_ADDR;
+
 #ifdef CONFIG_XIP_KERNEL
-       xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
-       xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
+       kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
+       kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
 
-       load_pa = (uintptr_t)CONFIG_PHYS_RAM_BASE;
-       load_sz = (uintptr_t)(&_end) - (uintptr_t)(&_sdata);
+       kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
+       kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_sdata);
 
-       va_kernel_xip_pa_offset = kernel_virt_addr - xiprom;
+       kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
 #else
-       load_pa = (uintptr_t)(&_start);
-       load_sz = (uintptr_t)(&_end) - load_pa;
+       kernel_map.phys_addr = (uintptr_t)(&_start);
+       kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr;
 #endif
 
-       va_pa_offset = PAGE_OFFSET - load_pa;
+       kernel_map.va_pa_offset = PAGE_OFFSET - kernel_map.phys_addr;
 #ifdef CONFIG_64BIT
-       va_kernel_pa_offset = kernel_virt_addr - load_pa;
+       kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
 #endif
 
-       pfn_base = PFN_DOWN(load_pa);
+       pfn_base = PFN_DOWN(kernel_map.phys_addr);
 
        /*
         * Enforce boot alignment requirements of RV32 and
@@ -594,7 +568,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 
        /* Sanity check alignment and size */
        BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0);
-       BUG_ON((load_pa % map_size) != 0);
+       BUG_ON((kernel_map.phys_addr % map_size) != 0);
 
        pt_ops.alloc_pte = alloc_pte_early;
        pt_ops.get_pte_virt = get_pte_virt_early;
@@ -611,19 +585,19 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
        create_pmd_mapping(fixmap_pmd, FIXADDR_START,
                           (uintptr_t)fixmap_pte, PMD_SIZE, PAGE_TABLE);
        /* Setup trampoline PGD and PMD */
-       create_pgd_mapping(trampoline_pg_dir, kernel_virt_addr,
+       create_pgd_mapping(trampoline_pg_dir, kernel_map.virt_addr,
                           (uintptr_t)trampoline_pmd, PGDIR_SIZE, PAGE_TABLE);
 #ifdef CONFIG_XIP_KERNEL
-       create_pmd_mapping(trampoline_pmd, kernel_virt_addr,
-                          xiprom, PMD_SIZE, PAGE_KERNEL_EXEC);
+       create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
+                          kernel_map.xiprom, PMD_SIZE, PAGE_KERNEL_EXEC);
 #else
-       create_pmd_mapping(trampoline_pmd, kernel_virt_addr,
-                          load_pa, PMD_SIZE, PAGE_KERNEL_EXEC);
+       create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
+                          kernel_map.phys_addr, PMD_SIZE, PAGE_KERNEL_EXEC);
 #endif
 #else
        /* Setup trampoline PGD */
-       create_pgd_mapping(trampoline_pg_dir, kernel_virt_addr,
-                          load_pa, PGDIR_SIZE, PAGE_KERNEL_EXEC);
+       create_pgd_mapping(trampoline_pg_dir, kernel_map.virt_addr,
+                          kernel_map.phys_addr, PGDIR_SIZE, PAGE_KERNEL_EXEC);
 #endif
 
        /*
index 35703d5..e7fd0c2 100644 (file)
@@ -23,7 +23,7 @@ EXPORT_SYMBOL(__virt_to_phys);
 
 phys_addr_t __phys_addr_symbol(unsigned long x)
 {
-       unsigned long kernel_start = (unsigned long)kernel_virt_addr;
+       unsigned long kernel_start = kernel_map.virt_addr;
        unsigned long kernel_end = (unsigned long)_end;
 
        /*
index 0536ac8..ee4e5c1 100644 (file)
@@ -379,7 +379,7 @@ static int __init ptdump_init(void)
        address_markers[PAGE_OFFSET_NR].start_address = PAGE_OFFSET;
 #ifdef CONFIG_64BIT
        address_markers[MODULES_MAPPING_NR].start_address = MODULES_VADDR;
-       address_markers[KERNEL_MAPPING_NR].start_address = kernel_virt_addr;
+       address_markers[KERNEL_MAPPING_NR].start_address = kernel_map.virt_addr;
 #endif
 
        kernel_ptd_info.base_addr = KERN_VIRT_START;