[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <28fff8cb-d436-78c7-1836-2fc0f71f806b@loongson.cn>
Date: Wed, 15 Oct 2025 16:23:22 +0800
From: Bibo Mao <maobibo@...ngson.cn>
To: Song Gao <gaosong@...ngson.cn>, chenhuacai@...nel.org
Cc: kvm@...r.kernel.org, loongarch@...ts.linux.dev, kernel@...0n.name,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3] LoongArch: KVM: Add AVEC support
On 2025/10/15 下午2:06, Song Gao wrote:
> Add cpu_has_msgint() to check whether the host cpu supported avec,
> and restore/save CSR_MSGIS0-CSR_MSGIS3.
>
> Signed-off-by: Song Gao <gaosong@...ngson.cn>
> ---
> arch/loongarch/include/asm/kvm_host.h | 4 ++++
> arch/loongarch/include/asm/kvm_vcpu.h | 1 +
> arch/loongarch/include/uapi/asm/kvm.h | 1 +
> arch/loongarch/kvm/interrupt.c | 15 +++++++++++++--
> arch/loongarch/kvm/vcpu.c | 19 +++++++++++++++++--
> arch/loongarch/kvm/vm.c | 4 ++++
> 6 files changed, 40 insertions(+), 4 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
> index 0cecbd038bb3..827e204bdeb3 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -283,6 +283,10 @@ static inline bool kvm_guest_has_lbt(struct kvm_vcpu_arch *arch)
> return arch->cpucfg[2] & (CPUCFG2_X86BT | CPUCFG2_ARMBT | CPUCFG2_MIPSBT);
> }
>
> +static inline bool cpu_has_msgint(void)
> +{
> + return read_cpucfg(LOONGARCH_CPUCFG1) & CPUCFG1_MSGINT;
> +}
> static inline bool kvm_guest_has_pmu(struct kvm_vcpu_arch *arch)
> {
> return arch->cpucfg[6] & CPUCFG6_PMP;
> diff --git a/arch/loongarch/include/asm/kvm_vcpu.h b/arch/loongarch/include/asm/kvm_vcpu.h
> index f1efd7cfbc20..3784ab4ccdb5 100644
> --- a/arch/loongarch/include/asm/kvm_vcpu.h
> +++ b/arch/loongarch/include/asm/kvm_vcpu.h
> @@ -15,6 +15,7 @@
> #define CPU_PMU (_ULCAST_(1) << 10)
> #define CPU_TIMER (_ULCAST_(1) << 11)
> #define CPU_IPI (_ULCAST_(1) << 12)
> +#define CPU_AVEC (_ULCAST_(1) << 14)
>
> /* Controlled by 0x52 guest exception VIP aligned to estat bit 5~12 */
> #define CPU_IP0 (_ULCAST_(1))
> diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
> index 57ba1a563bb1..de6c3f18e40a 100644
> --- a/arch/loongarch/include/uapi/asm/kvm.h
> +++ b/arch/loongarch/include/uapi/asm/kvm.h
> @@ -104,6 +104,7 @@ struct kvm_fpu {
> #define KVM_LOONGARCH_VM_FEAT_PV_IPI 6
> #define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7
> #define KVM_LOONGARCH_VM_FEAT_PTW 8
> +#define KVM_LOONGARCH_VM_FEAT_MSGINT 9
>
> /* Device Control API on vcpu fd */
> #define KVM_LOONGARCH_VCPU_CPUCFG 0
> diff --git a/arch/loongarch/kvm/interrupt.c b/arch/loongarch/kvm/interrupt.c
> index 8462083f0301..f586f421bc19 100644
> --- a/arch/loongarch/kvm/interrupt.c
> +++ b/arch/loongarch/kvm/interrupt.c
> @@ -21,6 +21,7 @@ static unsigned int priority_to_irq[EXCCODE_INT_NUM] = {
> [INT_HWI5] = CPU_IP5,
> [INT_HWI6] = CPU_IP6,
> [INT_HWI7] = CPU_IP7,
> + [INT_AVEC] = CPU_AVEC,
> };
>
> static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
> @@ -31,6 +32,11 @@ static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
> if (priority < EXCCODE_INT_NUM)
> irq = priority_to_irq[priority];
>
> + if (cpu_has_msgint() && (priority == INT_AVEC)) {
> + set_gcsr_estat(irq);
> + return 1;
> + }
> +
> switch (priority) {
> case INT_TI:
> case INT_IPI:
> @@ -58,6 +64,11 @@ static int kvm_irq_clear(struct kvm_vcpu *vcpu, unsigned int priority)
> if (priority < EXCCODE_INT_NUM)
> irq = priority_to_irq[priority];
>
> + if (cpu_has_msgint() && (priority == INT_AVEC)) {
> + clear_gcsr_estat(irq);
> + return 1;
> + }
> +
> switch (priority) {
> case INT_TI:
> case INT_IPI:
> @@ -83,10 +94,10 @@ void kvm_deliver_intr(struct kvm_vcpu *vcpu)
> unsigned long *pending = &vcpu->arch.irq_pending;
> unsigned long *pending_clr = &vcpu->arch.irq_clear;
>
> - for_each_set_bit(priority, pending_clr, INT_IPI + 1)
> + for_each_set_bit(priority, pending_clr, EXCCODE_INT_NUM)
> kvm_irq_clear(vcpu, priority);
>
> - for_each_set_bit(priority, pending, INT_IPI + 1)
> + for_each_set_bit(priority, pending, EXCCODE_INT_NUM)
> kvm_irq_deliver(vcpu, priority);
> }
>
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 30e3b089a596..226c735155be 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -657,8 +657,7 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
> *v = GENMASK(31, 0);
> return 0;
> case LOONGARCH_CPUCFG1:
> - /* CPUCFG1_MSGINT is not supported by KVM */
> - *v = GENMASK(25, 0);
> + *v = GENMASK(26, 0);
> return 0;
> case LOONGARCH_CPUCFG2:
> /* CPUCFG2 features unconditionally supported by KVM */
> @@ -726,6 +725,10 @@ static int kvm_check_cpucfg(int id, u64 val)
> return -EINVAL;
>
> switch (id) {
> + case LOONGARCH_CPUCFG1:
> + if ((val & CPUCFG1_MSGINT) && (!cpu_has_msgint()))
> + return -EINVAL;
> + return 0;
> case LOONGARCH_CPUCFG2:
> if (!(val & CPUCFG2_LLFTP))
> /* Guests must have a constant timer */
> @@ -1658,6 +1661,12 @@ static int _kvm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2);
> kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3);
> kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_LLBCTL);
> + if (cpu_has_msgint()) {
> + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR0);
> + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR1);
> + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR2);
> + kvm_restore_hw_gcsr(csr, LOONGARCH_CSR_ISR3);
> + }
>
> /* Restore Root.GINTC from unused Guest.GINTC register */
> write_csr_gintc(csr->csrs[LOONGARCH_CSR_GINTC]);
> @@ -1747,6 +1756,12 @@ static int _kvm_vcpu_put(struct kvm_vcpu *vcpu, int cpu)
> kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN1);
> kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN2);
> kvm_save_hw_gcsr(csr, LOONGARCH_CSR_DMWIN3);
> + if (cpu_has_msgint()) {
> + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR0);
> + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR1);
> + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR2);
> + kvm_save_hw_gcsr(csr, LOONGARCH_CSR_ISR3);
> + }
>
> vcpu->arch.aux_inuse |= KVM_LARCH_SWCSR_LATEST;
>
> diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c
> index a49b1c1a3dd1..ec92e6f3cf92 100644
> --- a/arch/loongarch/kvm/vm.c
> +++ b/arch/loongarch/kvm/vm.c
> @@ -150,6 +150,10 @@ static int kvm_vm_feature_has_attr(struct kvm *kvm, struct kvm_device_attr *attr
> if (cpu_has_ptw)
> return 0;
> return -ENXIO;
> + case KVM_LOONGARCH_VM_FEAT_MSGINT:
> + if (cpu_has_msgint())
> + return 0;
> + return -ENXIO;
> default:
> return -ENXIO;
> }
>
> base-commit: 9b332cece987ee1790b2ed4c989e28162fa47860
>
Reviewed-by: Bibo Mao <maobibo@...ngson.cn>
Powered by blists - more mailing lists