Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

LoongArch: KVM: Add AVEC basic support

Check whether the host CPU supported AVEC, and save/restore CSR_MSGIS0-
CSR_MSGIS3 when necessary.

Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

authored by

Song Gao and committed by
Huacai Chen
7bcd8d0b 74087611

+36 -4
+1
arch/loongarch/include/asm/kvm_vcpu.h
··· 15 15 #define CPU_PMU (_ULCAST_(1) << 10) 16 16 #define CPU_TIMER (_ULCAST_(1) << 11) 17 17 #define CPU_IPI (_ULCAST_(1) << 12) 18 + #define CPU_AVEC (_ULCAST_(1) << 14) 18 19 19 20 /* Controlled by 0x52 guest exception VIP aligned to estat bit 5~12 */ 20 21 #define CPU_IP0 (_ULCAST_(1))
+1
arch/loongarch/include/uapi/asm/kvm.h
··· 104 104 #define KVM_LOONGARCH_VM_FEAT_PV_IPI 6 105 105 #define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7 106 106 #define KVM_LOONGARCH_VM_FEAT_PTW 8 107 + #define KVM_LOONGARCH_VM_FEAT_MSGINT 9 107 108 108 109 /* Device Control API on vcpu fd */ 109 110 #define KVM_LOONGARCH_VCPU_CPUCFG 0
+13 -2
arch/loongarch/kvm/interrupt.c
··· 21 21 [INT_HWI5] = CPU_IP5, 22 22 [INT_HWI6] = CPU_IP6, 23 23 [INT_HWI7] = CPU_IP7, 24 + [INT_AVEC] = CPU_AVEC, 24 25 }; 25 26 26 27 static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority) ··· 31 30 clear_bit(priority, &vcpu->arch.irq_pending); 32 31 if (priority < EXCCODE_INT_NUM) 33 32 irq = priority_to_irq[priority]; 33 + 34 + if (cpu_has_msgint && (priority == INT_AVEC)) { 35 + set_gcsr_estat(irq); 36 + return 1; 37 + } 34 38 35 39 switch (priority) { 36 40 case INT_TI: ··· 64 58 if (priority < EXCCODE_INT_NUM) 65 59 irq = priority_to_irq[priority]; 66 60 61 + if (cpu_has_msgint && (priority == INT_AVEC)) { 62 + clear_gcsr_estat(irq); 63 + return 1; 64 + } 65 + 67 66 switch (priority) { 68 67 case INT_TI: 69 68 case INT_IPI: ··· 94 83 unsigned long *pending = &vcpu->arch.irq_pending; 95 84 unsigned long *pending_clr = &vcpu->arch.irq_clear; 96 85 97 - for_each_set_bit(priority, pending_clr, INT_IPI + 1) 86 + for_each_set_bit(priority, pending_clr, EXCCODE_INT_NUM) 98 87 kvm_irq_clear(vcpu, priority); 99 88 100 - for_each_set_bit(priority, pending, INT_IPI + 1) 89 + for_each_set_bit(priority, pending, EXCCODE_INT_NUM) 101 90 kvm_irq_deliver(vcpu, priority); 102 91 } 103 92
+17 -2
arch/loongarch/kvm/vcpu.c
··· 659 659 *v = GENMASK(31, 0); 660 660 return 0; 661 661 case LOONGARCH_CPUCFG1: 662 - /* CPUCFG1_MSGINT is not supported by KVM */ 663 - *v = GENMASK(25, 0); 662 + *v = GENMASK(26, 0); 664 663 return 0; 665 664 case LOONGARCH_CPUCFG2: 666 665 /* CPUCFG2 features unconditionally supported by KVM */ ··· 727 728 return -EINVAL; 728 729 729 730 switch (id) { 731 + case LOONGARCH_CPUCFG1: 732 + if ((val & CPUCFG1_MSGINT) && !cpu_has_msgint) 733 + return -EINVAL; 734 + return 0; 730 735 case LOONGARCH_CPUCFG2: 731 736 if (!(val & CPUCFG2_LLFTP)) 732 737 /* Guests must have a constant timer */ ··· 1660 1657 kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2); 1661 1658 kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3); 1662 1659 kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_LLBCTL); 1660 + if (cpu_has_msgint) { 1661 + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR0); 1662 + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR1); 1663 + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR2); 1664 + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR3); 1665 + } 1663 1666 1664 1667 /* Restore Root.GINTC from unused Guest.GINTC register */ 1665 1668 write_csr_gintc(csr->csrs[LOONGARCH_CSR_GINTC]); ··· 1755 1746 kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN1); 1756 1747 kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2); 1757 1748 kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3); 1749 + if (cpu_has_msgint) { 1750 + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR0); 1751 + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR1); 1752 + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR2); 1753 + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR3); 1754 + } 1758 1755 1759 1756 vcpu->arch.aux_inuse |= KVM_LARCH_SWCSR_LATEST; 1760 1757
+4
arch/loongarch/kvm/vm.c
··· 154 154 if (cpu_has_ptw) 155 155 return 0; 156 156 return -ENXIO; 157 + case KVM_LOONGARCH_VM_FEAT_MSGINT: 158 + if (cpu_has_msgint) 159 + return 0; 160 + return -ENXIO; 157 161 case KVM_LOONGARCH_VM_FEAT_PMU: 158 162 case KVM_LOONGARCH_VM_FEAT_PV_IPI: 159 163 case KVM_LOONGARCH_VM_FEAT_PV_STEALTIME: