arm64: kexec: relocate in EL1 mode

Since we are going to keep MMU enabled during relocation, we need to
keep EL1 mode throughout the relocation.

Keep EL1 enabled, and switch EL2 only before entering the new world.

Suggested-by: James Morse <james.morse@arm.com>
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20210930143113.1502553-10-pasha.tatashin@soleen.com
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Pasha Tatashin 2021-09-30 14:31:07 +00:00 коммит произвёл Will Deacon
Родитель 08eae0ef61
Коммит ba959fe96a
3 изменённых файлов: 14 добавлений и 6 удалений

Просмотреть файл

@ -20,11 +20,10 @@ static inline void __noreturn __nocfi cpu_soft_restart(unsigned long entry,
{ {
typeof(__cpu_soft_restart) *restart; typeof(__cpu_soft_restart) *restart;
unsigned long el2_switch = is_hyp_nvhe();
restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart)); restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
cpu_install_idmap(); cpu_install_idmap();
restart(el2_switch, entry, arg0, arg1, arg2); restart(0, entry, arg0, arg1, arg2);
unreachable(); unreachable();
} }

Просмотреть файл

@ -240,8 +240,8 @@ void machine_kexec(struct kimage *kimage)
} else { } else {
if (is_hyp_nvhe()) if (is_hyp_nvhe())
__hyp_set_vectors(kimage->arch.el2_vectors); __hyp_set_vectors(kimage->arch.el2_vectors);
cpu_soft_restart(kimage->arch.kern_reloc, virt_to_phys(kimage), cpu_soft_restart(kimage->arch.kern_reloc,
0, 0); virt_to_phys(kimage), 0, 0);
} }
BUG(); /* Should never get here. */ BUG(); /* Should never get here. */

Просмотреть файл

@ -13,6 +13,7 @@
#include <asm/kexec.h> #include <asm/kexec.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/sysreg.h> #include <asm/sysreg.h>
#include <asm/virt.h>
/* /*
* arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it. * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
@ -61,12 +62,20 @@ SYM_CODE_START(arm64_relocate_new_kernel)
isb isb
/* Start new image. */ /* Start new image. */
ldr x1, [x0, #KIMAGE_ARCH_EL2_VECTORS] /* relocation start */
cbz x1, .Lel1
ldr x1, [x0, #KIMAGE_START] /* relocation start */
ldr x2, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */
mov x3, xzr
mov x4, xzr
mov x0, #HVC_SOFT_RESTART
hvc #0 /* Jumps from el2 */
.Lel1:
ldr x4, [x0, #KIMAGE_START] /* relocation start */ ldr x4, [x0, #KIMAGE_START] /* relocation start */
ldr x0, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */ ldr x0, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */
mov x1, xzr
mov x2, xzr mov x2, xzr
mov x3, xzr mov x3, xzr
br x4 br x4 /* Jumps from el1 */
SYM_CODE_END(arm64_relocate_new_kernel) SYM_CODE_END(arm64_relocate_new_kernel)
.align 3 /* To keep the 64-bit values below naturally aligned. */ .align 3 /* To keep the 64-bit values below naturally aligned. */