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,
|
xsrc->esb_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_ESB_PAGE_OFFSET, esb_len,
|
||||||
&local_err);
|
&local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_init_ram_device_ptr(&xsrc->esb_mmio_kvm, OBJECT(xsrc),
|
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,
|
xive->tm_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_TIMA_PAGE_OFFSET, tima_len,
|
||||||
&local_err);
|
&local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
memory_region_init_ram_device_ptr(&xive->tm_mmio_kvm, OBJECT(xive),
|
memory_region_init_ram_device_ptr(&xive->tm_mmio_kvm, OBJECT(xive),
|
||||||
"xive.tima", tima_len, xive->tm_mmap);
|
"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);
|
kvmppc_xive_cpu_connect(spapr_cpu_state(cpu)->tctx, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the KVM sources */
|
/* Update the KVM sources */
|
||||||
kvmppc_xive_source_reset(xsrc, &local_err);
|
kvmppc_xive_source_reset(xsrc, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_kernel_irqchip = true;
|
kvm_kernel_irqchip = true;
|
||||||
kvm_msi_via_irqfd_allowed = true;
|
kvm_msi_via_irqfd_allowed = true;
|
||||||
kvm_gsi_direct_mapping = 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)
|
void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
||||||
@ -796,23 +797,29 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
|||||||
xsrc = &xive->source;
|
xsrc = &xive->source;
|
||||||
esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
|
esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
|
||||||
|
|
||||||
memory_region_del_subregion(&xsrc->esb_mmio, &xsrc->esb_mmio_kvm);
|
if (xsrc->esb_mmap) {
|
||||||
object_unparent(OBJECT(&xsrc->esb_mmio_kvm));
|
memory_region_del_subregion(&xsrc->esb_mmio, &xsrc->esb_mmio_kvm);
|
||||||
munmap(xsrc->esb_mmap, esb_len);
|
object_unparent(OBJECT(&xsrc->esb_mmio_kvm));
|
||||||
xsrc->esb_mmap = NULL;
|
munmap(xsrc->esb_mmap, esb_len);
|
||||||
|
xsrc->esb_mmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memory_region_del_subregion(&xive->tm_mmio, &xive->tm_mmio_kvm);
|
if (xive->tm_mmap) {
|
||||||
object_unparent(OBJECT(&xive->tm_mmio_kvm));
|
memory_region_del_subregion(&xive->tm_mmio, &xive->tm_mmio_kvm);
|
||||||
munmap(xive->tm_mmap, 4ull << TM_SHIFT);
|
object_unparent(OBJECT(&xive->tm_mmio_kvm));
|
||||||
xive->tm_mmap = NULL;
|
munmap(xive->tm_mmap, 4ull << TM_SHIFT);
|
||||||
|
xive->tm_mmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When the KVM device fd is closed, the KVM device is destroyed
|
* When the KVM device fd is closed, the KVM device is destroyed
|
||||||
* and removed from the list of devices of the VM. The VCPU
|
* and removed from the list of devices of the VM. The VCPU
|
||||||
* presenters are also detached from the device.
|
* presenters are also detached from the device.
|
||||||
*/
|
*/
|
||||||
close(xive->fd);
|
if (xive->fd != -1) {
|
||||||
xive->fd = -1;
|
close(xive->fd);
|
||||||
|
xive->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
kvm_kernel_irqchip = false;
|
kvm_kernel_irqchip = false;
|
||||||
kvm_msi_via_irqfd_allowed = false;
|
kvm_msi_via_irqfd_allowed = false;
|
||||||
@ -822,5 +829,8 @@ void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
|
|||||||
kvm_cpu_disable_all();
|
kvm_cpu_disable_all();
|
||||||
|
|
||||||
/* VM Change state handler is not needed anymore */
|
/* 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…
x
Reference in New Issue
Block a user