[PULL 19/56] hw/block/pflash_cfi01: Restore ROMD mode after migration

Philippe Mathieu-Daudé <[email protected]>
Newsgroups org.nongnu.qemu-devel
Message-ID <[email protected]>
From: Bin Guo <[email protected]>

pflash_post_load() did not restore the ROMD mode of the memory region.
Although cmd and wcycle are migrated, the destination retains the
default ROMD = true from realize.  When the source was in a non-array
mode (e.g. ID read, cmd = 0x90), reads on the destination bypass
pflash_read() via the ROM fast path and return raw storage bytes
instead of the command-specific response.

Derive ROMD from the migrated cmd/wcycle in pflash_post_load.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4042
Cc: [email protected]
Signed-off-by: Bin Guo <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
[PMD: Including review comments from
 https://lore.kernel.org/qemu-devel/CAFEAcA-P6RH7nJK0KQ1H8576ULFA7nocB0EkhhZf6Rw3g0WCag@mail.gmail.com/

 Confirming that this is correct is a bit tricky. It relies on:
  * when we set romd mode to true we also set wcycle = 0, cmd = 0
    (which we do, in reset and in the mode_read_array code)
  * when we set romd mode to false at the top of pflash_write(),
    all paths out of that function either go through the
    mode_read_array path, or else update pfl->cmd to something
    non-zero
  * nowhere outside pflash_write() udpates cmd or wcycle except
    for the "clear them to 0 and set romd mode" places

 This is almost but not quite true. In pflash_read(), the default
 case for the pfl->cmd switch sets wcycle = 0 cmd = 0 but doesn't
 change the romd state. Luckily the "this should never happen"
 comment is true -- there's no way to get a pfl->cmd that falls
 into the default (except for being deliberately fed a bogus value
 via inbound migration).
]
Message-ID: <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
 hw/block/pflash_cfi01.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 5b9ddb20b18..a13b91967ed 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -1030,6 +1030,16 @@ static int pflash_post_load(void *opaque, int version_id)
 {
     PFlashCFI01 *pfl = opaque;
 
+    /*
+     * ROMD mode is not in the VMState; derive it from the migrated
+     * cmd and wcycle.  Only (wcycle == 0, cmd == 0x00) is read-array.
+     */
+    if (pfl->wcycle == 0 && pfl->cmd == 0x00) {
+        memory_region_rom_device_set_romd(&pfl->mem, true);
+    } else {
+        memory_region_rom_device_set_romd(&pfl->mem, false);
+    }
+
     if (!pfl->ro) {
         pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
                                                         pfl);
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.