Skip to content

Commit 5cf0896

Browse files
covanampalmer-dabbelt
authored andcommitted
riscv: replace misleading va_kernel_pa_offset on XIP kernel
On XIP kernel, the name "va_kernel_pa_offset" is misleading: unlike "normal" kernel, it is not the virtual-physical address offset of kernel mapping, it is the offset of kernel mapping's first virtual address to first physical address in DRAM, which is not meaningful because the kernel's first physical address is not in DRAM. For XIP kernel, there are 2 different offsets because the read-only part of the kernel resides in ROM while the rest is in RAM. The offset to ROM is in kernel_map.va_kernel_xip_pa_offset, while the offset to RAM is not stored anywhere: it is calculated on-the-fly. Remove this confusing "va_kernel_pa_offset" and add "va_kernel_xip_data_pa_offset" as its replacement. This new variable is the offset of virtual mapping of the kernel's data portion to the corresponding physical addresses. With the introduction of this new variable, also rename va_kernel_xip_pa_offset -> va_kernel_xip_text_pa_offset to make it clear that this one is about the .text section. Signed-off-by: Nam Cao <[email protected]> Reviewed-by: Alexandre Ghiti <[email protected]> Link: https://lore.kernel.org/r/84e5d005c1386d88d7b2531e0b6707ec5352ee54.1717789719.git.namcao@linutronix.de Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent f2df5b4 commit 5cf0896

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

arch/riscv/include/asm/page.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,13 @@ struct kernel_mapping {
112112
/* Offset between linear mapping virtual address and kernel load address */
113113
unsigned long va_pa_offset;
114114
/* Offset between kernel mapping virtual address and kernel load address */
115-
unsigned long va_kernel_pa_offset;
116-
unsigned long va_kernel_xip_pa_offset;
117115
#ifdef CONFIG_XIP_KERNEL
116+
unsigned long va_kernel_xip_text_pa_offset;
117+
unsigned long va_kernel_xip_data_pa_offset;
118118
uintptr_t xiprom;
119119
uintptr_t xiprom_sz;
120+
#else
121+
unsigned long va_kernel_pa_offset;
120122
#endif
121123
};
122124

@@ -134,25 +136,36 @@ extern phys_addr_t phys_ram_base;
134136
#else
135137
void *linear_mapping_pa_to_va(unsigned long x);
136138
#endif
139+
140+
#ifdef CONFIG_XIP_KERNEL
137141
#define kernel_mapping_pa_to_va(y) ({ \
138142
unsigned long _y = (unsigned long)(y); \
139-
(IS_ENABLED(CONFIG_XIP_KERNEL) && _y < phys_ram_base) ? \
140-
(void *)(_y + kernel_map.va_kernel_xip_pa_offset) : \
141-
(void *)(_y + kernel_map.va_kernel_pa_offset + XIP_OFFSET); \
143+
(_y < phys_ram_base) ? \
144+
(void *)(_y + kernel_map.va_kernel_xip_text_pa_offset) : \
145+
(void *)(_y + kernel_map.va_kernel_xip_data_pa_offset); \
142146
})
147+
#else
148+
#define kernel_mapping_pa_to_va(y) ((void *)((unsigned long)(y) + kernel_map.va_kernel_pa_offset))
149+
#endif
150+
143151
#define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x)
144152

145153
#ifndef CONFIG_DEBUG_VIRTUAL
146154
#define linear_mapping_va_to_pa(x) ((unsigned long)(x) - kernel_map.va_pa_offset)
147155
#else
148156
phys_addr_t linear_mapping_va_to_pa(unsigned long x);
149157
#endif
158+
159+
#ifdef CONFIG_XIP_KERNEL
150160
#define kernel_mapping_va_to_pa(y) ({ \
151161
unsigned long _y = (unsigned long)(y); \
152-
(IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \
153-
(_y - kernel_map.va_kernel_xip_pa_offset) : \
154-
(_y - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \
162+
(_y < kernel_map.virt_addr + XIP_OFFSET) ? \
163+
(_y - kernel_map.va_kernel_xip_text_pa_offset) : \
164+
(_y - kernel_map.va_kernel_xip_data_pa_offset); \
155165
})
166+
#else
167+
#define kernel_mapping_va_to_pa(y) ((unsigned long)(y) - kernel_map.va_kernel_pa_offset)
168+
#endif
156169

157170
#define __va_to_pa_nodebug(x) ({ \
158171
unsigned long _x = x; \

arch/riscv/mm/init.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,11 +1098,14 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
10981098
kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
10991099
kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start);
11001100

1101-
kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
1101+
kernel_map.va_kernel_xip_text_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
1102+
kernel_map.va_kernel_xip_data_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr
1103+
+ (uintptr_t)&_sdata - (uintptr_t)&_start;
11021104
#else
11031105
kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL);
11041106
kernel_map.phys_addr = (uintptr_t)(&_start);
11051107
kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr;
1108+
kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
11061109
#endif
11071110

11081111
#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
@@ -1124,7 +1127,6 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
11241127
*/
11251128
kernel_map.va_pa_offset = IS_ENABLED(CONFIG_64BIT) ?
11261129
0UL : PAGE_OFFSET - kernel_map.phys_addr;
1127-
kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
11281130

11291131
/*
11301132
* The default maximal physical memory size is KERN_VIRT_SIZE for 32-bit

0 commit comments

Comments
 (0)