@samitouri / QOSamiQemu / commits / 60d010f66f

hw/block/pflash_cfi01: Restore ROMD mode after migration

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: qemu-stable@nongnu.org Signed-off-by: Bin Guo <guobin@linux.alibaba.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> [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: <20260803041808.58174-1-guobin@linux.alibaba.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Bin Guo committed Aug 3, 2026 at 12:18 UTC 60d010f66f2ad7c15388a605e6f1a2114dc60185
1 file changed +10
hw/block/pflash_cfi01.c
+10
@@ -1030,6 +1030,16 @@ static int pflash_post_load(void *opaque, int version_id)
1030 {
1031 PFlashCFI01 *pfl = opaque;
1032
1033 + /*
1034 + * ROMD mode is not in the VMState; derive it from the migrated
1035 + * cmd and wcycle. Only (wcycle == 0, cmd == 0x00) is read-array.
1036 + */
1037 + if (pfl->wcycle == 0 && pfl->cmd == 0x00) {
1038 + memory_region_rom_device_set_romd(&pfl->mem, true);
1039 + } else {
1040 + memory_region_rom_device_set_romd(&pfl->mem, false);
1041 + }
1042 +
1043 if (!pfl->ro) {
1044 pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
1045 pfl);