migration/ram: Fix error handling in ram_write_tracking_start()

If something goes wrong during uffd_change_protection(), we would miss
to unregister uffd-wp and not release our reference. Fix it by
performing the uffd_change_protection(true) last.

Note that a uffd_change_protection(false) on the recovery path without a
prior uffd_change_protection(false) is fine.

Fixes: 278e2f551a09 ("migration: support UFFD write fault processing in ram_save_iterate()")
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 72ef3a370836aa07261ad7aaeea27ed5cbcee342)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
David Hildenbrand 2023-01-05 13:45:25 +01:00 committed by Michael Tokarev
parent f759e33000
commit ee2ec0ac52

View File

@ -1885,13 +1885,14 @@ int ram_write_tracking_start(void)
block->max_length, UFFDIO_REGISTER_MODE_WP, NULL)) {
goto fail;
}
block->flags |= RAM_UF_WRITEPROTECT;
memory_region_ref(block->mr);
/* Apply UFFD write protection to the block memory range */
if (uffd_change_protection(rs->uffdio_fd, block->host,
block->max_length, true, false)) {
goto fail;
}
block->flags |= RAM_UF_WRITEPROTECT;
memory_region_ref(block->mr);
trace_ram_write_tracking_ramblock_start(block->idstr, block->page_size,
block->host, block->max_length);