* [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC
2025-11-28 9:11 [PATCH v2 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
@ 2025-11-28 9:11 ` Song Gao
2025-11-28 12:41 ` Huacai Chen
2025-12-15 15:34 ` Thomas Gleixner
2025-11-28 9:11 ` [PATCH v2 2/4] LongArch: KVM: Add DINTC device support Song Gao
` (2 subsequent siblings)
3 siblings, 2 replies; 8+ messages in thread
From: Song Gao @ 2025-11-28 9:11 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel
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 related [flat|nested] 8+ messages in thread* Re: [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC
2025-11-28 9:11 ` [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
@ 2025-11-28 12:41 ` Huacai Chen
2025-12-15 15:34 ` Thomas Gleixner
1 sibling, 0 replies; 8+ messages in thread
From: Huacai Chen @ 2025-11-28 12:41 UTC (permalink / raw)
To: Song Gao, Thomas Gleixner; +Cc: maobibo, kvm, loongarch, kernel, linux-kernel
Hi, Thomas,
On Fri, Nov 28, 2025 at 5:35 PM Song Gao <gaosong@loongson.cn> wrote:
>
> Add some maccros for AVEC interrupt controller, so the dintc can use
> those maccros.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
Would you mind if I apply this simple patch to the loongarch tree?
Later patches depend on this one, but if it is taken into the irqchip
tree, this series is not very convenient for kvm.
Huacai
> ---
> 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] 8+ messages in thread
* Re: [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC
2025-11-28 9:11 ` [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
2025-11-28 12:41 ` Huacai Chen
@ 2025-12-15 15:34 ` Thomas Gleixner
1 sibling, 0 replies; 8+ messages in thread
From: Thomas Gleixner @ 2025-12-15 15:34 UTC (permalink / raw)
To: Song Gao, maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel
On Fri, Nov 28 2025 at 17:11, Song Gao wrote:
> Add some maccros for AVEC interrupt controller, so the dintc can use
> those maccros.
/maccros/macros/
Also your change log fails to mention that this updates the AVEC
driver, which is a nice change but unrelated to $subject.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/4] LongArch: KVM: Add DINTC device support
2025-11-28 9:11 [PATCH v2 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
2025-11-28 9:11 ` [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
@ 2025-11-28 9:11 ` Song Gao
2025-12-01 12:18 ` kernel test robot
2025-11-28 9:11 ` [PATCH v2 3/4] LongArch: KVM: Add irqfd set dintc msi Song Gao
2025-11-28 9:11 ` [PATCH v2 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu Song Gao
3 siblings, 1 reply; 8+ messages in thread
From: Song Gao @ 2025-11-28 9:11 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel
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 | 112 +++++++++++++++++++++++++
arch/loongarch/kvm/main.c | 5 ++
include/uapi/linux/kvm.h | 2 +
7 files changed, 148 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 0cecbd038bb3..7f6c4e7d241e 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
@@ -132,6 +133,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
@@ -242,6 +244,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..d30616ded1b1
--- /dev/null
+++ b/arch/loongarch/kvm/intc/dintc.c
@@ -0,0 +1,112 @@
+// 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)
+{
+ struct kvm *kvm;
+ struct loongarch_dintc *dintc;
+
+ 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 52f6000ab020..497a48235bf8 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1198,6 +1198,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 related [flat|nested] 8+ messages in thread* Re: [PATCH v2 2/4] LongArch: KVM: Add DINTC device support
2025-11-28 9:11 ` [PATCH v2 2/4] LongArch: KVM: Add DINTC device support Song Gao
@ 2025-12-01 12:18 ` kernel test robot
0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2025-12-01 12:18 UTC (permalink / raw)
To: Song Gao, maobibo, chenhuacai
Cc: llvm, oe-kbuild-all, kvm, loongarch, kernel, linux-kernel
Hi Song,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20251128]
[also build test WARNING on v6.18]
[cannot apply to kvm/queue kvm/next tip/irq/core mst-vhost/linux-next linus/master kvm/linux-next v6.18-rc7 v6.18-rc6 v6.18-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Song-Gao/LongArch-KVM-Add-some-maccros-for-AVEC/20251128-173944
base: next-20251128
patch link: https://lore.kernel.org/r/20251128091125.2720148-3-gaosong%40loongson.cn
patch subject: [PATCH v2 2/4] LongArch: KVM: Add DINTC device support
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20251201/202512011848.uhe7LBBn-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251201/202512011848.uhe7LBBn-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512011848.uhe7LBBn-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> arch/loongarch/kvm/intc/dintc.c:93:14: warning: unused variable 'kvm' [-Wunused-variable]
93 | struct kvm *kvm;
| ^~~
>> arch/loongarch/kvm/intc/dintc.c:94:26: warning: unused variable 'dintc' [-Wunused-variable]
94 | struct loongarch_dintc *dintc;
| ^~~~~
2 warnings generated.
vim +/kvm +93 arch/loongarch/kvm/intc/dintc.c
90
91 static void kvm_dintc_destroy(struct kvm_device *dev)
92 {
> 93 struct kvm *kvm;
> 94 struct loongarch_dintc *dintc;
95
96 if (!dev || !dev->kvm || !dev->kvm->arch.dintc)
97 return;
98
99 kfree(dev->kvm->arch.dintc);
100 }
101
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/4] LongArch: KVM: Add irqfd set dintc msi
2025-11-28 9:11 [PATCH v2 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
2025-11-28 9:11 ` [PATCH v2 1/4] LongArch: KVM: Add some maccros for AVEC Song Gao
2025-11-28 9:11 ` [PATCH v2 2/4] LongArch: KVM: Add DINTC device support Song Gao
@ 2025-11-28 9:11 ` Song Gao
2025-11-28 9:11 ` [PATCH v2 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu Song Gao
3 siblings, 0 replies; 8+ messages in thread
From: Song Gao @ 2025-11-28 9:11 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel
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 | 28 +++++++++++++++++++++++++-
3 files changed, 34 insertions(+), 1 deletion(-)
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 d30616ded1b1..ae0d61e2b8f0 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..fdcce472abb1 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,22 @@ 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);
+}
+
+
/*
* kvm_set_msi: inject the MSI corresponding to the
* MSI routing entry
@@ -26,10 +43,19 @@ 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)
{
+ u64 msg_addr;
+
if (!level)
return -1;
- pch_msi_set_irq(kvm, e->msi.data, level);
+ 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 if (msg_addr == 0) {
+ pch_msi_set_irq(kvm, e->msi.data, level);
+ }
return 0;
}
--
2.39.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 4/4] LongArch: KVM: Add dintc inject msi to the dest vcpu
2025-11-28 9:11 [PATCH v2 0/4] LongArch: KVM: Add AVEC support irqchip in kernel Song Gao
` (2 preceding siblings ...)
2025-11-28 9:11 ` [PATCH v2 3/4] LongArch: KVM: Add irqfd set dintc msi Song Gao
@ 2025-11-28 9:11 ` Song Gao
3 siblings, 0 replies; 8+ messages in thread
From: Song Gao @ 2025-11-28 9:11 UTC (permalink / raw)
To: maobibo, chenhuacai; +Cc: kvm, loongarch, kernel, linux-kernel
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 7f6c4e7d241e..298e4b7c3769 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -256,6 +256,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 1e7590fc1b47..84cf8b7c67dd 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 related [flat|nested] 8+ messages in thread