Am 27. Januar 2026 05:15:56 UTC schrieb Ani Sinha <[email protected]>:
>For confidential guests during the reset process, the old KVM VM file
>descriptor is closed and a new one is created. When a new file descriptor is
>created, a new openpic device needs to be created against this new KVM VM file
>descriptor as well. Additionally, existing memory region needs to be reattached
>to this new openpic device and proper CPU attributes set associating new file
>descriptor. This change makes this happen with the help of a callback handler
>that gets called when the KVM VM file descriptor changes as a part of the
>confidential guest reset process.
>
>Signed-off-by: Ani Sinha <[email protected]>
>---
> hw/intc/openpic_kvm.c | 112 +++++++++++++++++++++++++++++++++---------
> 1 file changed, 88 insertions(+), 24 deletions(-)
>
>diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
>index fbf0bdbe07..b099da20eb 100644
>--- a/hw/intc/openpic_kvm.c
>+++ b/hw/intc/openpic_kvm.c
>@@ -49,6 +49,7 @@ struct KVMOpenPICState {
>     uint32_t fd;
>     uint32_t model;
>     hwaddr mapped;
>+    NotifierWithReturn vmfd_change_notifier;
> };
> 
> static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level)
>@@ -114,6 +115,88 @@ static const MemoryRegionOps kvm_openpic_mem_ops = {
>     },
> };
> 
>+static int kvm_openpic_setup(KVMOpenPICState *opp, Error **errp)
>+{
>+    int kvm_openpic_model;
>+    struct kvm_create_device cd = {0};
>+    KVMState *s = kvm_state;
>+    int ret;
>+
>+    switch (opp->model) {
>+    case OPENPIC_MODEL_FSL_MPIC_20:
>+        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_20;
>+        break;
>+
>+    case OPENPIC_MODEL_FSL_MPIC_42:
>+        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_42;
>+        break;
>+
>+    default:
>+        error_setg(errp, "Unsupported OpenPIC model %" PRIu32, opp->model);
>+        return -1;
>+    }
>+
>+    cd.type = kvm_openpic_model;
>+    ret = kvm_vm_ioctl(s, KVM_CREATE_DEVICE, &cd);
>+    if (ret < 0) {
>+        error_setg(errp, "Can't create device %d: %s",
>+                   cd.type, strerror(errno));
>+        return -1;
>+    }
>+    opp->fd = cd.fd;
>+
>+    return 0;
>+}
>+
>+static int kvm_openpic_handle_vmfd_change(NotifierWithReturn *notifier,
>+                                          void *data, Error **errp)
>+{
>+    KVMOpenPICState *opp = container_of(notifier, KVMOpenPICState,
>+                                        vmfd_change_notifier);
>+    uint64_t reg_base;
>+    struct kvm_device_attr attr;
>+    CPUState *cs;
>+    int ret;
>+
>+    /* we are not interested in pre vmfd change notification */
>+    if (((VmfdChangeNotifier *)data)->pre) {
>+        return 0;
>+    }
>+
>+    /* close the old descriptor */
>+    close(opp->fd);
>+
>+    if (kvm_openpic_setup(opp, errp) < 0) {
>+        return -1;
>+    }
>+
>+    if (!opp->mapped) {
>+        return 0;
>+    }
>+
>+    reg_base = opp->mapped;
>+    attr.group = KVM_DEV_MPIC_GRP_MISC;
>+    attr.attr = KVM_DEV_MPIC_BASE_ADDR;
>+    attr.addr = (uint64_t)(unsigned long)&reg_base;
>+
>+    ret = ioctl(opp->fd, KVM_SET_DEVICE_ATTR, &attr);
>+    if (ret < 0) {
>+        error_setg(errp, "%s: %s %" PRIx64, __func__,
>+                   strerror(errno), reg_base);
>+        return -1;
>+    }
>+
>+    CPU_FOREACH(cs) {
>+        ret = kvm_vcpu_enable_cap(cs, KVM_CAP_IRQ_MPIC, 0, opp->fd,
>+                                   kvm_arch_vcpu_id(cs));
>+        if (ret < 0) {
>+            return ret;
>+        }
>+    }
>+
>+    return 0;
>+}
>+
> static void kvm_openpic_region_add(MemoryListener *listener,
>                                    MemoryRegionSection *section)
> {
>@@ -197,36 +280,14 @@ static void kvm_openpic_realize(DeviceState *dev, Error 
>**errp)
>     SysBusDevice *d = SYS_BUS_DEVICE(dev);
>     KVMOpenPICState *opp = KVM_OPENPIC(dev);
>     KVMState *s = kvm_state;
>-    int kvm_openpic_model;
>-    struct kvm_create_device cd = {0};
>-    int ret, i;
>+    int i;
> 
>     if (!kvm_check_extension(s, KVM_CAP_DEVICE_CTRL)) {
>         error_setg(errp, "Kernel is lacking Device Control API");
>         return;
>     }
> 
>-    switch (opp->model) {
>-    case OPENPIC_MODEL_FSL_MPIC_20:
>-        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_20;
>-        break;
>-
>-    case OPENPIC_MODEL_FSL_MPIC_42:
>-        kvm_openpic_model = KVM_DEV_TYPE_FSL_MPIC_42;
>-        break;
>-
>-    default:
>-        error_setg(errp, "Unsupported OpenPIC model %" PRIu32, opp->model);
>-        return;
>-    }
>-
>-    cd.type = kvm_openpic_model;
>-    ret = kvm_vm_ioctl(s, KVM_CREATE_DEVICE, &cd);
>-    if (ret < 0) {
>-        error_setg_errno(errp, errno, "Can't create device %d", cd.type);
>-        return;
>-    }
>-    opp->fd = cd.fd;
>+    kvm_openpic_setup(opp, errp);
> 
>     sysbus_init_mmio(d, &opp->mem);
>     qdev_init_gpio_in(dev, kvm_openpic_set_irq, OPENPIC_MAX_IRQ);
>@@ -235,6 +296,9 @@ static void kvm_openpic_realize(DeviceState *dev, Error 
>**errp)
>     opp->mem_listener.region_del = kvm_openpic_region_del;
>     opp->mem_listener.name = "openpic-kvm";
>     memory_listener_register(&opp->mem_listener, &address_space_memory);
>+    opp->vmfd_change_notifier.notify =
>+        kvm_openpic_handle_vmfd_change;
>+    kvm_vmfd_add_change_notifier(&opp->vmfd_change_notifier);
> 
>     /* indicate pic capabilities */
>     msi_nonbroken = true;

Code seems structurally comprehensible to me, so:

Reviewed-by: Bernhard Beschow <[email protected]>


Reply via email to