From d6f75f9e532a4a4b6bb4610049f4fa7f26160733 Mon Sep 17 00:00:00 2001 From: Xianglai Li 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 --- 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