From c642ddf19b248bb668e40a8d15089b877e4057fa Mon Sep 17 00:00:00 2001 From: Bibo Mao Date: Fri, 6 Jun 2025 14:30:30 +0800 Subject: 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 --- hw/intc/loongarch_extioi.c | 4 ++++ hw/intc/loongarch_extioi_kvm.c | 4 ++++ hw/intc/loongarch_ipi.c | 4 ++++ hw/intc/loongarch_ipi_kvm.c | 4 ++++ hw/intc/loongarch_pch_pic.c | 4 ++++ hw/intc/loongarch_pic_kvm.c | 4 ++++ 6 files changed, 24 insertions(+) (limited to 'hw/intc') diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 7be0685..8b8ac6b 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 f4c618c..0133540 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 0ea91ea..fc8005c 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 b615060..4cb3acc 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 1adef98..c4b242d 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 3eef81a..dd504ec 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); -- cgit v1.1