]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: riscv: Support guest wrs.nto
authorAndrew Jones <ajones@ventanamicro.com>
Fri, 26 Apr 2024 10:08:25 +0000 (12:08 +0200)
committerPalmer Dabbelt <palmer@rivosinc.com>
Fri, 12 Jul 2024 15:54:51 +0000 (08:54 -0700)
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>
arch/riscv/include/asm/kvm_host.h
arch/riscv/include/uapi/asm/kvm.h
arch/riscv/kvm/vcpu.c
arch/riscv/kvm/vcpu_insn.c
arch/riscv/kvm/vcpu_onereg.c

index 484d04a92fa6b7f02a5ef0b24faee9a87f98b1bb..e27c56e4478338edc79be2e8983e29804adce8b8 100644 (file)
@@ -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;
index b1c503c2959c34ee4fb7f7c7a4b3a0b6c3dda240..89ea06bd07c2b8dcc24663116145fadce4c742ee 100644 (file)
@@ -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,
 };
 
index b5ca9f2e98acd216caf4dd7537d106ce4f5bcdc0..abcdc78671e0bd23eba9e994d66676c256da0c44 100644 (file)
@@ -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),
index ee7215f4071f52186c4aa2295fbb385cae0f7a0f..97dec18e69892a1f3dac5464f892a8bac25eefd5 100644 (file)
@@ -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,
index f4a6124d25c939ecdf5dc631d8c7aa69a2684621..67c5794af3b605d0eb06a23b85a894db391535ad 100644 (file)
@@ -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: