qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V1 0/4] skip memory init during CPR
@ 2025-03-07 20:55 Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 1/4] migration: cpr_is_incoming Steve Sistare
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Steve Sistare @ 2025-03-07 20:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Fabiano Rosas, Steve Sistare

Fix bugs where the realize method re-initializes some memory regions during
CPR.  See the individual commit messages for details.

Steve Sistare (4):
  migration: cpr_is_incoming
  pflash: fix cpr
  hw/loader: fix roms during cpr
  hw/qxl: fix cpr

 hw/block/block.c        |  5 +++++
 hw/core/loader.c        |  5 ++++-
 hw/display/qxl.c        | 27 ++++++++++++++++++++++++---
 include/migration/cpr.h |  1 +
 migration/cpr.c         |  5 +++++
 5 files changed, 39 insertions(+), 4 deletions(-)

-- 
1.8.3.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH V1 1/4] migration: cpr_is_incoming
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
@ 2025-03-07 20:55 ` Steve Sistare
  2025-03-07 23:08   ` Peter Xu
  2025-03-07 20:55 ` [PATCH V1 2/4] pflash: fix cpr Steve Sistare
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Steve Sistare @ 2025-03-07 20:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Fabiano Rosas, Steve Sistare

Define the cpr_is_incoming helper, to be used in several cpr fix patches.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 include/migration/cpr.h | 1 +
 migration/cpr.c         | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/include/migration/cpr.h b/include/migration/cpr.h
index 3a6deb7..7561fc7 100644
--- a/include/migration/cpr.h
+++ b/include/migration/cpr.h
@@ -21,6 +21,7 @@ int cpr_find_fd(const char *name, int id);
 
 MigMode cpr_get_incoming_mode(void);
 void cpr_set_incoming_mode(MigMode mode);
+bool cpr_is_incoming(void);
 
 int cpr_state_save(MigrationChannel *channel, Error **errp);
 int cpr_state_load(MigrationChannel *channel, Error **errp);
diff --git a/migration/cpr.c b/migration/cpr.c
index 584b0b9..0e935ab 100644
--- a/migration/cpr.c
+++ b/migration/cpr.c
@@ -128,6 +128,11 @@ void cpr_set_incoming_mode(MigMode mode)
     incoming_mode = mode;
 }
 
+bool cpr_is_incoming(void)
+{
+    return incoming_mode != MIG_MODE_NONE;
+}
+
 int cpr_state_save(MigrationChannel *channel, Error **errp)
 {
     int ret;
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V1 2/4] pflash: fix cpr
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 1/4] migration: cpr_is_incoming Steve Sistare
@ 2025-03-07 20:55 ` Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 3/4] hw/loader: fix roms during cpr Steve Sistare
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Steve Sistare @ 2025-03-07 20:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Fabiano Rosas, Steve Sistare

During normal migration, new QEMU creates and initializes memory regions,
then loads the preserved contents of the region from vmstate.

During CPR, memory regions are preserved in place, then the realize
method initializes the regions contents, losing the old contents.  To
fix, skip the re-init during CPR.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 hw/block/block.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/block/block.c b/hw/block/block.c
index 1d405e0..2e10611 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -12,6 +12,7 @@
 #include "system/blockdev.h"
 #include "system/block-backend.h"
 #include "hw/block/block.h"
+#include "migration/cpr.h"
 #include "qapi/error.h"
 #include "qapi/qapi-types-block.h"
 
@@ -66,6 +67,10 @@ bool blk_check_size_and_read_all(BlockBackend *blk, DeviceState *dev,
     int ret;
     g_autofree char *dev_id = NULL;
 
+    if (cpr_is_incoming()) {
+        return true;
+    }
+
     blk_len = blk_getlength(blk);
     if (blk_len < 0) {
         error_setg_errno(errp, -blk_len,
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V1 3/4] hw/loader: fix roms during cpr
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 1/4] migration: cpr_is_incoming Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 2/4] pflash: fix cpr Steve Sistare
@ 2025-03-07 20:55 ` Steve Sistare
  2025-03-07 20:55 ` [PATCH V1 4/4] hw/qxl: fix cpr Steve Sistare
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Steve Sistare @ 2025-03-07 20:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Fabiano Rosas, Steve Sistare

During normal migration, new QEMU creates and initializes memory regions,
then loads the preserved contents of the region from vmstate.

During CPR, memory regions are preserved in place, then the realize
method initializes the regions contents, losing the old contents.  To
fix, skip the re-init during CPR.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 hw/core/loader.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index fd25c5e..3c3a9a0 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -51,6 +51,7 @@
 #include "trace.h"
 #include "hw/hw.h"
 #include "disas/disas.h"
