]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blobdiff - arch/riscv/kvm/vcpu.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[mirror_ubuntu-kernels.git] / arch / riscv / kvm / vcpu.c
index 8bd9f2a8a0b9131b54ef9605de1a6a01aae11621..d12ef99901fc50334df504c04d9492304f513411 100644 (file)
@@ -22,6 +22,8 @@
 #include <asm/cacheflush.h>
 #include <asm/hwcap.h>
 #include <asm/sbi.h>
+#include <asm/vector.h>
+#include <asm/kvm_vcpu_vector.h>
 
 const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
        KVM_GENERIC_VCPU_STATS(),
@@ -57,10 +59,12 @@ static const unsigned long kvm_isa_ext_arr[] = {
        [KVM_RISCV_ISA_EXT_H] = RISCV_ISA_EXT_h,
        [KVM_RISCV_ISA_EXT_I] = RISCV_ISA_EXT_i,
        [KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m,
+       [KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_v,
 
        KVM_ISA_EXT_ARR(SSAIA),
        KVM_ISA_EXT_ARR(SSTC),
        KVM_ISA_EXT_ARR(SVINVAL),
+       KVM_ISA_EXT_ARR(SVNAPOT),
        KVM_ISA_EXT_ARR(SVPBMT),
        KVM_ISA_EXT_ARR(ZBB),
        KVM_ISA_EXT_ARR(ZIHINTPAUSE),
@@ -85,6 +89,8 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
        switch (ext) {
        case KVM_RISCV_ISA_EXT_H:
                return false;
+       case KVM_RISCV_ISA_EXT_V:
+               return riscv_v_vstate_ctrl_user_allowed();
        default:
                break;
        }
@@ -102,6 +108,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
        case KVM_RISCV_ISA_EXT_SSAIA:
        case KVM_RISCV_ISA_EXT_SSTC:
        case KVM_RISCV_ISA_EXT_SVINVAL:
+       case KVM_RISCV_ISA_EXT_SVNAPOT:
        case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
        case KVM_RISCV_ISA_EXT_ZBB:
                return false;
@@ -138,6 +145,8 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu)
 
        kvm_riscv_vcpu_fp_reset(vcpu);
 
+       kvm_riscv_vcpu_vector_reset(vcpu);
+
        kvm_riscv_vcpu_timer_reset(vcpu);
 
        kvm_riscv_vcpu_aia_reset(vcpu);
@@ -198,6 +207,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
        cntx->hstatus |= HSTATUS_SPVP;
        cntx->hstatus |= HSTATUS_SPV;
 
+       if (kvm_riscv_vcpu_alloc_vector_context(vcpu, cntx))
+               return -ENOMEM;
+
        /* By default, make CY, TM, and IR counters accessible in VU mode */
        reset_csr->scounteren = 0x7;
 
@@ -241,6 +253,9 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 
        /* Free unused pages pre-allocated for G-stage page table mappings */
        kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
+
+       /* Free vector context space for host and guest kernel */
+       kvm_riscv_vcpu_free_vector_context(vcpu);
 }
 
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
@@ -250,10 +265,12 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 
 void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
 {
+       kvm_riscv_aia_wakeon_hgei(vcpu, true);
 }
 
 void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
 {
+       kvm_riscv_aia_wakeon_hgei(vcpu, false);
 }
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
@@ -679,6 +696,9 @@ static int kvm_riscv_vcpu_set_reg(struct kvm_vcpu *vcpu,
                return kvm_riscv_vcpu_set_reg_isa_ext(vcpu, reg);
        case KVM_REG_RISCV_SBI_EXT:
                return kvm_riscv_vcpu_set_reg_sbi_ext(vcpu, reg);
+       case KVM_REG_RISCV_VECTOR:
+               return kvm_riscv_vcpu_set_reg_vector(vcpu, reg,
+                                                KVM_REG_RISCV_VECTOR);
        default:
                break;
        }
@@ -708,6 +728,9 @@ static int kvm_riscv_vcpu_get_reg(struct kvm_vcpu *vcpu,
                return kvm_riscv_vcpu_get_reg_isa_ext(vcpu, reg);
        case KVM_REG_RISCV_SBI_EXT:
                return kvm_riscv_vcpu_get_reg_sbi_ext(vcpu, reg);
+       case KVM_REG_RISCV_VECTOR:
+               return kvm_riscv_vcpu_get_reg_vector(vcpu, reg,
+                                                KVM_REG_RISCV_VECTOR);
        default:
                break;
        }
@@ -1002,6 +1025,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        kvm_riscv_vcpu_host_fp_save(&vcpu->arch.host_context);
        kvm_riscv_vcpu_guest_fp_restore(&vcpu->arch.guest_context,
                                        vcpu->arch.isa);
+       kvm_riscv_vcpu_host_vector_save(&vcpu->arch.host_context);
+       kvm_riscv_vcpu_guest_vector_restore(&vcpu->arch.guest_context,
+                                           vcpu->arch.isa);
 
        kvm_riscv_vcpu_aia_load(vcpu, cpu);
 
@@ -1021,6 +1047,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
        kvm_riscv_vcpu_host_fp_restore(&vcpu->arch.host_context);
 
        kvm_riscv_vcpu_timer_save(vcpu);
+       kvm_riscv_vcpu_guest_vector_save(&vcpu->arch.guest_context,
+                                        vcpu->arch.isa);
+       kvm_riscv_vcpu_host_vector_restore(&vcpu->arch.host_context);
 
        csr->vsstatus = csr_read(CSR_VSSTATUS);
        csr->vsie = csr_read(CSR_VSIE);