[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