+#include "migration/cpr.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
 #include "system/reset.h"
@@ -1029,7 +1030,9 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro)
     vmstate_register_ram_global(rom->mr);
 
     data = memory_region_get_ram_ptr(rom->mr);
-    memcpy(data, rom->data, rom->datasize);
+    if (!cpr_is_incoming()) {
+        memcpy(data, rom->data, rom->datasize);
+    }
 
     return data;
 }
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V1 4/4] hw/qxl: fix cpr
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
                   ` (2 preceding siblings ...)
  2025-03-07 20:55 ` [PATCH V1 3/4] hw/loader: fix roms during cpr Steve Sistare
@ 2025-03-07 20:55 ` Steve Sistare
  2025-03-11 14:39 ` [PATCH V1 0/4] skip memory init during CPR Fabiano Rosas
  2025-03-13 17:24 ` Fabiano Rosas
  5 siblings, 0 replies; 8+ messages in thread
From: Steve Sistare @ 2025-03-07 20:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Fabiano Rosas, Steve Sistare

During normal migration, new QEMU creates and initializes memory regions,
then loads the preserved contents of the region from vmstate.

During CPR, memory regions are preserved in place, then the realize
method initializes the regions contents, losing the old contents.  To
fix, skip writes to the qxl memory regions during CPR load.

Reported-by: andrey.drobyshev@virtuozzo.com
Tested-by: andrey.drobyshev@virtuozzo.com
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 hw/display/qxl.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 2efdc77..da14da5 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -30,6 +30,7 @@
 #include "qemu/module.h"
 #include "hw/qdev-properties.h"
 #include "system/runstate.h"
+#include "migration/cpr.h"
 #include "migration/vmstate.h"
 #include "trace.h"
 
@@ -333,6 +334,10 @@ static void init_qxl_rom(PCIQXLDevice *d)
     uint32_t fb;
     int i, n;
 
+    if (cpr_is_incoming()) {
+        goto skip_init;
+    }
+
     memset(rom, 0, d->rom_size);
 
     rom->magic         = cpu_to_le32(QXL_ROM_MAGIC);
@@ -390,6 +395,7 @@ static void init_qxl_rom(PCIQXLDevice *d)
             sizeof(rom->client_monitors_config));
     }
 
+skip_init:
     d->shadow_rom = *rom;
     d->rom        = rom;
     d->modes      = modes;
@@ -403,6 +409,9 @@ static void init_qxl_ram(PCIQXLDevice *d)
 
     buf = d->vga.vram_ptr;
     d->ram = (QXLRam *)(buf + le32_to_cpu(d->shadow_rom.ram_header_offset));
+    if (cpr_is_incoming()) {
+        return;
+    }
     d->ram->magic       = cpu_to_le32(QXL_RAM_MAGIC);
     d->ram->int_pending = cpu_to_le32(0);
     d->ram->int_mask    = cpu_to_le32(0);
@@ -539,6 +548,10 @@ static void interface_set_compression_level(QXLInstance *sin, int level)
 
     trace_qxl_interface_set_compression_level(qxl->id, level);
     qxl->shadow_rom.compression_level = cpu_to_le32(level);
+    if (cpr_is_incoming()) {
+        assert(qxl->rom->compression_level == cpu_to_le32(level));
+        return;
+    }
     qxl->rom->compression_level = cpu_to_le32(level);
     qxl_rom_set_dirty(qxl);
 }
@@ -997,7 +1010,8 @@ static void interface_set_client_capabilities(QXLInstance *sin,
     }
 
     if (runstate_check(RUN_STATE_INMIGRATE) ||
-        runstate_check(RUN_STATE_POSTMIGRATE)) {
+        runstate_check(RUN_STATE_POSTMIGRATE) ||
+        cpr_is_incoming()) {
         return;
     }
 
@@ -1200,6 +1214,10 @@ static void qxl_reset_state(PCIQXLDevice *d)
 {
     QXLRom *rom = d->rom;
 
+    if (cpr_is_incoming()) {
+        return;
+    }
+
     qxl_check_state(d);
     d->shadow_rom.update_id = cpu_to_le32(0);
     *rom = d->shadow_rom;
@@ -1370,8 +1388,11 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     memslot.virt_start = virt_start + (guest_start - pci_start);
     memslot.virt_end   = virt_start + (guest_end   - pci_start);
     memslot.addr_delta = memslot.virt_start - delta;
-    memslot.generation = d->rom->slot_generation = 0;
-    qxl_rom_set_dirty(d);
+    if (!cpr_is_incoming()) {
+        d->rom->slot_generation = 0;
+        qxl_rom_set_dirty(d);
+    }
+    memslot.generation = d->rom->slot_generation;
 
     qemu_spice_add_memslot(&d->ssd, &memslot, async);
     d->guest_slots[slot_id].mr = mr;
-- 
1.8.3.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH V1 1/4] migration: cpr_is_incoming
  2025-03-07 20:55 ` [PATCH V1 1/4] migration: cpr_is_incoming Steve Sistare
