From: Bibo Mao Date: Fri, 6 Jun 2025 06:30:30 +0000 (+0800) Subject: hw/loongarch/virt: Add reset support for kernel irqchip X-Git-Tag: v10.1.0-rc0~47^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c642ddf19b248bb668e40a8d15089b877e4057fa;p=thirdparty%2Fqemu.git hw/loongarch/virt: Add reset support for kernel irqchip When system reboot, interrupt controller is restored to initial state. However if interrupt controller extioi/ipi/pch_pic is emulated in kernel, it should notify kvm to do so. Here suspend and restore API is used for reset, set initial state in qemu user space and restore API is used to notify kvm to reload register state. Reviewed-by: Song Gao Signed-off-by: Bibo Mao Message-ID: <20250606063033.2557365-11-maobibo@loongson.cn> Signed-off-by: Song Gao --- diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 7be0685f369..8b8ac6b187b 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -391,6 +391,10 @@ static void loongarch_extioi_reset_hold(Object *obj, ResetType type) if (lec->parent_phases.hold) { lec->parent_phases.hold(obj, type); } + + if (kvm_irqchip_in_kernel()) { + kvm_extioi_put(obj, 0); + } } static int vmstate_extioi_pre_save(void *opaque) diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c index f4c618ca4cd..0133540c45d 100644 --- a/hw/intc/loongarch_extioi_kvm.c +++ b/hw/intc/loongarch_extioi_kvm.c @@ -94,6 +94,10 @@ int kvm_extioi_put(void *opaque, int version_id) LoongArchExtIOIState *les = LOONGARCH_EXTIOI(opaque); int fd = les->dev_fd; + if (fd == 0) { + return 0; + } + kvm_extioi_access_regs(opaque, true); kvm_extioi_access_sw_status(opaque, true); kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 0ea91ea0547..fc8005c9444 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -122,6 +122,10 @@ static void loongarch_ipi_reset_hold(Object *obj, ResetType type) core->clear = 0; memset(core->buf, 0, sizeof(core->buf)); } + + if (kvm_irqchip_in_kernel()) { + kvm_ipi_put(obj, 0); + } } static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev, diff --git a/hw/intc/loongarch_ipi_kvm.c b/hw/intc/loongarch_ipi_kvm.c index b615060d833..4cb3acc921f 100644 --- a/hw/intc/loongarch_ipi_kvm.c +++ b/hw/intc/loongarch_ipi_kvm.c @@ -25,6 +25,10 @@ static void kvm_ipi_access_regs(void *opaque, bool write) uint64_t attr; int cpu, fd = lis->dev_fd; + if (fd == 0) { + return; + } + for (cpu = 0; cpu < ipi->num_cpu; cpu++) { core = &ipi->cpu[cpu]; attr = (cpu << 16) | CORE_STATUS_OFF; diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c index 1adef980d48..c4b242dbf41 100644 --- a/hw/intc/loongarch_pch_pic.c +++ b/hw/intc/loongarch_pch_pic.c @@ -264,6 +264,10 @@ static void loongarch_pic_reset_hold(Object *obj, ResetType type) if (lpc->parent_phases.hold) { lpc->parent_phases.hold(obj, type); } + + if (kvm_irqchip_in_kernel()) { + kvm_pic_put(obj, 0); + } } static void loongarch_pic_realize(DeviceState *dev, Error **errp) diff --git a/hw/intc/loongarch_pic_kvm.c b/hw/intc/loongarch_pic_kvm.c index 3eef81a9bb8..dd504ec6a6f 100644 --- a/hw/intc/loongarch_pic_kvm.c +++ b/hw/intc/loongarch_pic_kvm.c @@ -26,6 +26,10 @@ static void kvm_pch_pic_access(void *opaque, bool write) int fd = lps->dev_fd; int addr, offset; + if (fd == 0) { + return; + } + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_MASK, &s->int_mask, write); kvm_pch_pic_access_reg(fd, PCH_PIC_HTMSI_EN, &s->htmsi_en, write); kvm_pch_pic_access_reg(fd, PCH_PIC_INT_EDGE, &s->intedge, write);