- fix compile error on loongarch
- hw/loongarch: fix cpu hotplug reset
- hw/loongarch/boot: Use warn_report when no kernel filename
- hw/loongarch: clean code
- hw/loongarch: Add KVM pch msi device support
- hw/loongarch: Add KVM pch pic device support
- hw/loongarch: Add KVM extioi device support
- hw/loongarch: Add KVM IPI device support
- hw/loongarch/virt: Update the ACPI table for hotplug cpu
- hw/loongarch/virt: Add basic CPU plug support
- hw/loongarch/virt: Add CPU topology support
- accel/kvm/kvm-all: Fixes the missing break in vCPU unpark logic
- gdbstub: Add helper function to unregister GDB register space
- physmem: Add helper function to destroy CPU AddressSpace
- hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
- hw/acpi: Update ACPI GED framework to support vCPU Hotplug
- hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
- accel/kvm: Extract common KVM vCPU {creation,parking} code
- target/loongarch: Add steal time support on migration
- linux-headers: loongarch: Add kvm_para.h and unistd_64.h
- target/loongarch/kvm: Implement LoongArch PMU extension
- target/loongarch: Implement lbt registers save/restore function
- target/loongarch: Add loongson binary translation feature
- sync loongarch linux-headers
- target/loongarch: Avoid bits shift exceeding width of bool type
- target/loongarch: Use explicit little-endian LD/ST API
- target/loongarch: fix -Werror=maybe-uninitialized false-positive
- target/loongarch: Support QMP dump-guest-memory
- target/loongarch/kvm: Add vCPU reset function
- target/loongarch: Add compatible support about VM reboot
- target/loongarch: Fix cpu_reset set wrong CSR_CRMD
- target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
- target/loongarch: Remove avail_64 in trans_srai_w() and simplify it
- target/loongarch/kvm: Add software breakpoint support
- target/loongarch: Add loongarch vector property unconditionally
- target/loongarch/kvm: Fix VM recovery from disk failures
- target/loongarch: Put cpucfg operation before CSR register
- target/loongarch: Add TCG macro in structure CPUArchState
- hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location
- hw/loongarch/virt: Add FDT table support with acpi ged pm register
- hw/loongarch/virt: Add description for virt machine type
- hw/loongarch: Add acpi SPCR table support
- hw/loongarch: virt: pass random seed to fdt
- hw/loongarch: virt: support up to 4 serial ports
- hw/loongarch: Remove default enable with VIRTIO_VGA device
- hw/loongarch: Fix length for lowram in ACPI SRAT
- hw/loongarch/virt: Remove unused assignment
- hw/loongarch: Change the tpm support by default
- hw/loongarch/boot.c: fix out-of-bound reading
- hw/loongarch/virt: Use MemTxAttrs interface for misc ops
- tests/libqos: Add loongarch virt machine node
- hw/loongarch: Remove minimum and default memory size
- hw/loongarch: Refine system dram memory region
- hw/loongarch: Refine fwcfg memory map
- hw/loongarch: Refine fadt memory table for numa memory
- hw/loongarch: Refine acpi srat table for numa memory
- hw/loongarch: Add VM mode in IOCSR feature register in kvm mode
- hw/loongarch: Refine default numa id calculation
- hw/loongarch: Rename LoongArchMachineState with LoongArchVirtMachineState
- hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE
- hw/loongarch: move memory map to boot.c
- loongarch: switch boards to "default y"
- hw/loongarch: Add cells missing from rtc node
- hw/loongarch: Add cells missing from uart node
- hw/loongarch: fdt remove unused irqchip node
- hw/loongarch: fdt adds pcie irq_map node
- hw/loongarch: fdt adds pch_msi Controller
- hw/loongarch: fdt adds pch_pic Controller
- hw/loongarch: fdt adds Extend I/O Interrupt Controller
- hw/loongarch: fdt adds cpu interrupt controller node
- hw/loongarch: Init efi_fdt table
- hw/loongarch: Init efi_initrd table
- hw/loongarch: Init efi_boot_memmap table
- hw/loongarch: Init efi_system_table
- hw/loongarch: Add init_cmdline
- hw/loongarch: Add slave cpu boot_code
- hw/loongarch: Add load initrd
- hw/loongarch: Move boot functions to boot.c
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
(cherry picked from commit 04ca9e6c8ff19630116722240ae0136cea831c5c)
401 lines
13 KiB
Diff
401 lines
13 KiB
Diff
From 24e4e6742bdc8d804760e84f4e4bde5460e1e024 Mon Sep 17 00:00:00 2001
|
|
From: gaosong <gaosong@loongson.cn>
|
|
Date: Sun, 8 Sep 2024 09:29:00 +0800
|
|
Subject: [PATCH 72/78] hw/loongarch: Add KVM IPI device support
|
|
|
|
Added ipi interrupt controller for kvm emulation.
|
|
The main process is to send the command word for
|
|
creating an ipi device to the kernel.
|
|
When the VM is saved, the ioctl obtains the ipi
|
|
interrupt controller data in the kernel and saves it.
|
|
When the VM is recovered, the saved data is sent to the kernel.
|
|
|
|
Signed-off-by: gaosong <gaosong@loongson.cn>
|
|
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
|
---
|
|
hw/intc/Kconfig | 3 +
|
|
hw/intc/loongarch_ipi_kvm.c | 207 ++++++++++++++++++++++++++++++++
|
|
hw/intc/meson.build | 1 +
|
|
hw/loongarch/Kconfig | 1 +
|
|
hw/loongarch/virt.c | 35 ++++--
|
|
include/hw/intc/loongarch_ipi.h | 23 ++++
|
|
linux-headers/linux/kvm.h | 2 +
|
|
target/loongarch/kvm/kvm.c | 4 +
|
|
8 files changed, 263 insertions(+), 13 deletions(-)
|
|
create mode 100644 hw/intc/loongarch_ipi_kvm.c
|
|
|
|
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
|
|
index 97d550b06b..cbba74c22e 100644
|
|
--- a/hw/intc/Kconfig
|
|
+++ b/hw/intc/Kconfig
|
|
@@ -93,6 +93,9 @@ config NIOS2_VIC
|
|
config LOONGARCH_IPI
|
|
bool
|
|
|
|
+config LOONGARCH_IPI_KVM
|
|
+ bool
|
|
+
|
|
config LOONGARCH_PCH_PIC
|
|
bool
|
|
select UNIMP
|
|
diff --git a/hw/intc/loongarch_ipi_kvm.c b/hw/intc/loongarch_ipi_kvm.c
|
|
new file mode 100644
|
|
index 0000000000..fd308eb0c0
|
|
--- /dev/null
|
|
+++ b/hw/intc/loongarch_ipi_kvm.c
|
|
@@ -0,0 +1,207 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
+/*
|
|
+ * LoongArch kvm ipi interrupt support
|
|
+ *
|
|
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
|
|
+ */
|
|
+
|
|
+#include "qemu/osdep.h"
|
|
+#include "hw/qdev-properties.h"
|
|
+#include "qemu/typedefs.h"
|
|
+#include "hw/intc/loongarch_ipi.h"
|
|
+#include "hw/sysbus.h"
|
|
+#include "linux/kvm.h"
|
|
+#include "migration/vmstate.h"
|
|
+#include "qapi/error.h"
|
|
+#include "sysemu/kvm.h"
|
|
+
|
|
+#define IPI_DEV_FD_UNDEF -1
|
|
+
|
|
+static void kvm_ipi_access_regs(int fd, uint64_t addr,
|
|
+ uint32_t *val, int is_write)
|
|
+{
|
|
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_IPI_GRP_REGS,
|
|
+ addr, val, is_write, &error_abort);
|
|
+}
|
|
+
|
|
+static int kvm_loongarch_ipi_pre_save(void *opaque)
|
|
+{
|
|
+ KVMLoongArchIPI *ipi = (KVMLoongArchIPI *)opaque;
|
|
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(ipi);
|
|
+ IPICore *cpu;
|
|
+ uint64_t attr;
|
|
+ int cpu_id = 0;
|
|
+ int fd = ipi_class->dev_fd;
|
|
+
|
|
+ for (cpu_id = 0; cpu_id < ipi->num_cpu; cpu_id++) {
|
|
+ cpu = &ipi->cpu[cpu_id];
|
|
+ attr = (cpu_id << 16) | CORE_STATUS_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->status, false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_EN_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->en, false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_SET_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->set, false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_CLEAR_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->clear, false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_20;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[0], false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_28;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[2], false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_30;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[4], false);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_38;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[6], false);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int kvm_loongarch_ipi_post_load(void *opaque, int version_id)
|
|
+{
|
|
+ KVMLoongArchIPI *ipi = (KVMLoongArchIPI *)opaque;
|
|
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(ipi);
|
|
+ IPICore *cpu;
|
|
+ uint64_t attr;
|
|
+ int cpu_id = 0;
|
|
+ int fd = ipi_class->dev_fd;
|
|
+
|
|
+ for (cpu_id = 0; cpu_id < ipi->num_cpu; cpu_id++) {
|
|
+ cpu = &ipi->cpu[cpu_id];
|
|
+ attr = (cpu_id << 16) | CORE_STATUS_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->status, true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_EN_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->en, true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_SET_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->set, true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_CLEAR_OFF;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->clear, true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_20;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[0], true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_28;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[2], true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_30;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[4], true);
|
|
+
|
|
+ attr = (cpu_id << 16) | CORE_BUF_38;
|
|
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[6], true);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void kvm_loongarch_ipi_realize(DeviceState *dev, Error **errp)
|
|
+{
|
|
+ KVMLoongArchIPI *ipi = KVM_LOONGARCH_IPI(dev);
|
|
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(dev);
|
|
+ struct kvm_create_device cd = {0};
|
|
+ Error *err = NULL;
|
|
+ int ret;
|
|
+
|
|
+ if (ipi->num_cpu == 0) {
|
|
+ error_setg(errp, "num-cpu must be at least 1");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ipi_class->parent_realize(dev, &err);
|
|
+ if (err) {
|
|
+ error_propagate(errp, err);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ipi->cpu = g_new0(IPICore, ipi->num_cpu);
|
|
+ if (ipi->cpu == NULL) {
|
|
+ error_setg(errp, "Memory allocation for ExtIOICore faile");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!ipi_class->is_created) {
|
|
+ cd.type = KVM_DEV_TYPE_LA_IPI;
|
|
+ ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
|
|
+ if (ret < 0) {
|
|
+ error_setg_errno(errp, errno, "Creating the KVM device failed");
|
|
+ return;
|
|
+ }
|
|
+ ipi_class->is_created = true;
|
|
+ ipi_class->dev_fd = cd.fd;
|
|
+ fprintf(stdout, "Create LoongArch IPI irqchip in KVM done!\n");
|
|
+ }
|
|
+
|
|
+ assert(ipi_class->dev_fd != IPI_DEV_FD_UNDEF);
|
|
+}
|
|
+
|
|
+static Property kvm_loongarch_ipi_properties[] = {
|
|
+ DEFINE_PROP_UINT32("num-cpu", KVMLoongArchIPI, num_cpu, 1),
|
|
+ DEFINE_PROP_END_OF_LIST()
|
|
+};
|
|
+
|
|
+static const VMStateDescription vmstate_kvm_ipi_core = {
|
|
+ .name = "kvm-ipi-single",
|
|
+ .version_id = 1,
|
|
+ .minimum_version_id = 1,
|
|
+ .fields = (VMStateField[]) {
|
|
+ VMSTATE_UINT32(status, IPICore),
|
|
+ VMSTATE_UINT32(en, IPICore),
|
|
+ VMSTATE_UINT32(set, IPICore),
|
|
+ VMSTATE_UINT32(clear, IPICore),
|
|
+ VMSTATE_UINT32_ARRAY(buf, IPICore, 8),
|
|
+ VMSTATE_END_OF_LIST()
|
|
+ }
|
|
+};
|
|
+
|
|
+static const VMStateDescription vmstate_kvm_loongarch_ipi = {
|
|
+ .name = TYPE_KVM_LOONGARCH_IPI,
|
|
+ .version_id = 1,
|
|
+ .minimum_version_id = 1,
|
|
+ .pre_save = kvm_loongarch_ipi_pre_save,
|
|
+ .post_load = kvm_loongarch_ipi_post_load,
|
|
+ .fields = (VMStateField[]) {
|
|
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, KVMLoongArchIPI, num_cpu,
|
|
+ vmstate_kvm_ipi_core, IPICore),
|
|
+
|
|
+ VMSTATE_END_OF_LIST()
|
|
+ }
|
|
+};
|
|
+
|
|
+static void kvm_loongarch_ipi_class_init(ObjectClass *oc, void *data)
|
|
+{
|
|
+ DeviceClass *dc = DEVICE_CLASS(oc);
|
|
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_CLASS(oc);
|
|
+
|
|
+ ipi_class->parent_realize = dc->realize;
|
|
+ dc->realize = kvm_loongarch_ipi_realize;
|
|
+
|
|
+ ipi_class->is_created = false;
|
|
+ ipi_class->dev_fd = IPI_DEV_FD_UNDEF;
|
|
+
|
|
+ device_class_set_props(dc, kvm_loongarch_ipi_properties);
|
|
+
|
|
+ dc->vmsd = &vmstate_kvm_loongarch_ipi;
|
|
+}
|
|
+
|
|
+static const TypeInfo kvm_loongarch_ipi_info = {
|
|
+ .name = TYPE_KVM_LOONGARCH_IPI,
|
|
+ .parent = TYPE_SYS_BUS_DEVICE,
|
|
+ .instance_size = sizeof(KVMLoongArchIPI),
|
|
+ .class_size = sizeof(KVMLoongArchIPIClass),
|
|
+ .class_init = kvm_loongarch_ipi_class_init,
|
|
+};
|
|
+
|
|
+static void kvm_loongarch_ipi_register_types(void)
|
|
+{
|
|
+ type_register_static(&kvm_loongarch_ipi_info);
|
|
+}
|
|
+
|
|
+type_init(kvm_loongarch_ipi_register_types)
|
|
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
|
|
index ed355941d1..9deeeb51bb 100644
|
|
--- a/hw/intc/meson.build
|
|
+++ b/hw/intc/meson.build
|
|
@@ -70,6 +70,7 @@ specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
|
|
specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
|
|
specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
|
|
specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
|
|
+specific_ss.add(when: 'CONFIG_LOONGARCH_IPI_KVM', if_true: files('loongarch_ipi_kvm.c'))
|
|
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.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'))
|
|
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
|
index b42a8573d4..1e761624c6 100644
|
|
--- a/hw/loongarch/Kconfig
|
|
+++ b/hw/loongarch/Kconfig
|
|
@@ -14,6 +14,7 @@ config LOONGARCH_VIRT
|
|
select LOONGARCH_PCH_PIC
|
|
select LOONGARCH_PCH_MSI
|
|
select LOONGARCH_EXTIOI
|
|
+ select LOONGARCH_IPI_KVM if KVM
|
|
select LS7A_RTC
|
|
select SMBIOS
|
|
select ACPI_CPU_HOTPLUG
|
|
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
|
index 6159fd9470..f065eb75f8 100644
|
|
--- a/hw/loongarch/virt.c
|
|
+++ b/hw/loongarch/virt.c
|
|
@@ -829,16 +829,28 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
|
* +--------+ +---------+ +---------+
|
|
*/
|
|
|
|
- /* Create IPI device */
|
|
- ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
|
- qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.max_cpus);
|
|
- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
|
-
|
|
- /* IPI iocsr memory region */
|
|
- memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
|
|
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
|
|
- memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
|
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
|
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
|
+ ipi = qdev_new(TYPE_KVM_LOONGARCH_IPI);
|
|
+ qdev_prop_set_int32(ipi, "num-cpu", ms->smp.max_cpus);
|
|
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
|
+ } else {
|
|
+ ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
|
+ qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.max_cpus);
|
|
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
|
+
|
|
+ /* IPI iocsr memory region */
|
|
+ memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
|
|
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
|
|
+ memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
|
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
|
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
|
+ cpu_state = qemu_get_cpu(cpu);
|
|
+ cpudev = DEVICE(cpu_state);
|
|
+
|
|
+ /* connect ipi irq to cpu irq */
|
|
+ qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
|
|
+ }
|
|
+ }
|
|
|
|
/* Add cpu interrupt-controller */
|
|
fdt_add_cpuic_node(lvms, &cpuintc_phandle);
|
|
@@ -849,9 +861,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
|
lacpu = LOONGARCH_CPU(cpu_state);
|
|
env = &(lacpu->env);
|
|
env->address_space_iocsr = &lvms->as_iocsr;
|
|
-
|
|
- /* connect ipi irq to cpu irq */
|
|
- qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
|
|
env->ipistate = ipi;
|
|
}
|
|
|
|
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
|
|
index 1c1e834849..601b4f18a7 100644
|
|
--- a/include/hw/intc/loongarch_ipi.h
|
|
+++ b/include/hw/intc/loongarch_ipi.h
|
|
@@ -32,6 +32,7 @@
|
|
|
|
#define TYPE_LOONGARCH_IPI "loongarch_ipi"
|
|
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
|
|
+#define TYPE_KVM_LOONGARCH_IPI "loongarch-ipi-kvm"
|
|
|
|
typedef struct IPICore {
|
|
uint32_t status;
|
|
@@ -51,4 +52,26 @@ struct LoongArchIPI {
|
|
IPICore *cpu;
|
|
};
|
|
|
|
+struct KVMLoongArchIPI {
|
|
+ SysBusDevice parent_obj;
|
|
+ uint32_t num_cpu;
|
|
+ IPICore *cpu;
|
|
+};
|
|
+typedef struct KVMLoongArchIPI KVMLoongArchIPI;
|
|
+DECLARE_INSTANCE_CHECKER(KVMLoongArchIPI, KVM_LOONGARCH_IPI,
|
|
+ TYPE_KVM_LOONGARCH_IPI)
|
|
+
|
|
+struct KVMLoongArchIPIClass {
|
|
+ SysBusDeviceClass parent_class;
|
|
+ DeviceRealize parent_realize;
|
|
+
|
|
+ bool is_created;
|
|
+ int dev_fd;
|
|
+
|
|
+};
|
|
+typedef struct KVMLoongArchIPIClass KVMLoongArchIPIClass;
|
|
+DECLARE_CLASS_CHECKERS(KVMLoongArchIPIClass, KVM_LOONGARCH_IPI,
|
|
+ TYPE_KVM_LOONGARCH_IPI)
|
|
+
|
|
+
|
|
#endif
|
|
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
|
index eb30402c2d..ea1f821a9f 100644
|
|
--- a/linux-headers/linux/kvm.h
|
|
+++ b/linux-headers/linux/kvm.h
|
|
@@ -1470,6 +1470,8 @@ enum kvm_device_type {
|
|
#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
|
|
KVM_DEV_TYPE_RISCV_AIA,
|
|
#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA
|
|
+ KVM_DEV_TYPE_LA_IPI,
|
|
+#define KVM_DEV_TYPE_LA_IPI KVM_DEV_TYPE_LA_IPI
|
|
KVM_DEV_TYPE_MAX,
|
|
};
|
|
|
|
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
|
index 550f14269e..ab1ea3d4fd 100644
|
|
--- a/target/loongarch/kvm/kvm.c
|
|
+++ b/target/loongarch/kvm/kvm.c
|
|
@@ -1066,6 +1066,10 @@ int kvm_arch_get_default_type(MachineState *ms)
|
|
int kvm_arch_init(MachineState *ms, KVMState *s)
|
|
{
|
|
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
|
|
+ if(!kvm_vm_check_attr(kvm_state, KVM_LOONGARCH_VM_HAVE_IRQCHIP, KVM_LOONGARCH_VM_HAVE_IRQCHIP)) {
|
|
+ s->kernel_irqchip_allowed = false;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
2.39.1
|
|
|