KVM: riscv: Support guest wrs.nto
When a guest traps on wrs.nto, call kvm_vcpu_on_spin() to attempt to yield to the lock holding VCPU. Also extend the KVM ISA extension ONE_REG interface to allow KVM userspace to detect and enable the Zawrs extension for the Guest/VM. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> Acked-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20240426100820.14762-13-ajones@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
244c18fbf6
commit
86d6a86e59
@ -69,6 +69,7 @@ struct kvm_vcpu_stat {
|
||||
struct kvm_vcpu_stat_generic generic;
|
||||
u64 ecall_exit_stat;
|
||||
u64 wfi_exit_stat;
|
||||
u64 wrs_exit_stat;
|
||||
u64 mmio_exit_user;
|
||||
u64 mmio_exit_kernel;
|
||||
u64 csr_exit_user;
|
||||
|
@ -167,6 +167,7 @@ enum KVM_RISCV_ISA_EXT_ID {
|
||||
KVM_RISCV_ISA_EXT_ZFA,
|
||||
KVM_RISCV_ISA_EXT_ZTSO,
|
||||
KVM_RISCV_ISA_EXT_ZACAS,
|
||||
KVM_RISCV_ISA_EXT_ZAWRS,
|
||||
KVM_RISCV_ISA_EXT_MAX,
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
|
||||
KVM_GENERIC_VCPU_STATS(),
|
||||
STATS_DESC_COUNTER(VCPU, ecall_exit_stat),
|
||||
STATS_DESC_COUNTER(VCPU, wfi_exit_stat),
|
||||
STATS_DESC_COUNTER(VCPU, wrs_exit_stat),
|
||||
STATS_DESC_COUNTER(VCPU, mmio_exit_user),
|
||||
STATS_DESC_COUNTER(VCPU, mmio_exit_kernel),
|
||||
STATS_DESC_COUNTER(VCPU, csr_exit_user),
|
||||
|
@ -16,6 +16,9 @@
|
||||
#define INSN_MASK_WFI 0xffffffff
|
||||
#define INSN_MATCH_WFI 0x10500073
|
||||
|
||||
#define INSN_MASK_WRS 0xffffffff
|
||||
#define INSN_MATCH_WRS 0x00d00073
|
||||
|
||||
#define INSN_MATCH_CSRRW 0x1073
|
||||
#define INSN_MASK_CSRRW 0x707f
|
||||
#define INSN_MATCH_CSRRS 0x2073
|
||||
@ -203,6 +206,13 @@ static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
|
||||
return KVM_INSN_CONTINUE_NEXT_SEPC;
|
||||
}
|
||||
|
||||
static int wrs_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
|
||||
{
|
||||
vcpu->stat.wrs_exit_stat++;
|
||||
kvm_vcpu_on_spin(vcpu, vcpu->arch.guest_context.sstatus & SR_SPP);
|
||||
return KVM_INSN_CONTINUE_NEXT_SEPC;
|
||||
}
|
||||
|
||||
struct csr_func {
|
||||
unsigned int base;
|
||||
unsigned int count;
|
||||
@ -378,6 +388,11 @@ static const struct insn_func system_opcode_funcs[] = {
|
||||
.match = INSN_MATCH_WFI,
|
||||
.func = wfi_insn,
|
||||
},
|
||||
{
|
||||
.mask = INSN_MASK_WRS,
|
||||
.match = INSN_MATCH_WRS,
|
||||
.func = wrs_insn,
|
||||
},
|
||||
};
|
||||
|
||||
static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
||||
|
@ -41,6 +41,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
|
||||
KVM_ISA_EXT_ARR(SVNAPOT),
|
||||
KVM_ISA_EXT_ARR(SVPBMT),
|
||||
KVM_ISA_EXT_ARR(ZACAS),
|
||||
KVM_ISA_EXT_ARR(ZAWRS),
|
||||
KVM_ISA_EXT_ARR(ZBA),
|
||||
KVM_ISA_EXT_ARR(ZBB),
|
||||
KVM_ISA_EXT_ARR(ZBC),
|
||||
@ -120,6 +121,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
|
||||
case KVM_RISCV_ISA_EXT_SVINVAL:
|
||||
case KVM_RISCV_ISA_EXT_SVNAPOT:
|
||||
case KVM_RISCV_ISA_EXT_ZACAS:
|
||||
case KVM_RISCV_ISA_EXT_ZAWRS:
|
||||
case KVM_RISCV_ISA_EXT_ZBA:
|
||||
case KVM_RISCV_ISA_EXT_ZBB:
|
||||
case KVM_RISCV_ISA_EXT_ZBC:
|
||||
|
Loading…
Reference in New Issue
Block a user