Lines Matching +full:riscv +full:- +full:aia
1 // SPDX-License-Identifier: GPL-2.0
12 #include <linux/irqchip/riscv-imsic.h>
45 * 1) Hardware: IMSIC VS-file (vsfile_cpu >= 0)
46 * 2) Software: IMSIC SW-file (vsfile_cpu < 0)
49 /* IMSIC VS-file */
56 /* IMSIC SW-file */
244 imsic_mrif_atomic_rmw(__mrif, __ptr, __new_val, -1UL)
254 &mrif->eithreshold); in imsic_mrif_topei()
259 eix = &mrif->eix[ei]; in imsic_mrif_topei()
260 eipend[0] = imsic_mrif_atomic_read(mrif, &eix->eie[0]) & in imsic_mrif_topei()
261 imsic_mrif_atomic_read(mrif, &eix->eip[0]); in imsic_mrif_topei()
263 eipend[1] = imsic_mrif_atomic_read(mrif, &eix->eie[1]) & in imsic_mrif_topei()
264 imsic_mrif_atomic_read(mrif, &eix->eip[1]); in imsic_mrif_topei()
275 if (test_bit(i - imin, eipend)) in imsic_mrif_topei()
292 num = isel - IMSIC_EIP0; in imsic_mrif_isel_check()
295 num = isel - IMSIC_EIE0; in imsic_mrif_isel_check()
298 return -ENOENT; in imsic_mrif_isel_check()
302 return -EINVAL; in imsic_mrif_isel_check()
305 return -EINVAL; in imsic_mrif_isel_check()
320 old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eidelivery, in imsic_mrif_rmw()
324 old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eithreshold, in imsic_mrif_rmw()
325 new_val, wr_mask & (IMSIC_MAX_ID - 1)); in imsic_mrif_rmw()
331 num = isel - IMSIC_EIP0; in imsic_mrif_rmw()
334 num = isel - IMSIC_EIE0; in imsic_mrif_rmw()
338 return -EINVAL; in imsic_mrif_rmw()
339 eix = &mrif->eix[num / 2]; in imsic_mrif_rmw()
343 return -EINVAL; in imsic_mrif_rmw()
344 ei = (pend) ? &eix->eip[0] : &eix->eie[0]; in imsic_mrif_rmw()
346 ei = (pend) ? &eix->eip[num & 0x1] : &eix->eie[num & 0x1]; in imsic_mrif_rmw()
349 /* Bit0 of EIP0 or EIE0 is read-only */ in imsic_mrif_rmw()
356 return -ENOENT; in imsic_mrif_rmw()
377 struct imsic_mrif *mrif = idata->mrif; in imsic_vsfile_local_read()
383 new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT; in imsic_vsfile_local_read()
392 if (idata->clear) { in imsic_vsfile_local_read()
393 mrif->eidelivery = imsic_vs_csr_swap(IMSIC_EIDELIVERY, 0); in imsic_vsfile_local_read()
394 mrif->eithreshold = imsic_vs_csr_swap(IMSIC_EITHRESHOLD, 0); in imsic_vsfile_local_read()
395 for (i = 0; i < idata->nr_eix; i++) { in imsic_vsfile_local_read()
396 eix = &mrif->eix[i]; in imsic_vsfile_local_read()
397 eix->eip[0] = imsic_eix_swap(IMSIC_EIP0 + i * 2, 0); in imsic_vsfile_local_read()
398 eix->eie[0] = imsic_eix_swap(IMSIC_EIE0 + i * 2, 0); in imsic_vsfile_local_read()
400 eix->eip[1] = imsic_eix_swap(IMSIC_EIP0 + i * 2 + 1, 0); in imsic_vsfile_local_read()
401 eix->eie[1] = imsic_eix_swap(IMSIC_EIE0 + i * 2 + 1, 0); in imsic_vsfile_local_read()
405 mrif->eidelivery = imsic_vs_csr_read(IMSIC_EIDELIVERY); in imsic_vsfile_local_read()
406 mrif->eithreshold = imsic_vs_csr_read(IMSIC_EITHRESHOLD); in imsic_vsfile_local_read()
407 for (i = 0; i < idata->nr_eix; i++) { in imsic_vsfile_local_read()
408 eix = &mrif->eix[i]; in imsic_vsfile_local_read()
409 eix->eip[0] = imsic_eix_read(IMSIC_EIP0 + i * 2); in imsic_vsfile_local_read()
410 eix->eie[0] = imsic_eix_read(IMSIC_EIE0 + i * 2); in imsic_vsfile_local_read()
412 eix->eip[1] = imsic_eix_read(IMSIC_EIP0 + i * 2 + 1); in imsic_vsfile_local_read()
413 eix->eie[1] = imsic_eix_read(IMSIC_EIE0 + i * 2 + 1); in imsic_vsfile_local_read()
427 /* We can only read clear if we have a IMSIC VS-file */ in imsic_vsfile_read()
455 new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT; in imsic_vsfile_local_rw()
458 switch (idata->isel) { in imsic_vsfile_local_rw()
460 if (idata->write) in imsic_vsfile_local_rw()
461 imsic_vs_csr_write(IMSIC_EIDELIVERY, idata->val); in imsic_vsfile_local_rw()
463 idata->val = imsic_vs_csr_read(IMSIC_EIDELIVERY); in imsic_vsfile_local_rw()
466 if (idata->write) in imsic_vsfile_local_rw()
467 imsic_vs_csr_write(IMSIC_EITHRESHOLD, idata->val); in imsic_vsfile_local_rw()
469 idata->val = imsic_vs_csr_read(IMSIC_EITHRESHOLD); in imsic_vsfile_local_rw()
474 if (idata->isel & 0x1) in imsic_vsfile_local_rw()
477 if (idata->write) in imsic_vsfile_local_rw()
478 imsic_eix_write(idata->isel, idata->val); in imsic_vsfile_local_rw()
480 idata->val = imsic_eix_read(idata->isel); in imsic_vsfile_local_rw()
497 /* We can only access register if we have a IMSIC VS-file */ in imsic_vsfile_rw()
499 return -EINVAL; in imsic_vsfile_rw()
525 /* We can only zero-out if we have a IMSIC VS-file */ in imsic_vsfile_local_clear()
574 eix = &mrif->eix[i]; in imsic_vsfile_local_update()
575 imsic_eix_set(IMSIC_EIP0 + i * 2, eix->eip[0]); in imsic_vsfile_local_update()
576 imsic_eix_set(IMSIC_EIE0 + i * 2, eix->eie[0]); in imsic_vsfile_local_update()
578 imsic_eix_set(IMSIC_EIP0 + i * 2 + 1, eix->eip[1]); in imsic_vsfile_local_update()
579 imsic_eix_set(IMSIC_EIE0 + i * 2 + 1, eix->eie[1]); in imsic_vsfile_local_update()
582 imsic_vs_csr_write(IMSIC_EITHRESHOLD, mrif->eithreshold); in imsic_vsfile_local_update()
583 imsic_vs_csr_write(IMSIC_EIDELIVERY, mrif->eidelivery); in imsic_vsfile_local_update()
596 * SW-file in this function because it is always called when the in imsic_vsfile_cleanup()
600 write_lock_irqsave(&imsic->vsfile_lock, flags); in imsic_vsfile_cleanup()
601 old_vsfile_hgei = imsic->vsfile_hgei; in imsic_vsfile_cleanup()
602 old_vsfile_cpu = imsic->vsfile_cpu; in imsic_vsfile_cleanup()
603 imsic->vsfile_cpu = imsic->vsfile_hgei = -1; in imsic_vsfile_cleanup()
604 imsic->vsfile_va = NULL; in imsic_vsfile_cleanup()
605 imsic->vsfile_pa = 0; in imsic_vsfile_cleanup()
606 write_unlock_irqrestore(&imsic->vsfile_lock, flags); in imsic_vsfile_cleanup()
608 memset(imsic->swfile, 0, sizeof(*imsic->swfile)); in imsic_vsfile_cleanup()
616 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in imsic_swfile_extirq_update()
617 struct imsic_mrif *mrif = imsic->swfile; in imsic_swfile_extirq_update()
626 raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); in imsic_swfile_extirq_update()
628 if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && in imsic_swfile_extirq_update()
629 imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) in imsic_swfile_extirq_update()
634 raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); in imsic_swfile_extirq_update()
640 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in imsic_swfile_read()
644 * write SW-file and MRIF in this function because it is always in imsic_swfile_read()
645 * called when VCPU is not using SW-file and the MRIF points to in imsic_swfile_read()
649 memcpy(mrif, imsic->swfile, sizeof(*mrif)); in imsic_swfile_read()
651 memset(imsic->swfile, 0, sizeof(*imsic->swfile)); in imsic_swfile_read()
661 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in imsic_swfile_update()
662 struct imsic_mrif *smrif = imsic->swfile; in imsic_swfile_update()
664 imsic_mrif_atomic_write(smrif, &smrif->eidelivery, mrif->eidelivery); in imsic_swfile_update()
665 imsic_mrif_atomic_write(smrif, &smrif->eithreshold, mrif->eithreshold); in imsic_swfile_update()
666 for (i = 0; i < imsic->nr_eix; i++) { in imsic_swfile_update()
667 seix = &smrif->eix[i]; in imsic_swfile_update()
668 eix = &mrif->eix[i]; in imsic_swfile_update()
669 imsic_mrif_atomic_or(smrif, &seix->eip[0], eix->eip[0]); in imsic_swfile_update()
670 imsic_mrif_atomic_or(smrif, &seix->eie[0], eix->eie[0]); in imsic_swfile_update()
672 imsic_mrif_atomic_or(smrif, &seix->eip[1], eix->eip[1]); in imsic_swfile_update()
673 imsic_mrif_atomic_or(smrif, &seix->eie[1], eix->eie[1]); in imsic_swfile_update()
682 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_has_interrupt()
687 * The IMSIC SW-file directly injects interrupt via hvip so in kvm_riscv_vcpu_aia_imsic_has_interrupt()
688 * only check for interrupt when IMSIC VS-file is being used. in kvm_riscv_vcpu_aia_imsic_has_interrupt()
691 read_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_has_interrupt()
692 if (imsic->vsfile_cpu > -1) in kvm_riscv_vcpu_aia_imsic_has_interrupt()
693 ret = !!(csr_read(CSR_HGEIP) & BIT(imsic->vsfile_hgei)); in kvm_riscv_vcpu_aia_imsic_has_interrupt()
694 read_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_has_interrupt()
710 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_put()
716 read_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_put()
717 if (imsic->vsfile_cpu > -1) in kvm_riscv_vcpu_aia_imsic_put()
718 csr_set(CSR_HGEIE, BIT(imsic->vsfile_hgei)); in kvm_riscv_vcpu_aia_imsic_put()
719 read_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_put()
727 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_release()
729 /* Read and clear IMSIC VS-file details */ in kvm_riscv_vcpu_aia_imsic_release()
730 write_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_release()
731 old_vsfile_hgei = imsic->vsfile_hgei; in kvm_riscv_vcpu_aia_imsic_release()
732 old_vsfile_cpu = imsic->vsfile_cpu; in kvm_riscv_vcpu_aia_imsic_release()
733 imsic->vsfile_cpu = imsic->vsfile_hgei = -1; in kvm_riscv_vcpu_aia_imsic_release()
734 imsic->vsfile_va = NULL; in kvm_riscv_vcpu_aia_imsic_release()
735 imsic->vsfile_pa = 0; in kvm_riscv_vcpu_aia_imsic_release()
736 write_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_release()
738 /* Do nothing, if no IMSIC VS-file to release */ in kvm_riscv_vcpu_aia_imsic_release()
744 * the old IMSIC VS-file so we first re-direct all interrupt in kvm_riscv_vcpu_aia_imsic_release()
748 /* Purge the G-stage mapping */ in kvm_riscv_vcpu_aia_imsic_release()
749 kvm_riscv_mmu_iounmap(vcpu->kvm, vcpu->arch.aia_context.imsic_addr, in kvm_riscv_vcpu_aia_imsic_release()
755 * At this point, all interrupt producers have been re-directed in kvm_riscv_vcpu_aia_imsic_release()
757 * VS-file to the IMSIC SW-file. in kvm_riscv_vcpu_aia_imsic_release()
760 /* Read and clear register state from old IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_release()
762 imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu, imsic->nr_hw_eix, in kvm_riscv_vcpu_aia_imsic_release()
765 /* Update register state in IMSIC SW-file */ in kvm_riscv_vcpu_aia_imsic_release()
768 /* Free-up old IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_release()
778 struct kvm *kvm = vcpu->kvm; in kvm_riscv_vcpu_aia_imsic_update()
779 struct kvm_run *run = vcpu->run; in kvm_riscv_vcpu_aia_imsic_update()
780 struct kvm_vcpu_aia *vaia = &vcpu->arch.aia_context; in kvm_riscv_vcpu_aia_imsic_update()
781 struct imsic *imsic = vaia->imsic_state; in kvm_riscv_vcpu_aia_imsic_update()
782 int ret = 0, new_vsfile_hgei = -1, old_vsfile_hgei, old_vsfile_cpu; in kvm_riscv_vcpu_aia_imsic_update()
785 if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_EMUL) in kvm_riscv_vcpu_aia_imsic_update()
788 /* Read old IMSIC VS-file details */ in kvm_riscv_vcpu_aia_imsic_update()
789 read_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_update()
790 old_vsfile_hgei = imsic->vsfile_hgei; in kvm_riscv_vcpu_aia_imsic_update()
791 old_vsfile_cpu = imsic->vsfile_cpu; in kvm_riscv_vcpu_aia_imsic_update()
792 read_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_update()
795 if (old_vsfile_cpu == vcpu->cpu) in kvm_riscv_vcpu_aia_imsic_update()
798 /* Allocate new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
799 ret = kvm_riscv_aia_alloc_hgei(vcpu->cpu, vcpu, in kvm_riscv_vcpu_aia_imsic_update()
803 if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) { in kvm_riscv_vcpu_aia_imsic_update()
804 run->fail_entry.hardware_entry_failure_reason = in kvm_riscv_vcpu_aia_imsic_update()
806 run->fail_entry.cpu = vcpu->cpu; in kvm_riscv_vcpu_aia_imsic_update()
807 run->exit_reason = KVM_EXIT_FAIL_ENTRY; in kvm_riscv_vcpu_aia_imsic_update()
811 /* Release old IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
822 * to the old IMSIC VS-file so we first move all interrupt in kvm_riscv_vcpu_aia_imsic_update()
823 * producers to the new IMSIC VS-file. in kvm_riscv_vcpu_aia_imsic_update()
826 /* Ensure HGEIE CSR bit is zero before using the new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
829 /* Zero-out new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
830 imsic_vsfile_local_clear(new_vsfile_hgei, imsic->nr_hw_eix); in kvm_riscv_vcpu_aia_imsic_update()
832 /* Update G-stage mapping for the new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
833 ret = kvm_riscv_mmu_ioremap(kvm, vcpu->arch.aia_context.imsic_addr, in kvm_riscv_vcpu_aia_imsic_update()
841 /* Update new IMSIC VS-file details in IMSIC context */ in kvm_riscv_vcpu_aia_imsic_update()
842 write_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_update()
843 imsic->vsfile_hgei = new_vsfile_hgei; in kvm_riscv_vcpu_aia_imsic_update()
844 imsic->vsfile_cpu = vcpu->cpu; in kvm_riscv_vcpu_aia_imsic_update()
845 imsic->vsfile_va = new_vsfile_va; in kvm_riscv_vcpu_aia_imsic_update()
846 imsic->vsfile_pa = new_vsfile_pa; in kvm_riscv_vcpu_aia_imsic_update()
847 write_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_update()
851 * to the new IMSIC VS-file so we move register state from in kvm_riscv_vcpu_aia_imsic_update()
852 * the old IMSIC VS/SW-file to the new IMSIC VS-file. in kvm_riscv_vcpu_aia_imsic_update()
857 /* Read and clear register state from old IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
859 imsic->nr_hw_eix, true, &tmrif); in kvm_riscv_vcpu_aia_imsic_update()
861 /* Free-up old IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
864 /* Read and clear register state from IMSIC SW-file */ in kvm_riscv_vcpu_aia_imsic_update()
868 /* Restore register state in the new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
869 imsic_vsfile_local_update(new_vsfile_hgei, imsic->nr_hw_eix, &tmrif); in kvm_riscv_vcpu_aia_imsic_update()
872 /* Set VCPU HSTATUS.VGEIN to new IMSIC VS-file */ in kvm_riscv_vcpu_aia_imsic_update()
873 vcpu->arch.guest_context.hstatus &= ~HSTATUS_VGEIN; in kvm_riscv_vcpu_aia_imsic_update()
875 vcpu->arch.guest_context.hstatus |= in kvm_riscv_vcpu_aia_imsic_update()
878 /* Continue run-loop */ in kvm_riscv_vcpu_aia_imsic_update()
882 kvm_riscv_aia_free_hgei(vcpu->cpu, new_vsfile_hgei); in kvm_riscv_vcpu_aia_imsic_update()
893 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_rmw()
897 topei = imsic_mrif_topei(imsic->swfile, imsic->nr_eix, in kvm_riscv_vcpu_aia_imsic_rmw()
898 imsic->nr_msis); in kvm_riscv_vcpu_aia_imsic_rmw()
906 eix = &imsic->swfile->eix[topei / in kvm_riscv_vcpu_aia_imsic_rmw()
908 clear_bit(topei & (BITS_PER_TYPE(u64) - 1), in kvm_riscv_vcpu_aia_imsic_rmw()
909 eix->eip); in kvm_riscv_vcpu_aia_imsic_rmw()
913 r = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, isel, in kvm_riscv_vcpu_aia_imsic_rmw()
915 /* Forward unknown IMSIC register to user-space */ in kvm_riscv_vcpu_aia_imsic_rmw()
917 rc = (r == -ENOENT) ? 0 : KVM_INSN_ILLEGAL_TRAP; in kvm_riscv_vcpu_aia_imsic_rmw()
936 return -ENODEV; in kvm_riscv_aia_imsic_rw_attr()
941 return -ENODEV; in kvm_riscv_aia_imsic_rw_attr()
944 imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_aia_imsic_rw_attr()
946 read_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_aia_imsic_rw_attr()
949 vsfile_hgei = imsic->vsfile_hgei; in kvm_riscv_aia_imsic_rw_attr()
950 vsfile_cpu = imsic->vsfile_cpu; in kvm_riscv_aia_imsic_rw_attr()
953 rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, in kvm_riscv_aia_imsic_rw_attr()
954 isel, NULL, *val, -1UL); in kvm_riscv_aia_imsic_rw_attr()
957 rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, in kvm_riscv_aia_imsic_rw_attr()
961 read_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_aia_imsic_rw_attr()
964 rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix, in kvm_riscv_aia_imsic_rw_attr()
977 return -ENODEV; in kvm_riscv_aia_imsic_has_attr()
982 return -ENODEV; in kvm_riscv_aia_imsic_has_attr()
985 imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_aia_imsic_has_attr()
986 return imsic_mrif_isel_check(imsic->nr_eix, isel); in kvm_riscv_aia_imsic_has_attr()
991 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_reset()
998 memset(imsic->swfile, 0, sizeof(*imsic->swfile)); in kvm_riscv_vcpu_aia_imsic_reset()
1006 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_inject()
1012 return -ENODEV; in kvm_riscv_vcpu_aia_imsic_inject()
1015 if (imsic->nr_msis <= iid) in kvm_riscv_vcpu_aia_imsic_inject()
1016 return -EINVAL; in kvm_riscv_vcpu_aia_imsic_inject()
1018 read_lock_irqsave(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_inject()
1020 if (imsic->vsfile_cpu >= 0) { in kvm_riscv_vcpu_aia_imsic_inject()
1021 writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE); in kvm_riscv_vcpu_aia_imsic_inject()
1023 eix = &imsic->swfile->eix[iid / BITS_PER_TYPE(u64)]; in kvm_riscv_vcpu_aia_imsic_inject()
1024 set_bit(iid & (BITS_PER_TYPE(u64) - 1), eix->eip); in kvm_riscv_vcpu_aia_imsic_inject()
1028 read_unlock_irqrestore(&imsic->vsfile_lock, flags); in kvm_riscv_vcpu_aia_imsic_inject()
1037 return -EOPNOTSUPP; in imsic_mmio_read()
1050 return -EOPNOTSUPP; in imsic_mmio_write()
1055 kvm_riscv_aia_inject_msi(vcpu->kvm, &msi); in imsic_mmio_write()
1070 struct kvm *kvm = vcpu->kvm; in kvm_riscv_vcpu_aia_imsic_init()
1073 if (!kvm->arch.aia.nr_ids) in kvm_riscv_vcpu_aia_imsic_init()
1074 return -EINVAL; in kvm_riscv_vcpu_aia_imsic_init()
1079 return -ENOMEM; in kvm_riscv_vcpu_aia_imsic_init()
1080 vcpu->arch.aia_context.imsic_state = imsic; in kvm_riscv_vcpu_aia_imsic_init()
1083 imsic->nr_msis = kvm->arch.aia.nr_ids + 1; in kvm_riscv_vcpu_aia_imsic_init()
1084 rwlock_init(&imsic->vsfile_lock); in kvm_riscv_vcpu_aia_imsic_init()
1085 imsic->nr_eix = BITS_TO_U64(imsic->nr_msis); in kvm_riscv_vcpu_aia_imsic_init()
1086 imsic->nr_hw_eix = BITS_TO_U64(kvm_riscv_aia_max_ids); in kvm_riscv_vcpu_aia_imsic_init()
1087 imsic->vsfile_hgei = imsic->vsfile_cpu = -1; in kvm_riscv_vcpu_aia_imsic_init()
1089 /* Setup IMSIC SW-file */ in kvm_riscv_vcpu_aia_imsic_init()
1091 get_order(sizeof(*imsic->swfile))); in kvm_riscv_vcpu_aia_imsic_init()
1093 ret = -ENOMEM; in kvm_riscv_vcpu_aia_imsic_init()
1096 imsic->swfile = page_to_virt(swfile_page); in kvm_riscv_vcpu_aia_imsic_init()
1097 imsic->swfile_pa = page_to_phys(swfile_page); in kvm_riscv_vcpu_aia_imsic_init()
1098 raw_spin_lock_init(&imsic->swfile_extirq_lock); in kvm_riscv_vcpu_aia_imsic_init()
1101 kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); in kvm_riscv_vcpu_aia_imsic_init()
1102 mutex_lock(&kvm->slots_lock); in kvm_riscv_vcpu_aia_imsic_init()
1104 vcpu->arch.aia_context.imsic_addr, in kvm_riscv_vcpu_aia_imsic_init()
1106 &imsic->iodev); in kvm_riscv_vcpu_aia_imsic_init()
1107 mutex_unlock(&kvm->slots_lock); in kvm_riscv_vcpu_aia_imsic_init()
1114 free_pages((unsigned long)imsic->swfile, in kvm_riscv_vcpu_aia_imsic_init()
1115 get_order(sizeof(*imsic->swfile))); in kvm_riscv_vcpu_aia_imsic_init()
1117 vcpu->arch.aia_context.imsic_state = NULL; in kvm_riscv_vcpu_aia_imsic_init()
1124 struct kvm *kvm = vcpu->kvm; in kvm_riscv_vcpu_aia_imsic_cleanup()
1125 struct imsic *imsic = vcpu->arch.aia_context.imsic_state; in kvm_riscv_vcpu_aia_imsic_cleanup()
1132 mutex_lock(&kvm->slots_lock); in kvm_riscv_vcpu_aia_imsic_cleanup()
1133 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &imsic->iodev); in kvm_riscv_vcpu_aia_imsic_cleanup()
1134 mutex_unlock(&kvm->slots_lock); in kvm_riscv_vcpu_aia_imsic_cleanup()
1136 free_pages((unsigned long)imsic->swfile, in kvm_riscv_vcpu_aia_imsic_cleanup()
1137 get_order(sizeof(*imsic->swfile))); in kvm_riscv_vcpu_aia_imsic_cleanup()
1139 vcpu->arch.aia_context.imsic_state = NULL; in kvm_riscv_vcpu_aia_imsic_cleanup()