On 11/2/26 14:41, Abhisek Panda wrote:
> When a Windows guest puts an idle SATA drive into standby, it disables
> PCI bus mastering on the AHCI controller but fails to clear the port
> engine bits in the port command register. During post-migration
> handling, QEMU’s ahci_state_post_load function checks only these port
> engine bits to determine whether to start the engines and map the FIS
> receive buffer (PxFB) and Command List buffer (PxCLB). Because PCI bus
> mastering is disabled, DMA access to guest memory is blocked.
> Consequently, the memory mapping requests fail or incorrectly route
> through bounce buffers instead of direct guest memory, causing the
> destination QEMU process to abort the migration.
The fix is right, but on current master the abort is the less common
outcome. Since 637b0aa139 ("softmmu: Support concurrent bounce
buffers") each PCI device has its own 4k bounce budget, and a started
port takes 1024 bytes for the command list plus 256 for the FIS area.
While the started ports fit into that budget, post_load succeeds with
lst and res_fis pointing at private zero-filled bounce buffers, and the
migration completes. When the guest later stops the port, the unmap
writes those buffers back, i.e. zeros land on PxCLB/PxFB in guest
memory. Only when the budget is exceeded does post_load fail.I have checked both on q35 with a qtest: clear bus mastering, migrate, re-enable it, stop and restart port 0, issue IDENTIFY. With one disk master migrates fine and stopping the port zeroes the whole command list and FIS area. With three disks the destination fails with "bad FIS receive buffer address". With your patch both cases migrate, guest memory stays intact, and the restarted port works. Please describe both outcomes in the commit message, the silent memory corruption is the more important one. > Starting DMA/FIS engines when bus mastering is disabled might lead to > buffer mapping failures or improper bounce buffer allocations. Do not > start the engines in the aforementioned scenario. When the guest > re-enables bus mastering to access an idle drive, it should reset the > port engine, safely allocating the buffers and starting the engines. "it should" is what the patch relies on, as nothing restarts the engines on a bus master 0->1 transition. Andy's trace in the 2019 thread shows that Windows 10 does exactly that: it re-enables bus mastering, rewrites PxCLB/PxFB, clears and restarts PxCMD and issues a COMRESET. Windows 7 does not clear bus mastering at all. Please state this instead of "should". > Reported-by: andychiu <[email protected]> > Suggested-by: Michael S. Tsirkin <[email protected]> > Suggested-by: John Snow <[email protected]> > Link: https://lists.gnu.org/archive/html/qemu-devel/2019-09/msg01544.html > Signed-off-by: Abhisek Panda <[email protected]> With the commit message updated: Tested-by: Denis V. Lunev <[email protected]> Reviewed-by: Denis V. Lunev <[email protected]> Den P.S. John - will you take this?
