aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2025-06-06 14:30:30 +0800
committerSong Gao <gaosong@loongson.cn>2025-06-19 15:52:35 +0800
commitc642ddf19b248bb668e40a8d15089b877e4057fa (patch)
treee6df9db7b9b7f819cb83ba8512fe515fb03d1c62
parent0dd6798a1adda03dcfa6304437faa8e62a193d9c (diff)
downloadqemu-c642ddf19b248bb668e40a8d15089b877e4057fa.zip
qemu-c642ddf19b248bb668e40a8d15089b877e4057fa.tar.gz
qemu-c642ddf19b248bb668e40a8d15089b877e4057fa.tar.bz2
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 <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>
-rw-r--r--hw/intc/loongarch_extioi.c4
-rw-r--r--hw/intc/loongarch_extioi_kvm.c4
-rw-r--r--hw/intc/loongarch_ipi.c4
-rw-r--r--hw/intc/loongarch_ipi_kvm.c4
-rw-r--r--hw/intc/loongarch_pch_pic.c4
-rw-r--r--hw/intc/loongarch_pic_kvm.c4
6 files changed, 24 insertions, 0 deletions
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);