riscv64: disable mmu before kernel jump

Nick Owens <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
hi,

i tried to install 7.9 under libvirt/qemu with uefi/edk2 firmware, but
it faults right after the loader tries to jump to the kernel.

it seems since edk2 ~2023, it runs with paging enabled and maps memory
non-executable. to fix this we can disable S mode paging by setting SATP
CSR to 0 before the jump.

linux does the same in its efi stub.

this lets bsd.rd and bsd boot for me in the vm.

diff --git a/sys/arch/riscv64/stand/efiboot/exec.c b/sys/arch/riscv64/stand/efiboot/exec.c
index 0a71ccecccb..ec7325ad777 100644
--- a/sys/arch/riscv64/stand/efiboot/exec.c
+++ b/sys/arch/riscv64/stand/efiboot/exec.c
@@ -83,6 +83,13 @@ run_loadfile(uint64_t *marks, int howto)
 
 	cpu_flush_dcache((vaddr_t)fdt, fdt_get_size(fdt));
 
+	/*
+	 * Firmware may be running with paging enabled and the kernel
+	 * load area mapped non-executable; the kernel expects to be
+	 * entered in bare mode.
+	 */
+	__asm volatile("csrw satp, zero; sfence.vma" ::: "memory");
+
 	(*(startfuncp)(marks[MARK_ENTRY]))((void *)marks[MARK_END], 0, fdt);
 
 	/* NOTREACHED */
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.