]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
hw/loongarch/virt: Add reset support for kernel irqchip
authorBibo Mao <maobibo@loongson.cn>
Fri, 6 Jun 2025 06:30:30 +0000 (14:30 +0800)
committerSong Gao <gaosong@loongson.cn>
Thu, 19 Jun 2025 07:52:35 +0000 (15:52 +0800)
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 <gaosong@loongson.cn>
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250606063033.2557365-11-maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
hw/intc/loongarch_extioi.c
hw/intc/loongarch_extioi_kvm.c
hw/intc/loongarch_ipi.c
hw/intc/loongarch_ipi_kvm.c
hw/intc/loongarch_pch_pic.c
hw/intc/loongarch_pic_kvm.c

index 7be0685f36926a6f910877aa73410431a4bb190b..8b8ac6b187bc62f6a3018b90c0c45c27a8075e6f 100644 (file)
@@ -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)
index f4c618ca4cd1c0ad2e49ce4e807de5fb3b83c483..0133540c45ddfc261b1dd99ec981b1bbf71cdda7 100644 (file)
@@ -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,
index 0ea91ea054736162bb4baa1f7a7ddf29a98d2a8a..fc8005c9444076fb9805108db32e1382ea9405e1 100644 (file)
@@ -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,
index b615060d8337ab692283cbcf36a62c17bf19c383..4cb3acc921f8b261f08c62351428b31238b6060c 100644 (file)
@@ -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;
index 1adef980d489c09e7c47d65732a6a14553ab0984..c4b242dbf4169051c1c3b775c2cad44a9decb562 100644 (file)
@@ -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)
index 3eef81a9bb8c5adfa8f93c391731f4aac06f8b7d..dd504ec6a6faca09b6670836fca5feead3dc7df2 100644 (file)
@@ -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);