From: Fangyu Yu <[email protected]>
Add riscv_kexec_relocate_entry to .kexec.tramp.text and the two
asm-visible globals (riscv_kexec_relocate_entry_pa and
riscv_kexec_cc_buffer_pa) that the wrapper consumes.
The wrapper performs the same two-step transition used by the crash
path: switch to the trampoline pgd, jump to the PA of self, then drop
the MMU with PC already on a PA. It finally jumps to the PA of
control_code_buffer.
machine_kexec_prepare() publishes the wrapper PA via WRITE_ONCE for
non-crash images. The per-image control_code_buffer PA is published
later, at dispatch time, so a load failure between prepare() and the
kexec_image swap cannot leave the global pointing at a freed page.
Nothing routes to the wrapper yet; the switchover happens in the
follow-up patch.
Signed-off-by: Fangyu Yu <[email protected]>
---
arch/riscv/include/asm/kexec.h | 1 +
arch/riscv/kernel/kexec_relocate.S | 36 ++++++++++++++++++++++++++++++
arch/riscv/kernel/machine_kexec.c | 5 +++++
3 files changed, 42 insertions(+)
diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
index 6466c1f00d41..b75cab959e53 100644
--- a/arch/riscv/include/asm/kexec.h
+++ b/arch/riscv/include/asm/kexec.h
@@ -53,6 +53,7 @@ typedef void (*riscv_kexec_method)(unsigned long first_ind_entry,
unsigned long va_pa_off);
extern riscv_kexec_method riscv_kexec_norelocate;
+extern riscv_kexec_method riscv_kexec_relocate_entry;
#ifdef CONFIG_KEXEC_FILE
extern const struct kexec_file_ops elf_kexec_ops;
diff --git a/arch/riscv/kernel/kexec_relocate.S b/arch/riscv/kernel/kexec_relocate.S
index 8cfdf6f4032a..6c624560c9ac 100644
--- a/arch/riscv/kernel/kexec_relocate.S
+++ b/arch/riscv/kernel/kexec_relocate.S
@@ -225,6 +225,42 @@ SYM_CODE_START(riscv_kexec_norelocate)
SYM_CODE_END(riscv_kexec_norelocate)
+.extern riscv_kexec_relocate_entry_pa
+.extern riscv_kexec_cc_buffer_pa
+.section ".kexec.tramp.text", "ax"
+SYM_CODE_START(riscv_kexec_relocate_entry)
+ /*
+ * Two-pass entry, identical in shape to riscv_kexec_norelocate:
+ * - 1st entry: t3 == 0 (initialized by machine_kexec()).
+ * - 2nd entry: t3 == PA of riscv_kexec_relocate_entry, so auipc
+ * matches t3 and we fall through to label 1.
+ * Args a0..a4 are passed through unchanged to riscv_kexec_relocate.
+ */
+ auipc t0, 0
+ beq t0, t3, 1f
+
+ la t0, riscv_kexec_relocate_entry_pa
+ REG_L t3, 0(t0)
+ la t0, kexec_tramp_satp
+ REG_L t1, 0(t0)
+ csrw CSR_SATP, t1
+ sfence.vma x0, x0
+
+ jr t3
+1:
+ /*
+ * Now executing at the PA of this wrapper with the trampoline pgd
+ * installed (identity-mapped). Drop the MMU; PC stays valid because
+ * it is already a PA.
+ */
+ csrw CSR_SATP, zero
+
+ /* Jump to the PA of control_code_buffer to run the relocate body. */
+ la t0, riscv_kexec_cc_buffer_pa
+ REG_L t0, 0(t0)
+ jr t0
+SYM_CODE_END(riscv_kexec_relocate_entry)
+
.section ".rodata"
SYM_DATA(riscv_kexec_relocate_size,
.long riscv_kexec_relocate_end - riscv_kexec_relocate)
diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c
index d82f45fb44b6..71688c63af65 100644
--- a/arch/riscv/kernel/machine_kexec.c
+++ b/arch/riscv/kernel/machine_kexec.c
@@ -20,6 +20,8 @@
unsigned long kexec_tramp_satp;
unsigned long riscv_kexec_norelocate_pa;
+unsigned long riscv_kexec_relocate_entry_pa;
+unsigned long riscv_kexec_cc_buffer_pa;
/*
* Trampoline page tables. Both the VA(trampoline)->PA and the
* PA(trampoline)->PA identity mapping are installed in this single
@@ -164,6 +166,9 @@ machine_kexec_prepare(struct kimage *image)
/* Mark the control page executable */
set_memory_x((unsigned long) control_code_buffer, 1);
+
+ WRITE_ONCE(riscv_kexec_relocate_entry_pa,
+ __pa_symbol(&riscv_kexec_relocate_entry));
} else {
WRITE_ONCE(riscv_kexec_norelocate_pa,
__pa_symbol(&riscv_kexec_norelocate));
--
2.50.1
--
kvm-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kvm-riscv
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.