* [PATCH v3 1/4] LongArch: KVM: Add some maccros for AVEC
2025-12-06 6:46 [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
@ 2025-12-06 6:46 ` Song Gao
2025-12-08 3:45 ` Bibo Mao
2025-12-06 6:46 ` [PATCH v3 2/4] LongArch: KVM: Add DINTC device support Song Gao
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2025-12-06 6:46 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
Add some maccros for AVEC interrupt controller, so the dintc can use
those maccros.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
arch/loongarch/include/asm/irq.h | 8 ++++++++
drivers/irqchip/irq-loongarch-avec.c | 5 +++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h
index 12bd15578c33..aaa022fcb9e3 100644
--- a/arch/loongarch/include/asm/irq.h
+++ b/arch/loongarch/include/asm/irq.h
@@ -50,6 +50,14 @@ void spurious_interrupt(void);
#define NR_LEGACY_VECTORS 16
#define IRQ_MATRIX_BITS NR_VECTORS
+#define AVEC_VIRQ_SHIFT 4
+#define AVEC_VIRQ_BIT 8
+#define AVEC_VIRQ_MASK GENMASK(AVEC_VIRQ_BIT - 1, 0)
+#define AVEC_CPU_SHIFT 12
+#define AVEC_CPU_BIT 16
+#define AVEC_CPU_MASK GENMASK(AVEC_CPU_BIT - 1, 0)
+
+
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c
index bf52dc8345f5..f0118cfd4363 100644
--- a/drivers/irqchip/irq-loongarch-avec.c
+++ b/drivers/irqchip/irq-loongarch-avec.c
@@ -209,8 +209,9 @@ static void avecintc_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
struct avecintc_data *adata = irq_data_get_irq_chip_data(d);
msg->address_hi = 0x0;
- msg->address_lo = (loongarch_avec.msi_base_addr | (adata->vec & 0xff) << 4)
- | ((cpu_logical_map(adata->cpu & 0xffff)) << 12);
+ msg->address_lo = (loongarch_avec.msi_base_addr |
+ (adata->vec & AVEC_VIRQ_MASK) << AVEC_VIRQ_SHIFT) |
+ ((cpu_logical_map(adata->cpu & AVEC_CPU_MASK)) << AVEC_CPU_SHIFT);
msg->data = 0x0;
}
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 1/4] LongArch: KVM: Add some maccros for AVEC
2025-12-06 6:46 ` [PATCH v3 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
@ 2025-12-08 3:45 ` Bibo Mao
0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2025-12-08 3:45 UTC (permalink / raw)
To: Song Gao, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
On 2025/12/6 下午2:46, Song Gao wrote:
> Add some maccros for AVEC interrupt controller, so the dintc can use
> those maccros.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> arch/loongarch/include/asm/irq.h | 8 ++++++++
> drivers/irqchip/irq-loongarch-avec.c | 5 +++--
> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h
> index 12bd15578c33..aaa022fcb9e3 100644
> --- a/arch/loongarch/include/asm/irq.h
> +++ b/arch/loongarch/include/asm/irq.h
> @@ -50,6 +50,14 @@ void spurious_interrupt(void);
> #define NR_LEGACY_VECTORS 16
> #define IRQ_MATRIX_BITS NR_VECTORS
>
> +#define AVEC_VIRQ_SHIFT 4
> +#define AVEC_VIRQ_BIT 8
> +#define AVEC_VIRQ_MASK GENMASK(AVEC_VIRQ_BIT - 1, 0)
> +#define AVEC_CPU_SHIFT 12
(AVEC_VIRQ_SHIFT + AVEC_VIRQ_BIT) compared with hard coded 12 ?
> +#define AVEC_CPU_BIT 16
> +#define AVEC_CPU_MASK GENMASK(AVEC_CPU_BIT - 1, 0)
> +
> +
one more unnecessary space line, otherwise it looks good to me.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
> #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
> void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
>
> diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c
> index bf52dc8345f5..f0118cfd4363 100644
> --- a/drivers/irqchip/irq-loongarch-avec.c
> +++ b/drivers/irqchip/irq-loongarch-avec.c
> @@ -209,8 +209,9 @@ static void avecintc_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
> struct avecintc_data *adata = irq_data_get_irq_chip_data(d);
>
> msg->address_hi = 0x0;
> - msg->address_lo = (loongarch_avec.msi_base_addr | (adata->vec & 0xff) << 4)
> - | ((cpu_logical_map(adata->cpu & 0xffff)) << 12);
> + msg->address_lo = (loongarch_avec.msi_base_addr |
> + (adata->vec & AVEC_VIRQ_MASK) << AVEC_VIRQ_SHIFT) |
> + ((cpu_logical_map(adata->cpu & AVEC_CPU_MASK)) << AVEC_CPU_SHIFT);
> msg->data = 0x0;
> }
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/4] LongArch: KVM: Add DINTC device support
2025-12-06 6:46 [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
2025-12-06 6:46 ` [PATCH v3 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
@ 2025-12-06 6:46 ` Song Gao
2025-12-08 3:54 ` Bibo Mao
2025-12-06 6:46 ` [PATCH v3 3/4] LongArch: KVM: Add irqfd set dintc msi Song Gao
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2025-12-06 6:46 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
Add device model for AVEC interrupt controller, implement basic
create/destroy/set_attr interfaces, and register device model to kvm
device table.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
arch/loongarch/include/asm/kvm_dintc.h | 21 +++++
arch/loongarch/include/asm/kvm_host.h | 3 +
arch/loongarch/include/uapi/asm/kvm.h | 4 +
arch/loongarch/kvm/Makefile | 1 +
arch/loongarch/kvm/intc/dintc.c | 110 +++++++++++++++++++++++++
arch/loongarch/kvm/main.c | 5 ++
include/uapi/linux/kvm.h | 2 +
7 files changed, 146 insertions(+)
create mode 100644 arch/loongarch/include/asm/kvm_dintc.h
create mode 100644 arch/loongarch/kvm/intc/dintc.c
diff --git a/arch/loongarch/include/asm/kvm_dintc.h b/arch/loongarch/include/asm/kvm_dintc.h
new file mode 100644
index 000000000000..d980d39c0344
--- /dev/null
+++ b/arch/loongarch/include/asm/kvm_dintc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+
+#ifndef __ASM_KVM_DINTC_H
+#define __ASM_KVM_DINTC_H
+
+
+struct loongarch_dintc {
+ struct kvm *kvm;
+ uint64_t msg_addr_base;
+ uint64_t msg_addr_size;
+};
+
+struct dintc_state {
+ atomic64_t vector_map[4];
+};
+
+int kvm_loongarch_register_dintc_device(void);
+#endif
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index e4fe5b8e8149..26a90f4146ac 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -22,6 +22,7 @@
#include <asm/kvm_ipi.h>
#include <asm/kvm_eiointc.h>
#include <asm/kvm_pch_pic.h>
+#include <asm/kvm_dintc.h>
#include <asm/loongarch.h>
#define __KVM_HAVE_ARCH_INTC_INITIALIZED
@@ -134,6 +135,7 @@ struct kvm_arch {
struct loongarch_ipi *ipi;
struct loongarch_eiointc *eiointc;
struct loongarch_pch_pic *pch_pic;
+ struct loongarch_dintc *dintc;
};
#define CSR_MAX_NUMS 0x800
@@ -244,6 +246,7 @@ struct kvm_vcpu_arch {
struct kvm_mp_state mp_state;
/* ipi state */
struct ipi_state ipi_state;
+ struct dintc_state dintc_state;
/* cpucfg */
u32 cpucfg[KVM_MAX_CPUCFG_REGS];
diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
index de6c3f18e40a..07da84f7002c 100644
--- a/arch/loongarch/include/uapi/asm/kvm.h
+++ b/arch/loongarch/include/uapi/asm/kvm.h
@@ -154,4 +154,8 @@ struct kvm_iocsr_entry {
#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000006
#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0
+#define KVM_DEV_LOONGARCH_DINTC_CTRL 0x40000007
+#define KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_BASE 0x0
+#define KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE 0x1
+
#endif /* __UAPI_ASM_LOONGARCH_KVM_H */
diff --git a/arch/loongarch/kvm/Makefile b/arch/loongarch/kvm/Makefile
index cb41d9265662..fe984bf1cbdb 100644
--- a/arch/loongarch/kvm/Makefile
+++ b/arch/loongarch/kvm/Makefile
@@ -19,6 +19,7 @@ kvm-y += vm.o
kvm-y += intc/ipi.o
kvm-y += intc/eiointc.o
kvm-y += intc/pch_pic.o
+kvm-y += intc/dintc.o
kvm-y += irqfd.o
CFLAGS_exit.o += $(call cc-disable-warning, override-init)
diff --git a/arch/loongarch/kvm/intc/dintc.c b/arch/loongarch/kvm/intc/dintc.c
new file mode 100644
index 000000000000..cd6cc9392adc
--- /dev/null
+++ b/arch/loongarch/kvm/intc/dintc.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_dintc.h>
+#include <asm/kvm_vcpu.h>
+
+static int kvm_dintc_ctrl_access(struct kvm_device *dev,
+ struct kvm_device_attr *attr,
+ bool is_write)
+{
+ int addr = attr->attr;
+ void __user *data;
+ struct loongarch_dintc *s = dev->kvm->arch.dintc;
+ u64 tmp;
+
+ data = (void __user *)attr->addr;
+ switch (addr) {
+ case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_BASE:
+ if (is_write) {
+ if (copy_from_user(&tmp, data, sizeof(s->msg_addr_base)))
+ return -EFAULT;
+ if (s->msg_addr_base) {
+ /* Duplicate setting are not allowed. */
+ return -EFAULT;
+ }
+ if (tmp > (1UL << AVEC_CPU_SHIFT))
+ s->msg_addr_base = tmp;
+ else
+ return -EFAULT;
+ }
+ break;
+ case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE:
+ if (is_write) {
+ if (copy_from_user(&tmp, data, sizeof(s->msg_addr_size)))
+ return -EFAULT;
+ if (s->msg_addr_size) {
+ /*Duplicate setting are not allowed. */
+ return -EFAULT;
+ }
+ s->msg_addr_size = tmp;
+ }
+ break;
+ default:
+ kvm_err("%s: unknown dintc register, addr = %d\n", __func__, addr);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int kvm_dintc_set_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ switch (attr->group) {
+ case KVM_DEV_LOONGARCH_DINTC_CTRL:
+ return kvm_dintc_ctrl_access(dev, attr, true);
+ default:
+ kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
+ return -EINVAL;
+ }
+}
+
+static int kvm_dintc_create(struct kvm_device *dev, u32 type)
+{
+ struct kvm *kvm;
+ struct loongarch_dintc *s;
+
+ if (!dev) {
+ kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
+ return -EINVAL;
+ }
+
+ kvm = dev->kvm;
+ if (kvm->arch.dintc) {
+ kvm_err("%s: LoongArch DINTC has already been created!\n", __func__);
+ return -EINVAL;
+ }
+
+ s = kzalloc(sizeof(struct loongarch_dintc), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ s->kvm = kvm;
+ kvm->arch.dintc = s;
+ return 0;
+}
+
+static void kvm_dintc_destroy(struct kvm_device *dev)
+{
+
+ if (!dev || !dev->kvm || !dev->kvm->arch.dintc)
+ return;
+
+ kfree(dev->kvm->arch.dintc);
+}
+
+static struct kvm_device_ops kvm_dintc_dev_ops = {
+ .name = "kvm-loongarch-dintc",
+ .create = kvm_dintc_create,
+ .destroy = kvm_dintc_destroy,
+ .set_attr = kvm_dintc_set_attr,
+};
+
+int kvm_loongarch_register_dintc_device(void)
+{
+ return kvm_register_device_ops(&kvm_dintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DINTC);
+}
diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
index 80ea63d465b8..d18d9f4d485c 100644
--- a/arch/loongarch/kvm/main.c
+++ b/arch/loongarch/kvm/main.c
@@ -408,6 +408,11 @@ static int kvm_loongarch_env_init(void)
/* Register LoongArch PCH-PIC interrupt controller interface. */
ret = kvm_loongarch_register_pch_pic_device();
+ if (ret)
+ return ret;
+
+ /* Register LoongArch DINTC interrupt contrroller interface */
+ ret = kvm_loongarch_register_dintc_device();
return ret;
}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index dddb781b0507..ebf86a65eef1 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1209,6 +1209,8 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC
KVM_DEV_TYPE_LOONGARCH_PCHPIC,
#define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC
+ KVM_DEV_TYPE_LOONGARCH_DINTC,
+#define KVM_DEV_TYPE_LOONGARCH_DINTC KVM_DEV_TYPE_LOONGARCH_DINTC
KVM_DEV_TYPE_MAX,
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 2/4] LongArch: KVM: Add DINTC device support
2025-12-06 6:46 ` [PATCH v3 2/4] LongArch: KVM: Add DINTC device support Song Gao
@ 2025-12-08 3:54 ` Bibo Mao
0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2025-12-08 3:54 UTC (permalink / raw)
To: Song Gao, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
On 2025/12/6 下午2:46, Song Gao wrote:
> Add device model for AVEC interrupt controller, implement basic
> create/destroy/set_attr interfaces, and register device model to kvm
> device table.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> arch/loongarch/include/asm/kvm_dintc.h | 21 +++++
> arch/loongarch/include/asm/kvm_host.h | 3 +
> arch/loongarch/include/uapi/asm/kvm.h | 4 +
> arch/loongarch/kvm/Makefile | 1 +
> arch/loongarch/kvm/intc/dintc.c | 110 +++++++++++++++++++++++++
> arch/loongarch/kvm/main.c | 5 ++
> include/uapi/linux/kvm.h | 2 +
> 7 files changed, 146 insertions(+)
> create mode 100644 arch/loongarch/include/asm/kvm_dintc.h
> create mode 100644 arch/loongarch/kvm/intc/dintc.c
>
> diff --git a/arch/loongarch/include/asm/kvm_dintc.h b/arch/loongarch/include/asm/kvm_dintc.h
> new file mode 100644
> index 000000000000..d980d39c0344
> --- /dev/null
> +++ b/arch/loongarch/include/asm/kvm_dintc.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2025 Loongson Technology Corporation Limited
> + */
> +
> +#ifndef __ASM_KVM_DINTC_H
> +#define __ASM_KVM_DINTC_H
> +
> +
> +struct loongarch_dintc {
> + struct kvm *kvm;
> + uint64_t msg_addr_base;
> + uint64_t msg_addr_size;
> +};
> +
> +struct dintc_state {
> + atomic64_t vector_map[4];
> +};
> +
> +int kvm_loongarch_register_dintc_device(void);
> +#endif
> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
> index e4fe5b8e8149..26a90f4146ac 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -22,6 +22,7 @@
> #include <asm/kvm_ipi.h>
> #include <asm/kvm_eiointc.h>
> #include <asm/kvm_pch_pic.h>
> +#include <asm/kvm_dintc.h>
> #include <asm/loongarch.h>
>
> #define __KVM_HAVE_ARCH_INTC_INITIALIZED
> @@ -134,6 +135,7 @@ struct kvm_arch {
> struct loongarch_ipi *ipi;
> struct loongarch_eiointc *eiointc;
> struct loongarch_pch_pic *pch_pic;
> + struct loongarch_dintc *dintc;
> };
>
> #define CSR_MAX_NUMS 0x800
> @@ -244,6 +246,7 @@ struct kvm_vcpu_arch {
> struct kvm_mp_state mp_state;
> /* ipi state */
> struct ipi_state ipi_state;
> + struct dintc_state dintc_state;
> /* cpucfg */
> u32 cpucfg[KVM_MAX_CPUCFG_REGS];
>
> diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
> index de6c3f18e40a..07da84f7002c 100644
> --- a/arch/loongarch/include/uapi/asm/kvm.h
> +++ b/arch/loongarch/include/uapi/asm/kvm.h
> @@ -154,4 +154,8 @@ struct kvm_iocsr_entry {
> #define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000006
> #define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0
>
> +#define KVM_DEV_LOONGARCH_DINTC_CTRL 0x40000007
> +#define KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_BASE 0x0
> +#define KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE 0x1
> +
> #endif /* __UAPI_ASM_LOONGARCH_KVM_H */
> diff --git a/arch/loongarch/kvm/Makefile b/arch/loongarch/kvm/Makefile
> index cb41d9265662..fe984bf1cbdb 100644
> --- a/arch/loongarch/kvm/Makefile
> +++ b/arch/loongarch/kvm/Makefile
> @@ -19,6 +19,7 @@ kvm-y += vm.o
> kvm-y += intc/ipi.o
> kvm-y += intc/eiointc.o
> kvm-y += intc/pch_pic.o
> +kvm-y += intc/dintc.o
> kvm-y += irqfd.o
>
> CFLAGS_exit.o += $(call cc-disable-warning, override-init)
> diff --git a/arch/loongarch/kvm/intc/dintc.c b/arch/loongarch/kvm/intc/dintc.c
> new file mode 100644
> index 000000000000..cd6cc9392adc
> --- /dev/null
> +++ b/arch/loongarch/kvm/intc/dintc.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2025 Loongson Technology Corporation Limited
> + */
> +
> +#include <linux/kvm_host.h>
> +#include <asm/kvm_dintc.h>
> +#include <asm/kvm_vcpu.h>
> +
> +static int kvm_dintc_ctrl_access(struct kvm_device *dev,
> + struct kvm_device_attr *attr,
> + bool is_write)
> +{
> + int addr = attr->attr;
> + void __user *data;
> + struct loongarch_dintc *s = dev->kvm->arch.dintc;
> + u64 tmp;
> +
> + data = (void __user *)attr->addr;
> + switch (addr) {
> + case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_BASE:
> + if (is_write) {
> + if (copy_from_user(&tmp, data, sizeof(s->msg_addr_base)))
> + return -EFAULT;
> + if (s->msg_addr_base) {
> + /* Duplicate setting are not allowed. */
> + return -EFAULT;
> + }
> + if (tmp > (1UL << AVEC_CPU_SHIFT))
The address check should be (tmp & (BIT(AVEC_CPU_SHIFT) - 1) == 0 ?
otherwise look good to me.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
> + s->msg_addr_base = tmp;
> + else
> + return -EFAULT;
> + }
> + break;
> + case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE:
> + if (is_write) {
> + if (copy_from_user(&tmp, data, sizeof(s->msg_addr_size)))
> + return -EFAULT;
> + if (s->msg_addr_size) {
> + /*Duplicate setting are not allowed. */
> + return -EFAULT;
> + }
> + s->msg_addr_size = tmp;
> + }
> + break;
> + default:
> + kvm_err("%s: unknown dintc register, addr = %d\n", __func__, addr);
> + return -ENXIO;
> + }
> +
> + return 0;
> +}
> +
> +static int kvm_dintc_set_attr(struct kvm_device *dev,
> + struct kvm_device_attr *attr)
> +{
> + switch (attr->group) {
> + case KVM_DEV_LOONGARCH_DINTC_CTRL:
> + return kvm_dintc_ctrl_access(dev, attr, true);
> + default:
> + kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
> + return -EINVAL;
> + }
> +}
> +
> +static int kvm_dintc_create(struct kvm_device *dev, u32 type)
> +{
> + struct kvm *kvm;
> + struct loongarch_dintc *s;
> +
> + if (!dev) {
> + kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
> + return -EINVAL;
> + }
> +
> + kvm = dev->kvm;
> + if (kvm->arch.dintc) {
> + kvm_err("%s: LoongArch DINTC has already been created!\n", __func__);
> + return -EINVAL;
> + }
> +
> + s = kzalloc(sizeof(struct loongarch_dintc), GFP_KERNEL);
> + if (!s)
> + return -ENOMEM;
> +
> + s->kvm = kvm;
> + kvm->arch.dintc = s;
> + return 0;
> +}
> +
> +static void kvm_dintc_destroy(struct kvm_device *dev)
> +{
> +
> + if (!dev || !dev->kvm || !dev->kvm->arch.dintc)
> + return;
> +
> + kfree(dev->kvm->arch.dintc);
> +}
> +
> +static struct kvm_device_ops kvm_dintc_dev_ops = {
> + .name = "kvm-loongarch-dintc",
> + .create = kvm_dintc_create,
> + .destroy = kvm_dintc_destroy,
> + .set_attr = kvm_dintc_set_attr,
> +};
> +
> +int kvm_loongarch_register_dintc_device(void)
> +{
> + return kvm_register_device_ops(&kvm_dintc_dev_ops, KVM_DEV_TYPE_LOONGARCH_DINTC);
> +}
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index 80ea63d465b8..d18d9f4d485c 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -408,6 +408,11 @@ static int kvm_loongarch_env_init(void)
>
> /* Register LoongArch PCH-PIC interrupt controller interface. */
> ret = kvm_loongarch_register_pch_pic_device();
> + if (ret)
> + return ret;
> +
> + /* Register LoongArch DINTC interrupt contrroller interface */
> + ret = kvm_loongarch_register_dintc_device();
>
> return ret;
> }
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index dddb781b0507..ebf86a65eef1 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1209,6 +1209,8 @@ enum kvm_device_type {
> #define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC
> KVM_DEV_TYPE_LOONGARCH_PCHPIC,
> #define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC
> + KVM_DEV_TYPE_LOONGARCH_DINTC,
> +#define KVM_DEV_TYPE_LOONGARCH_DINTC KVM_DEV_TYPE_LOONGARCH_DINTC
>
> KVM_DEV_TYPE_MAX,
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 3/4] LongArch: KVM: Add irqfd set dintc msi
2025-12-06 6:46 [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
2025-12-06 6:46 ` [PATCH v3 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
2025-12-06 6:46 ` [PATCH v3 2/4] LongArch: KVM: Add DINTC device support Song Gao
@ 2025-12-06 6:46 ` Song Gao
2025-12-08 3:58 ` Bibo Mao
2025-12-06 6:46 ` [PATCH v3 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu Song Gao
2025-12-13 12:39 ` [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Huacai Chen
4 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2025-12-06 6:46 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
Add irqfd choice dintc to set msi irq by the msg_addr and
implement dintc set msi irq.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
arch/loongarch/include/asm/kvm_dintc.h | 1 +
arch/loongarch/kvm/intc/dintc.c | 6 ++++
arch/loongarch/kvm/irqfd.c | 45 ++++++++++++++++++++++----
3 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/arch/loongarch/include/asm/kvm_dintc.h b/arch/loongarch/include/asm/kvm_dintc.h
index d980d39c0344..f87fb802a7bf 100644
--- a/arch/loongarch/include/asm/kvm_dintc.h
+++ b/arch/loongarch/include/asm/kvm_dintc.h
@@ -11,6 +11,7 @@ struct loongarch_dintc {
struct kvm *kvm;
uint64_t msg_addr_base;
uint64_t msg_addr_size;
+ uint32_t cpu_mask;
};
struct dintc_state {
diff --git a/arch/loongarch/kvm/intc/dintc.c b/arch/loongarch/kvm/intc/dintc.c
index cd6cc9392adc..15e2ccd25a63 100644
--- a/arch/loongarch/kvm/intc/dintc.c
+++ b/arch/loongarch/kvm/intc/dintc.c
@@ -15,6 +15,7 @@ static int kvm_dintc_ctrl_access(struct kvm_device *dev,
void __user *data;
struct loongarch_dintc *s = dev->kvm->arch.dintc;
u64 tmp;
+ u32 cpu_bit;
data = (void __user *)attr->addr;
switch (addr) {
@@ -30,6 +31,11 @@ static int kvm_dintc_ctrl_access(struct kvm_device *dev,
s->msg_addr_base = tmp;
else
return -EFAULT;
+ s->msg_addr_base = tmp;
+ cpu_bit = find_first_bit((unsigned long *)&(s->msg_addr_base), 64)
+ - AVEC_CPU_SHIFT;
+ cpu_bit = min(cpu_bit, AVEC_CPU_BIT);
+ s->cpu_mask = GENMASK(cpu_bit - 1, 0) & AVEC_CPU_MASK;
}
break;
case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE:
diff --git a/arch/loongarch/kvm/irqfd.c b/arch/loongarch/kvm/irqfd.c
index 9a39627aecf0..d49a6c6471df 100644
--- a/arch/loongarch/kvm/irqfd.c
+++ b/arch/loongarch/kvm/irqfd.c
@@ -6,6 +6,7 @@
#include <linux/kvm_host.h>
#include <trace/events/kvm.h>
#include <asm/kvm_pch_pic.h>
+#include <asm/kvm_vcpu.h>
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level, bool line_status)
@@ -16,6 +17,41 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
return 0;
}
+static int kvm_dintc_set_msi_irq(struct kvm *kvm, u32 addr, int data, int level)
+{
+ unsigned int virq, dest;
+ struct kvm_vcpu *vcpu;
+
+ virq = (addr >> AVEC_VIRQ_SHIFT) & AVEC_VIRQ_MASK;
+ dest = (addr >> AVEC_CPU_SHIFT) & kvm->arch.dintc->cpu_mask;
+ if (dest > KVM_MAX_VCPUS)
+ return -EINVAL;
+ vcpu = kvm_get_vcpu_by_cpuid(kvm, dest);
+ if (!vcpu)
+ return -EINVAL;
+ return kvm_loongarch_deliver_msi_to_vcpu(kvm, vcpu, virq, level);
+}
+
+static int loongarch_set_msi(struct kvm_kernel_irq_routing_entry *e,
+ struct kvm *kvm, int level)
+{
+ u64 msg_addr;
+
+ if (!level)
+ return -1;
+
+ msg_addr = (((u64)e->msi.address_hi) << 32) | e->msi.address_lo;
+ if (cpu_has_msgint && kvm->arch.dintc &&
+ msg_addr >= kvm->arch.dintc->msg_addr_base &&
+ msg_addr < (kvm->arch.dintc->msg_addr_base + kvm->arch.dintc->msg_addr_size)) {
+ return kvm_dintc_set_msi_irq(kvm, msg_addr, e->msi.data, level);
+ } else {
+ pch_msi_set_irq(kvm, e->msi.data, level);
+ }
+
+ return 0;
+}
+
/*
* kvm_set_msi: inject the MSI corresponding to the
* MSI routing entry
@@ -26,12 +62,7 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level, bool line_status)
{
- if (!level)
- return -1;
-
- pch_msi_set_irq(kvm, e->msi.data, level);
-
- return 0;
+ return loongarch_set_msi(e, kvm, level);
}
/*
@@ -76,7 +107,7 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
pch_pic_set_irq(kvm->arch.pch_pic, e->irqchip.pin, level);
return 0;
case KVM_IRQ_ROUTING_MSI:
- pch_msi_set_irq(kvm, e->msi.data, level);
+ loongarch_set_msi(e, kvm, level);
return 0;
default:
return -EWOULDBLOCK;
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 3/4] LongArch: KVM: Add irqfd set dintc msi
2025-12-06 6:46 ` [PATCH v3 3/4] LongArch: KVM: Add irqfd set dintc msi Song Gao
@ 2025-12-08 3:58 ` Bibo Mao
0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2025-12-08 3:58 UTC (permalink / raw)
To: Song Gao, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
On 2025/12/6 下午2:46, Song Gao wrote:
> Add irqfd choice dintc to set msi irq by the msg_addr and
> implement dintc set msi irq.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> arch/loongarch/include/asm/kvm_dintc.h | 1 +
> arch/loongarch/kvm/intc/dintc.c | 6 ++++
> arch/loongarch/kvm/irqfd.c | 45 ++++++++++++++++++++++----
> 3 files changed, 45 insertions(+), 7 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_dintc.h b/arch/loongarch/include/asm/kvm_dintc.h
> index d980d39c0344..f87fb802a7bf 100644
> --- a/arch/loongarch/include/asm/kvm_dintc.h
> +++ b/arch/loongarch/include/asm/kvm_dintc.h
> @@ -11,6 +11,7 @@ struct loongarch_dintc {
> struct kvm *kvm;
> uint64_t msg_addr_base;
> uint64_t msg_addr_size;
> + uint32_t cpu_mask;
> };
>
> struct dintc_state {
> diff --git a/arch/loongarch/kvm/intc/dintc.c b/arch/loongarch/kvm/intc/dintc.c
> index cd6cc9392adc..15e2ccd25a63 100644
> --- a/arch/loongarch/kvm/intc/dintc.c
> +++ b/arch/loongarch/kvm/intc/dintc.c
> @@ -15,6 +15,7 @@ static int kvm_dintc_ctrl_access(struct kvm_device *dev,
> void __user *data;
> struct loongarch_dintc *s = dev->kvm->arch.dintc;
> u64 tmp;
> + u32 cpu_bit;
>
> data = (void __user *)attr->addr;
> switch (addr) {
> @@ -30,6 +31,11 @@ static int kvm_dintc_ctrl_access(struct kvm_device *dev,
> s->msg_addr_base = tmp;
> else
> return -EFAULT;
> + s->msg_addr_base = tmp;
> + cpu_bit = find_first_bit((unsigned long *)&(s->msg_addr_base), 64)
> + - AVEC_CPU_SHIFT;
> + cpu_bit = min(cpu_bit, AVEC_CPU_BIT);
> + s->cpu_mask = GENMASK(cpu_bit - 1, 0) & AVEC_CPU_MASK;
> }
> break;
> case KVM_DEV_LOONGARCH_DINTC_MSG_ADDR_SIZE:
> diff --git a/arch/loongarch/kvm/irqfd.c b/arch/loongarch/kvm/irqfd.c
> index 9a39627aecf0..d49a6c6471df 100644
> --- a/arch/loongarch/kvm/irqfd.c
> +++ b/arch/loongarch/kvm/irqfd.c
> @@ -6,6 +6,7 @@
> #include <linux/kvm_host.h>
> #include <trace/events/kvm.h>
> #include <asm/kvm_pch_pic.h>
> +#include <asm/kvm_vcpu.h>
>
> static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
> struct kvm *kvm, int irq_source_id, int level, bool line_status)
> @@ -16,6 +17,41 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
> return 0;
> }
>
> +static int kvm_dintc_set_msi_irq(struct kvm *kvm, u32 addr, int data, int level)
> +{
> + unsigned int virq, dest;
> + struct kvm_vcpu *vcpu;
> +
> + virq = (addr >> AVEC_VIRQ_SHIFT) & AVEC_VIRQ_MASK;
> + dest = (addr >> AVEC_CPU_SHIFT) & kvm->arch.dintc->cpu_mask;
> + if (dest > KVM_MAX_VCPUS)
> + return -EINVAL;
> + vcpu = kvm_get_vcpu_by_cpuid(kvm, dest);
> + if (!vcpu)
> + return -EINVAL;
> + return kvm_loongarch_deliver_msi_to_vcpu(kvm, vcpu, virq, level);
> +}
> +
> +static int loongarch_set_msi(struct kvm_kernel_irq_routing_entry *e,
> + struct kvm *kvm, int level)
> +{
> + u64 msg_addr;
> +
> + if (!level)
> + return -1;
> +
> + msg_addr = (((u64)e->msi.address_hi) << 32) | e->msi.address_lo;
> + if (cpu_has_msgint && kvm->arch.dintc &&
> + msg_addr >= kvm->arch.dintc->msg_addr_base &&
> + msg_addr < (kvm->arch.dintc->msg_addr_base + kvm->arch.dintc->msg_addr_size)) {
> + return kvm_dintc_set_msi_irq(kvm, msg_addr, e->msi.data, level);
> + } else {
> + pch_msi_set_irq(kvm, e->msi.data, level);
> + }
> +
> + return 0;
> +}
> +
> /*
> * kvm_set_msi: inject the MSI corresponding to the
> * MSI routing entry
> @@ -26,12 +62,7 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
> int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
> struct kvm *kvm, int irq_source_id, int level, bool line_status)
> {
> - if (!level)
> - return -1;
> -
> - pch_msi_set_irq(kvm, e->msi.data, level);
> -
> - return 0;
> + return loongarch_set_msi(e, kvm, level);
> }
>
> /*
> @@ -76,7 +107,7 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
> pch_pic_set_irq(kvm->arch.pch_pic, e->irqchip.pin, level);
> return 0;
> case KVM_IRQ_ROUTING_MSI:
> - pch_msi_set_irq(kvm, e->msi.data, level);
> + loongarch_set_msi(e, kvm, level);
> return 0;
> default:
> return -EWOULDBLOCK;
>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu
2025-12-06 6:46 [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
` (2 preceding siblings ...)
2025-12-06 6:46 ` [PATCH v3 3/4] LongArch: KVM: Add irqfd set dintc msi Song Gao
@ 2025-12-06 6:46 ` Song Gao
2025-12-08 4:04 ` Bibo Mao
2025-12-13 12:39 ` [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Huacai Chen
4 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2025-12-06 6:46 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
Implement irqfd deliver msi to vcpu and
vcpu dintc inject irq.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
arch/loongarch/include/asm/kvm_host.h | 5 +++
arch/loongarch/kvm/interrupt.c | 1 +
arch/loongarch/kvm/vcpu.c | 55 +++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index 26a90f4146ac..8099dd3f71dd 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -258,6 +258,11 @@ struct kvm_vcpu_arch {
} st;
};
+void loongarch_dintc_inject_irq(struct kvm_vcpu *vcpu);
+int kvm_loongarch_deliver_msi_to_vcpu(struct kvm *kvm,
+ struct kvm_vcpu *vcpu,
+ u32 vector, int level);
+
static inline unsigned long readl_sw_gcsr(struct loongarch_csrs *csr, int reg)
{
return csr->csrs[reg];
diff --git a/arch/loongarch/kvm/interrupt.c b/arch/loongarch/kvm/interrupt.c
index a6d42d399a59..c74e7af3e772 100644
--- a/arch/loongarch/kvm/interrupt.c
+++ b/arch/loongarch/kvm/interrupt.c
@@ -33,6 +33,7 @@ static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
irq = priority_to_irq[priority];
if (cpu_has_msgint && (priority == INT_AVEC)) {
+ loongarch_dintc_inject_irq(vcpu);
set_gcsr_estat(irq);
return 1;
}
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 6d833599ef2e..356d288799ac 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -13,6 +13,61 @@
#define CREATE_TRACE_POINTS
#include "trace.h"
+void loongarch_dintc_inject_irq(struct kvm_vcpu *vcpu)
+{
+ struct dintc_state *ds = &vcpu->arch.dintc_state;
+ unsigned int i;
+ unsigned long temp[4], old;
+
+ if (!ds)
+ return;
+
+ for (i = 0; i < 4; i++) {
+ old = atomic64_read(&(ds->vector_map[i]));
+ if (old)
+ temp[i] = atomic64_xchg(&(ds->vector_map[i]), 0);
+ }
+
+ if (temp[0]) {
+ old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR0);
+ kvm_write_hw_gcsr(LOONGARCH_CSR_ISR0, temp[0]|old);
+ }
+ if (temp[1]) {
+ old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR1);
+ kvm_write_hw_gcsr(LOONGARCH_CSR_ISR1, temp[1]|old);
+ }
+ if (temp[2]) {
+ old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR2);
+ kvm_write_hw_gcsr(LOONGARCH_CSR_ISR2, temp[2]|old);
+ }
+ if (temp[3]) {
+ old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR3);
+ kvm_write_hw_gcsr(LOONGARCH_CSR_ISR3, temp[3]|old);
+ }
+}
+
+int kvm_loongarch_deliver_msi_to_vcpu(struct kvm *kvm,
+ struct kvm_vcpu *vcpu,
+ u32 vector, int level)
+{
+ struct kvm_interrupt vcpu_irq;
+ struct dintc_state *ds;
+
+ if (!level)
+ return 0;
+ if (!vcpu || vector >= 256)
+ return -EINVAL;
+ ds = &vcpu->arch.dintc_state;
+ if (!ds)
+ return -ENODEV;
+ set_bit(vector, (unsigned long *)&ds->vector_map);
+ vcpu_irq.irq = INT_AVEC;
+ kvm_vcpu_ioctl_interrupt(vcpu, &vcpu_irq);
+ kvm_vcpu_kick(vcpu);
+ return 0;
+}
+
+
const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
KVM_GENERIC_VCPU_STATS(),
STATS_DESC_COUNTER(VCPU, int_exits),
--
2.39.3
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu
2025-12-06 6:46 ` [PATCH v3 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu Song Gao
@ 2025-12-08 4:04 ` Bibo Mao
0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2025-12-08 4:04 UTC (permalink / raw)
To: Song Gao, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel, lixianglai
On 2025/12/6 下午2:46, Song Gao wrote:
> Implement irqfd deliver msi to vcpu and
> vcpu dintc inject irq.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> arch/loongarch/include/asm/kvm_host.h | 5 +++
> arch/loongarch/kvm/interrupt.c | 1 +
> arch/loongarch/kvm/vcpu.c | 55 +++++++++++++++++++++++++++
> 3 files changed, 61 insertions(+)
>
> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
> index 26a90f4146ac..8099dd3f71dd 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -258,6 +258,11 @@ struct kvm_vcpu_arch {
> } st;
> };
>
> +void loongarch_dintc_inject_irq(struct kvm_vcpu *vcpu);
> +int kvm_loongarch_deliver_msi_to_vcpu(struct kvm *kvm,
> + struct kvm_vcpu *vcpu,
> + u32 vector, int level);
> +
> static inline unsigned long readl_sw_gcsr(struct loongarch_csrs *csr, int reg)
> {
> return csr->csrs[reg];
> diff --git a/arch/loongarch/kvm/interrupt.c b/arch/loongarch/kvm/interrupt.c
> index a6d42d399a59..c74e7af3e772 100644
> --- a/arch/loongarch/kvm/interrupt.c
> +++ b/arch/loongarch/kvm/interrupt.c
> @@ -33,6 +33,7 @@ static int kvm_irq_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
> irq = priority_to_irq[priority];
>
> if (cpu_has_msgint && (priority == INT_AVEC)) {
> + loongarch_dintc_inject_irq(vcpu);
> set_gcsr_estat(irq);
> return 1;
> }
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 6d833599ef2e..356d288799ac 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -13,6 +13,61 @@
> #define CREATE_TRACE_POINTS
> #include "trace.h"
>
> +void loongarch_dintc_inject_irq(struct kvm_vcpu *vcpu)
> +{
> + struct dintc_state *ds = &vcpu->arch.dintc_state;
> + unsigned int i;
> + unsigned long temp[4], old;
> +
> + if (!ds)
> + return;
> +
> + for (i = 0; i < 4; i++) {
> + old = atomic64_read(&(ds->vector_map[i]));
> + if (old)
> + temp[i] = atomic64_xchg(&(ds->vector_map[i]), 0);
> + }
> +
> + if (temp[0]) {
> + old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR0);
> + kvm_write_hw_gcsr(LOONGARCH_CSR_ISR0, temp[0]|old);
> + }
should there be one extra space line between two if() sentenses?
> + if (temp[1]) {
> + old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR1);
> + kvm_write_hw_gcsr(LOONGARCH_CSR_ISR1, temp[1]|old);
> + }
ditto
> + if (temp[2]) {
> + old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR2);
> + kvm_write_hw_gcsr(LOONGARCH_CSR_ISR2, temp[2]|old);
> + }
ditto
the other looks good to me.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
> + if (temp[3]) {
> + old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR3);
> + kvm_write_hw_gcsr(LOONGARCH_CSR_ISR3, temp[3]|old);
> + }
> +}
> +
> +int kvm_loongarch_deliver_msi_to_vcpu(struct kvm *kvm,
> + struct kvm_vcpu *vcpu,
> + u32 vector, int level)
> +{
> + struct kvm_interrupt vcpu_irq;
> + struct dintc_state *ds;
> +
> + if (!level)
> + return 0;
> + if (!vcpu || vector >= 256)
> + return -EINVAL;
> + ds = &vcpu->arch.dintc_state;
> + if (!ds)
> + return -ENODEV;
> + set_bit(vector, (unsigned long *)&ds->vector_map);
> + vcpu_irq.irq = INT_AVEC;
> + kvm_vcpu_ioctl_interrupt(vcpu, &vcpu_irq);
> + kvm_vcpu_kick(vcpu);
> + return 0;
> +}
> +
> +
> const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
> KVM_GENERIC_VCPU_STATS(),
> STATS_DESC_COUNTER(VCPU, int_exits),
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel
2025-12-06 6:46 [PATCH v3 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
` (3 preceding siblings ...)
2025-12-06 6:46 ` [PATCH v3 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu Song Gao
@ 2025-12-13 12:39 ` Huacai Chen
4 siblings, 0 replies; 10+ messages in thread
From: Huacai Chen @ 2025-12-13 12:39 UTC (permalink / raw)
To: Song Gao; +Cc: maobibo, kvm, loongarch, kernel, linux-kernel, lixianglai
Hi, Song,
On Sat, Dec 6, 2025 at 3:11 PM Song Gao <gaosong@loongson.cn> wrote:
>
> Hi,
>
> This series adds AVEC-related macros, implements the DINTC in-kernel irqchip device,
> enables irqfd to deliver MSI to DINTC, and supports injecting MSI interrupts
> to the target vCPU.
>
>
> V3: Fix kvm_arch_set_irq_inatomic() missing dintc set msi.(patch3)
>
> V2:
> https://patchew.org/linux/20251128091125.2720148-1-gaosong@loongson.cn/
>
> Thanks.
> Song Gao
>
> Song Gao (4):
> LongArch: KVM: Add some maccros for AVEC
The first patch has been merged.
For others, I prefer the AVEC/AVECINTC naming rather than DINTC, since
the driver name and your cover letter both call it AVEC.
But If you don't like AVEC or want to keep consistency with the user
manual, please use DMSINTC because the IOCSR feature bit is called
DMSI.
Huacai
> LongArch: KVM: Add DINTC device support
> LongArch: KVM: Add irqfd set dintc msi
> LongArch: KVM: Add dintc inject msi to the dest vcpu
>
> arch/loongarch/include/asm/irq.h | 8 ++
> arch/loongarch/include/asm/kvm_dintc.h | 22 +++++
> arch/loongarch/include/asm/kvm_host.h | 8 ++
> arch/loongarch/include/uapi/asm/kvm.h | 4 +
> arch/loongarch/kvm/Makefile | 1 +
> arch/loongarch/kvm/intc/dintc.c | 116 +++++++++++++++++++++++++
> arch/loongarch/kvm/interrupt.c | 1 +
> arch/loongarch/kvm/irqfd.c | 45 ++++++++--
> arch/loongarch/kvm/main.c | 5 ++
> arch/loongarch/kvm/vcpu.c | 55 ++++++++++++
> drivers/irqchip/irq-loongarch-avec.c | 5 +-
> include/uapi/linux/kvm.h | 2 +
> 12 files changed, 263 insertions(+), 9 deletions(-)
> create mode 100644 arch/loongarch/include/asm/kvm_dintc.h
> create mode 100644 arch/loongarch/kvm/intc/dintc.c
>
> --
> 2.39.3
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread