The WFI and WRS virtual instruction traps from Guest VS/VU-mode (aka L2/nested guest) should be redirected to Guest HS-mode (aka L1/guest hypervisor).
Signed-off-by: Anup Patel <[email protected]> --- arch/riscv/kvm/vcpu_insn.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 745cd654df94..ebd0cfc1bf30 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -76,6 +76,20 @@ void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu) static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn) { + /* + * Trap from virtual-VS/VU modes should be forwarded to + * virtual-HS mode as a virtual instruction trap. + */ + if (kvm_riscv_vcpu_nested_virt(vcpu)) + return KVM_INSN_VIRTUAL_TRAP; + + /* + * Trap from virtual-U mode should be forwarded to + * virtual-HS mode as illegal instruction trap. + */ + if (!(vcpu->arch.guest_context.hstatus & HSTATUS_SPVP)) + return KVM_INSN_ILLEGAL_TRAP; + vcpu->stat.wfi_exit_stat++; kvm_riscv_vcpu_wfi(vcpu); return KVM_INSN_CONTINUE_NEXT_SEPC; @@ -83,6 +97,20 @@ static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn) static int wrs_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn) { + /* + * Trap from virtual-VS/VU modes should be forwarded to + * virtual-HS mode as a virtual instruction trap. + */ + if (kvm_riscv_vcpu_nested_virt(vcpu)) + return KVM_INSN_VIRTUAL_TRAP; + + /* + * Trap from virtual-U mode should be forwarded to + * virtual-HS mode as illegal instruction trap. + */ + if (!(vcpu->arch.guest_context.hstatus & HSTATUS_SPVP)) + return KVM_INSN_ILLEGAL_TRAP; + vcpu->stat.wrs_exit_stat++; kvm_vcpu_on_spin(vcpu, vcpu->arch.guest_context.sstatus & SR_SPP); return KVM_INSN_CONTINUE_NEXT_SEPC; -- 2.43.0

