- target/i386: csv: Release CSV3 shared pages after unmapping DMA - target/i386: Add new CPU model ClearwaterForest - target/i386: add sha512, sm3, sm4 feature bits - docs: Add GNR, SRF and CWF CPU models - target/i386: Export BHI_NO bit to guests - target/i386: Introduce SierraForest-v2 model - vdpa/iommufd:Implement DMA mapping through the iommufd interface - vdpa/iommufd:Introduce vdpa-iommufd module - vdpa/iommufd:support associating iommufd backend for vDPA devices - Kconfig/iommufd/VDPA: Update IOMMUFD module configuration dependencies The vDPA module can also use IOMMUFD like the VFIO module. - backends/iommufd: Get rid of qemu_open_old() - backends/iommufd: Make iommufd_backend_*() return bool - backends/iommufd: Fix missing ERRP_GUARD() for error_prepend() - backends/iommufd: Remove mutex - backends/iommufd: Remove check on number of backend users - hw/intc: Add extioi ability of 256 vcpu interrupt routing - hw/rtc: Fixed loongson rtc emulation errors - hw/loongarch/boot: Adjust the loading position of the initrd - target/loongarch: Fix the cpu unplug resource leak - target/loongarch: fix vcpu reset command word issue - vdpa:Fix dirty page bitmap synchronization not done after suspend for vdpa devices Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit a5212066e7516ff2a316e1b2feaa75dd5ee4d17a)
205 lines
7.8 KiB
Diff
205 lines
7.8 KiB
Diff
From d6f75f9e532a4a4b6bb4610049f4fa7f26160733 Mon Sep 17 00:00:00 2001
|
|
From: Xianglai Li <lixianglai@loongson.cn>
|
|
Date: Thu, 20 Feb 2025 19:24:18 +0800
|
|
Subject: [PATCH] hw/intc: Add extioi ability of 256 vcpu interrupt routing
|
|
|
|
Add the feature field for the CPU-encoded interrupt
|
|
route to extioi and the corresponding mechanism for
|
|
backup recovery.
|
|
|
|
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
|
---
|
|
hw/intc/loongarch_extioi_kvm.c | 65 ++++++++++++++++++++++++++++--
|
|
hw/loongarch/virt.c | 2 +
|
|
include/hw/intc/loongarch_extioi.h | 4 ++
|
|
linux-headers/asm-loongarch/kvm.h | 10 +++++
|
|
4 files changed, 77 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c
|
|
index f5bbc33255..2e7c764b7c 100644
|
|
--- a/hw/intc/loongarch_extioi_kvm.c
|
|
+++ b/hw/intc/loongarch_extioi_kvm.c
|
|
@@ -18,8 +18,32 @@
|
|
static void kvm_extioi_access_regs(int fd, uint64_t addr,
|
|
void *val, int is_write)
|
|
{
|
|
- kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS,
|
|
- addr, val, is_write, &error_abort);
|
|
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS,
|
|
+ addr, val, is_write, &error_abort);
|
|
+}
|
|
+
|
|
+static void kvm_extioi_access_sw_status(int fd, uint64_t addr,
|
|
+ void *val, bool is_write)
|
|
+{
|
|
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS,
|
|
+ addr, val, is_write, &error_abort);
|
|
+}
|
|
+
|
|
+static void kvm_extioi_save_load_sw_status(void *opaque, bool is_write)
|
|
+{
|
|
+ KVMLoongArchExtIOI *s = (KVMLoongArchExtIOI *)opaque;
|
|
+ KVMLoongArchExtIOIClass *class = KVM_LOONGARCH_EXTIOI_GET_CLASS(s);
|
|
+ int fd = class->dev_fd;
|
|
+ int addr;
|
|
+
|
|
+ addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU;
|
|
+ kvm_extioi_access_sw_status(fd, addr, (void *)&s->num_cpu, is_write);
|
|
+
|
|
+ addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE;
|
|
+ kvm_extioi_access_sw_status(fd, addr, (void *)&s->features, is_write);
|
|
+
|
|
+ addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE;
|
|
+ kvm_extioi_access_sw_status(fd, addr, (void *)&s->status, is_write);
|
|
}
|
|
|
|
static int kvm_loongarch_extioi_pre_save(void *opaque)
|
|
@@ -41,6 +65,8 @@ static int kvm_loongarch_extioi_pre_save(void *opaque)
|
|
kvm_extioi_access_regs(fd, EXTIOI_COREISR_START,
|
|
(void *)s->coreisr, false);
|
|
|
|
+ kvm_extioi_save_load_sw_status(opaque, false);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -61,12 +87,19 @@ static int kvm_loongarch_extioi_post_load(void *opaque, int version_id)
|
|
(void *)s->sw_coremap, true);
|
|
kvm_extioi_access_regs(fd, EXTIOI_COREISR_START, (void *)s->coreisr, true);
|
|
|
|
+ kvm_extioi_save_load_sw_status(opaque, true);
|
|
+
|
|
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL,
|
|
+ KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED,
|
|
+ NULL, true, &error_abort);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
static void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
KVMLoongArchExtIOIClass *extioi_class = KVM_LOONGARCH_EXTIOI_GET_CLASS(dev);
|
|
+ KVMLoongArchExtIOI *s = KVM_LOONGARCH_EXTIOI(dev);
|
|
struct kvm_create_device cd = {0};
|
|
Error *err = NULL;
|
|
int ret,i;
|
|
@@ -77,6 +110,10 @@ static void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
|
return;
|
|
}
|
|
|
|
+ if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
|
|
+ s->features |= EXTIOI_VIRT_HAS_FEATURES;
|
|
+ }
|
|
+
|
|
if (!extioi_class->is_created) {
|
|
cd.type = KVM_DEV_TYPE_LA_EXTIOI;
|
|
ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
|
|
@@ -87,6 +124,15 @@ static void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
|
}
|
|
extioi_class->is_created = true;
|
|
extioi_class->dev_fd = cd.fd;
|
|
+
|
|
+ kvm_device_access(cd.fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL,
|
|
+ KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU,
|
|
+ &s->num_cpu, true, NULL);
|
|
+
|
|
+ kvm_device_access(cd.fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL,
|
|
+ KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE,
|
|
+ &s->features, true, NULL);
|
|
+
|
|
fprintf(stdout, "Create LoongArch extioi irqchip in KVM done!\n");
|
|
}
|
|
|
|
@@ -102,8 +148,8 @@ static void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
|
|
|
static const VMStateDescription vmstate_kvm_extioi_core = {
|
|
.name = "kvm-extioi-single",
|
|
- .version_id = 1,
|
|
- .minimum_version_id = 1,
|
|
+ .version_id = 2,
|
|
+ .minimum_version_id = 2,
|
|
.pre_save = kvm_loongarch_extioi_pre_save,
|
|
.post_load = kvm_loongarch_extioi_post_load,
|
|
.fields = (VMStateField[]) {
|
|
@@ -119,10 +165,20 @@ static const VMStateDescription vmstate_kvm_extioi_core = {
|
|
EXTIOI_IRQS_IPMAP_SIZE / 4),
|
|
VMSTATE_UINT32_ARRAY(coremap, KVMLoongArchExtIOI, EXTIOI_IRQS / 4),
|
|
VMSTATE_UINT8_ARRAY(sw_coremap, KVMLoongArchExtIOI, EXTIOI_IRQS),
|
|
+ VMSTATE_UINT32(num_cpu, KVMLoongArchExtIOI),
|
|
+ VMSTATE_UINT32(features, KVMLoongArchExtIOI),
|
|
+ VMSTATE_UINT32(status, KVMLoongArchExtIOI),
|
|
VMSTATE_END_OF_LIST()
|
|
}
|
|
};
|
|
|
|
+static Property extioi_properties[] = {
|
|
+ DEFINE_PROP_UINT32("num-cpu", KVMLoongArchExtIOI, num_cpu, 1),
|
|
+ DEFINE_PROP_BIT("has-virtualization-extension", KVMLoongArchExtIOI,
|
|
+ features, EXTIOI_HAS_VIRT_EXTENSION, 0),
|
|
+ DEFINE_PROP_END_OF_LIST(),
|
|
+};
|
|
+
|
|
static void kvm_loongarch_extioi_class_init(ObjectClass *oc, void *data)
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
|
@@ -131,6 +187,7 @@ static void kvm_loongarch_extioi_class_init(ObjectClass *oc, void *data)
|
|
extioi_class->parent_realize = dc->realize;
|
|
dc->realize = kvm_loongarch_extioi_realize;
|
|
extioi_class->is_created = false;
|
|
+ device_class_set_props(dc, extioi_properties);
|
|
dc->vmsd = &vmstate_kvm_extioi_core;
|
|
}
|
|
|
|
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
|
index ce026a4c3c..233297d78f 100644
|
|
--- a/hw/loongarch/virt.c
|
|
+++ b/hw/loongarch/virt.c
|
|
@@ -874,6 +874,8 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
|
/* Create EXTIOI device */
|
|
if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
|
extioi = qdev_new(TYPE_KVM_LOONGARCH_EXTIOI);
|
|
+ qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.max_cpus);
|
|
+ qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
|
|
} else {
|
|
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
|
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
|
|
index 9966cd98d3..92b38d5c38 100644
|
|
--- a/include/hw/intc/loongarch_extioi.h
|
|
+++ b/include/hw/intc/loongarch_extioi.h
|
|
@@ -94,6 +94,10 @@ struct LoongArchExtIOI {
|
|
|
|
struct KVMLoongArchExtIOI {
|
|
SysBusDevice parent_obj;
|
|
+ uint32_t num_cpu;
|
|
+ uint32_t features;
|
|
+ uint32_t status;
|
|
+
|
|
/* hardware state */
|
|
uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
|
|
uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
|
|
diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h
|
|
index 13c1280662..34abd65939 100644
|
|
--- a/linux-headers/asm-loongarch/kvm.h
|
|
+++ b/linux-headers/asm-loongarch/kvm.h
|
|
@@ -141,6 +141,16 @@ struct kvm_iocsr_entry {
|
|
|
|
#define KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS 0x40000003
|
|
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS 0x40000006
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU 0x0
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE 0x1
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE 0x2
|
|
+
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL 0x40000007
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU 0x0
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE 0x1
|
|
+#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED 0x3
|
|
+
|
|
#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000004
|
|
#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0
|
|
|
|
--
|
|
2.41.0.windows.1
|
|
|