[PATCH] RISC-V: KVM: Inject instruction access fault on unmapped guest fetch
Anup Patel
anup at brainfault.org
Tue Jul 14 06:05:39 PDT 2026
On Tue, Jul 7, 2026 at 5:56 PM Qingwei Hu <qingwei.hu at bytedance.com> wrote:
>
> When an instruction guest-page-fault targets a GPA that is not backed by
> any memslot, KVM has no MMIO emulation path for the fetch. Load and
> store guest-page faults can be routed through MMIO emulation, but an
> instruction fetch has no data payload or access size for userspace to
> complete in the same way.
>
> Treat this case as an architectural access fault in the guest. On bare
> metal, fetching from an inaccessible physical address raises an
> instruction access fault for the supervisor to handle through its trap
> vector. Reflect EXC_INST_ACCESS back to the guest so the guest observes
> the same class of exception rather than leaving the fetch as a
> host-handled condition.
>
> stval contains the virtual address of the portion of the instruction that
> caused the fault, while sepc points to the beginning of the instruction.
>
> Signed-off-by: Qingwei Hu <qingwei.hu at bytedance.com>
LGTM.
Reviewed-by: Anup Patel <anup at brainfault.org>
Queued this patch as a fix for Linux-7.2-rcX
Thanks,
Anup
> ---
> arch/riscv/kvm/vcpu_exit.c | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c
> index 0bb0c51e3c89..6c8530b9f29e 100644
> --- a/arch/riscv/kvm/vcpu_exit.c
> +++ b/arch/riscv/kvm/vcpu_exit.c
> @@ -38,6 +38,25 @@ static int gstage_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run,
> return kvm_riscv_vcpu_mmio_store(vcpu, run,
> fault_addr,
> trap->htinst);
> + case EXC_INST_GUEST_PAGE_FAULT: {
> + /*
> + * No memslot backs this GPA and an instruction fetch
> + * cannot be emulated as MMIO. On bare metal a fetch
> + * from an unbacked physical address raises an
> + * instruction access fault, so reflect that back to
> + * the guest.
> + */
> + struct kvm_cpu_trap inst_trap = {
> + .sepc = trap->sepc,
> + .scause = EXC_INST_ACCESS,
> + .stval = trap->stval,
> + .htval = 0,
> + .htinst = 0,
> + };
> +
> + kvm_riscv_vcpu_trap_redirect(vcpu, &inst_trap);
> + return 1;
> + }
> default:
> return -EOPNOTSUPP;
> };
> --
> 2.39.5
>
More information about the kvm-riscv
mailing list