@ 2025-03-07 23:08   ` Peter Xu
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Xu @ 2025-03-07 23:08 UTC (permalink / raw)
  To: Steve Sistare
  Cc: qemu-devel, Philippe Mathieu-Daude, Richard Henderson,
	Gerd Hoffmann, Kevin Wolf, Hanna Reitz, Fabiano Rosas

On Fri, Mar 07, 2025 at 12:55:51PM -0800, Steve Sistare wrote:
> Define the cpr_is_incoming helper, to be used in several cpr fix patches.
> 
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>

Reviewed-by: Peter Xu <peterx@redhat.com>

-- 
Peter Xu



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH V1 0/4] skip memory init during CPR
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
                   ` (3 preceding siblings ...)
  2025-03-07 20:55 ` [PATCH V1 4/4] hw/qxl: fix cpr Steve Sistare
@ 2025-03-11 14:39 ` Fabiano Rosas
  2025-03-13 17:24 ` Fabiano Rosas
  5 siblings, 0 replies; 8+ messages in thread
From: Fabiano Rosas @ 2025-03-11 14:39 UTC (permalink / raw)
  To: Steve Sistare, qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Steve Sistare

Steve Sistare <steven.sistare@oracle.com> writes:

> Fix bugs where the realize method re-initializes some memory regions during
> CPR.  See the individual commit messages for details.
>
> Steve Sistare (4):
>   migration: cpr_is_incoming
>   pflash: fix cpr
>   hw/loader: fix roms during cpr
>   hw/qxl: fix cpr
>
>  hw/block/block.c        |  5 +++++
>  hw/core/loader.c        |  5 ++++-
>  hw/display/qxl.c        | 27 ++++++++++++++++++++++++---
>  include/migration/cpr.h |  1 +
>  migration/cpr.c         |  5 +++++
>  5 files changed, 39 insertions(+), 4 deletions(-)

Series:

Reviewed-by: Fabiano Rosas <farosas@suse.de>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH V1 0/4] skip memory init during CPR
  2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
                   ` (4 preceding siblings ...)
  2025-03-11 14:39 ` [PATCH V1 0/4] skip memory init during CPR Fabiano Rosas
@ 2025-03-13 17:24 ` Fabiano Rosas
  5 siblings, 0 replies; 8+ messages in thread
From: Fabiano Rosas @ 2025-03-13 17:24 UTC (permalink / raw)
  To: Steve Sistare, qemu-devel
  Cc: Philippe Mathieu-Daude, Richard Henderson, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Peter Xu, Steve Sistare

Steve Sistare <steven.sistare@oracle.com> writes:

> Fix bugs where the realize method re-initializes some memory regions during
> CPR.  See the individual commit messages for details.
>
> Steve Sistare (4):
>   migration: cpr_is_incoming
>   pflash: fix cpr
>   hw/loader: fix roms during cpr
>   hw/qxl: fix cpr
>
>  hw/block/block.c        |  5 +++++
>  hw/core/loader.c        |  5 ++++-
>  hw/display/qxl.c        | 27 ++++++++++++++++++++++++---
>  include/migration/cpr.h |  1 +
>  migration/cpr.c         |  5 +++++
>  5 files changed, 39 insertions(+), 4 deletions(-)

I'm queing this for the freeze to ensure people using CPR with qxl can
get a complete feature in 10.0. If anyone has concerns, please speak up.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-03-13 17:25 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-07 20:55 [PATCH V1 0/4] skip memory init during CPR Steve Sistare
2025-03-07 20:55 ` [PATCH V1 1/4] migration: cpr_is_incoming Steve Sistare
2025-03-07 23:08   ` Peter Xu
2025-03-07 20:55 ` [PATCH V1 2/4] pflash: fix cpr Steve Sistare
2025-03-07 20:55 ` [PATCH V1 3/4] hw/loader: fix roms during cpr Steve Sistare
2025-03-07 20:55 ` [PATCH V1 4/4] hw/qxl: fix cpr Steve Sistare
2025-03-11 14:39 ` [PATCH V1 0/4] skip memory init during CPR Fabiano Rosas
2025-03-13 17:24 ` Fabiano Rosas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).