mirror of https://gitee.com/openkylin/qemu.git
spapr/xive: Add proper rollback to kvmppc_xive_connect()
Make kvmppc_xive_disconnect() able to undo the changes of a partial execution of kvmppc_xive_connect() and use it to perform rollback. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Message-Id: <156198735673.293938.7313195993600841641.stgit@bahia> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
aaa450300e
commit
1c3d4a8f4b
|
@ -724,8 +724,7 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
|
|||
xsrc->esb_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_ESB_PAGE_OFFSET, esb_len,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memory_region_init_ram_device_ptr(&xsrc->esb_mmio_kvm, OBJECT(xsrc),
|
||||
|
@ -743,8 +742,7 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
|
|||
xive->tm_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_TIMA_PAGE_OFFSET, tima_len,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
memory_region_init_ram_device_ptr(&xive->tm_mmio_kvm, OBJECT(xive),
|
||||
"xive.tima", tima_len, xive->tm_mmap);
|
||||
|
@ -760,21 +758,24 @@ void kvmppc_xive_connect(SpaprXive *xive, Error **errp)
|
|||
|
||||
kvmppc_xive_cpu_connect(spapr_cpu_state(cpu)->tctx, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the KVM sources */
|
||||
kvmppc_xive_source_reset(xsrc, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
kvm_kernel_irqchip = true;
|
||||
kvm_msi_via_irqfd_allowed = true;
|
||||
kvm_gsi_direct_mapping = true;
|
||||
return;
|
||||
|
||||
fail:
|
||||
error_propagate(errp, local_err);
|
||||
kvmppc_xive_disconnect(xive, NULL);
|
||||
}
|
||||
|
||||
void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
||||
|
@ -796,23 +797,29 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
|||
xsrc = &xive->source;
|
||||
esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
|
||||
|
||||
memory_region_del_subregion(&xsrc->esb_mmio, &xsrc->esb_mmio_kvm);
|
||||
object_unparent(OBJECT(&xsrc->esb_mmio_kvm));
|
||||
munmap(xsrc->esb_mmap, esb_len);
|
||||
xsrc->esb_mmap = NULL;
|
||||
if (xsrc->esb_mmap) {
|
||||
memory_region_del_subregion(&xsrc->esb_mmio, &xsrc->esb_mmio_kvm);
|
||||
object_unparent(OBJECT(&xsrc->esb_mmio_kvm));
|
||||
munmap(xsrc->esb_mmap, esb_len);
|
||||
xsrc->esb_mmap = NULL;
|
||||
}
|
||||
|
||||
memory_region_del_subregion(&xive->tm_mmio, &xive->tm_mmio_kvm);
|
||||
object_unparent(OBJECT(&xive->tm_mmio_kvm));
|
||||
munmap(xive->tm_mmap, 4ull << TM_SHIFT);
|
||||
xive->tm_mmap = NULL;
|
||||
if (xive->tm_mmap) {
|
||||
memory_region_del_subregion(&xive->tm_mmio, &xive->tm_mmio_kvm);
|
||||
object_unparent(OBJECT(&xive->tm_mmio_kvm));
|
||||
munmap(xive->tm_mmap, 4ull << TM_SHIFT);
|
||||
xive->tm_mmap = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the KVM device fd is closed, the KVM device is destroyed
|
||||
* and removed from the list of devices of the VM. The VCPU
|
||||
* presenters are also detached from the device.
|
||||
*/
|
||||
close(xive->fd);
|
||||
xive->fd = -1;
|
||||
if (xive->fd != -1) {
|
||||
close(xive->fd);
|
||||
xive->fd = -1;
|
||||
}
|
||||
|
||||
kvm_kernel_irqchip = false;
|
||||
kvm_msi_via_irqfd_allowed = false;
|
||||
|
@ -822,5 +829,8 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
|||
kvm_cpu_disable_all();
|
||||
|
||||
/* VM Change state handler is not needed anymore */
|
||||
qemu_del_vm_change_state_handler(xive->change);
|
||||
if (xive->change) {
|
||||
qemu_del_vm_change_state_handler(xive->change);
|
||||
xive->change = NULL;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue