Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

LoongArch: Simplify the processing of jumping new kernel for KASLR

Modified relocate_kernel() doesn't return new kernel's entry point but
the random_offset. In this way we share the start_kernel() processing
with the normal kernel, which avoids calling 'jr a0' directly and allows
some other operations (e.g, kasan_early_init) before start_kernel() when
KASLR (CONFIG_RANDOMIZE_BASE) is turned on.

Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

authored by

Qing Zhang and committed by
Huacai Chen
9fbcc076 fb6d5c1d

+9 -12
+1 -1
arch/loongarch/include/asm/setup.h
··· 34 34 extern long __rela_dyn_begin; 35 35 extern long __rela_dyn_end; 36 36 37 - extern void * __init relocate_kernel(void); 37 + extern unsigned long __init relocate_kernel(void); 38 38 39 39 #endif 40 40
+6 -5
arch/loongarch/kernel/head.S
··· 95 95 PTR_LI sp, (_THREAD_SIZE - PT_SIZE) 96 96 PTR_ADD sp, sp, tp 97 97 set_saved_sp sp, t0, t1 98 - #endif 99 98 100 - /* relocate_kernel() returns the new kernel entry point */ 101 - jr a0 102 - ASM_BUG() 99 + /* Jump to the new kernel: new_pc = current_pc + random_offset */ 100 + pcaddi t0, 0 101 + add.d t0, t0, a0 102 + jirl zero, t0, 0xc 103 + #endif /* CONFIG_RANDOMIZE_BASE */ 103 104 104 - #endif 105 + #endif /* CONFIG_RELOCATABLE */ 105 106 106 107 bl start_kernel 107 108 ASM_BUG()
+2 -6
arch/loongarch/kernel/relocate.c
··· 157 157 *new_addr = (unsigned long)reloc_offset; 158 158 } 159 159 160 - void * __init relocate_kernel(void) 160 + unsigned long __init relocate_kernel(void) 161 161 { 162 162 unsigned long kernel_length; 163 163 unsigned long random_offset = 0; 164 164 void *location_new = _text; /* Default to original kernel start */ 165 - void *kernel_entry = start_kernel; /* Default to original kernel entry point */ 166 165 char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */ 167 166 168 167 strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); ··· 189 190 190 191 reloc_offset += random_offset; 191 192 192 - /* Return the new kernel's entry point */ 193 - kernel_entry = RELOCATED_KASLR(start_kernel); 194 - 195 193 /* The current thread is now within the relocated kernel */ 196 194 __current_thread_info = RELOCATED_KASLR(__current_thread_info); 197 195 ··· 200 204 201 205 relocate_absolute(random_offset); 202 206 203 - return kernel_entry; 207 + return random_offset; 204 208 } 205 209 206 210 /*