system/cpus: refuse memsave/pmemsave while guest RAM is being migrated
memsave and pmemsave read guest memory and write it to a file, with no guard at all. They run on the main thread with the BQL held, so on a postcopy destination touching a not-yet-received page deadlocks: the thread blocks on the userfault while the postcopy incoming path waits for the BQL to install that page. During precopy the read returns incomplete state instead. Refuse both while guest RAM is still being received, using the same migration_guest_ram_loading() check as dump-guest-memory. Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20260619101834.228432-4-den@openvz.org>
Denis V. Lunev committed
Jun 19, 2026 at 12:18 UTC
19e8b596263c2ee966a4e45f0ffbc9bb08b55409
1 file changed
+11
system/cpus.c
+11
@@ -43,6 +43,7 @@
43
#include "system/physmem.h"
44
#include "system/replay.h"
45
#include "system/runstate.h"
46
+#include "migration/misc.h"
47
#include "system/cpu-timers.h"
48
#include "system/whpx.h"
49
#include "hw/core/boards.h"
@@ -843,6 +844,11 @@ void qmp_memsave(uint64_t addr, uint64_t size, const char *filename,
844
uint8_t buf[1024];
845
uint64_t orig_addr = addr, orig_size = size;
846
847
+ if (migration_guest_ram_loading()) {
848
+ error_setg(errp, "Guest memory access not allowed during migration");
849
+ return;
850
+ }
851
+
852
if (!has_cpu) {
853
cpu_index = 0;
854
}
@@ -889,6 +895,11 @@ void qmp_pmemsave(uint64_t addr, uint64_t size, const char *filename,
895
uint64_t l;
896
uint8_t buf[1024];
897
898
+ if (migration_guest_ram_loading()) {
899
+ error_setg(errp, "Guest memory access not allowed during migration");
900
+ return;
901
+ }
902
+
903
f = fopen(filename, "wb");
904
if (!f) {
905
error_setg_file_open(errp, errno, filename);