Function kvm_loongarch_extioi_realize() is added if irqchip-in-kernel property is enabled. It is to notify KVM kernel to create ExtIOI device in kernel mode.
Signed-off-by: Bibo Mao <maob...@loongson.cn> --- hw/intc/loongarch_extioi.c | 4 +++ hw/intc/loongarch_extioi_kvm.c | 46 ++++++++++++++++++++++++++++++ hw/intc/meson.build | 2 ++ include/hw/intc/loongarch_extioi.h | 3 ++ 4 files changed, 55 insertions(+) create mode 100644 hw/intc/loongarch_extioi_kvm.c diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index a737d49b12..854f54684b 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -376,6 +376,10 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp) } else { s->status |= BIT(EXTIOI_ENABLE); } + + if (kvm_enabled() && les->irqchip_in_kernel) { + kvm_loongarch_extioi_realize(dev, errp); + } } static void loongarch_extioi_unrealize(DeviceState *dev) diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c new file mode 100644 index 0000000000..833ec856ee --- /dev/null +++ b/hw/intc/loongarch_extioi_kvm.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch EXTIOI interrupt kvm support + * + * Copyright (C) 2025 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" +#include "hw/intc/loongarch_extioi.h" +#include "linux/kvm.h" +#include "qapi/error.h" +#include "system/kvm.h" + +void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp) +{ + LoongArchExtIOICommonState *lecs = LOONGARCH_EXTIOI_COMMON(dev); + LoongArchExtIOIState *les = LOONGARCH_EXTIOI(dev); + int ret; + + ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_LOONGARCH_EIOINTC, false); + if (ret < 0) { + fprintf(stderr, "create KVM_LOONGARCH_EIOINTC failed: %s\n", + strerror(-ret)); + abort(); + } + + les->dev_fd = ret; + ret = kvm_device_access(les->dev_fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, + KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU, + &lecs->num_cpu, true, NULL); + if (ret < 0) { + fprintf(stderr, "KVM_LOONGARCH_EXTIOI_INIT_NUM_CPU failed: %s\n", + strerror(-ret)); + abort(); + } + + ret = kvm_device_access(les->dev_fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, + KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE, + &lecs->features, true, NULL); + if (ret < 0) { + fprintf(stderr, "KVM_LOONGARCH_EXTIOI_INIT_FEATURE failed: %s\n", + strerror(-ret)); + abort(); + } +} diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 602da304b0..70e7548c52 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -74,3 +74,5 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c', 'loongarch_pic_common.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c')) +specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_EXTIOI'], + if_true: files('loongarch_extioi_kvm.c')) diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index c1d79d0a40..848a01f52c 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -16,6 +16,7 @@ OBJECT_DECLARE_TYPE(LoongArchExtIOIState, LoongArchExtIOIClass, LOONGARCH_EXTIOI struct LoongArchExtIOIState { LoongArchExtIOICommonState parent_obj; bool irqchip_in_kernel; + int dev_fd; }; struct LoongArchExtIOIClass { @@ -26,4 +27,6 @@ struct LoongArchExtIOIClass { ResettablePhases parent_phases; }; +void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp); + #endif /* LOONGARCH_EXTIOI_H */ -- 2.39.3