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)®_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]>
