From: Kevin Wolf <[email protected]> ide_sector_read() as well as its callers neglect to call ide_set_retry() before starting I/O. If the I/O fails, this means that the retry information is stale. In particular, ide_handle_rw_error() has an assertion that s->bus->retry_unit == s->unit, which can fail if either there was no previous request or it came from another device on the bus. If the assertion weren't there, a wrong request would be retried after resuming the VM.
Fix this by adding a ide_set_retry() call to ide_sector_read(). This affects only reads because ide_transfer_start() does call ide_set_retry(). For writes, the data transfer comes first and the I/O is only started when the data has been read into s->io_buffer, so by that time, ide_set_retry() has been called. For reads, however, the I/O comes first and only then the data is transferred to the guest, so the call in ide_transfer_start() is too late. Buglink: https://redhat.atlassian.net/browse/RHEL-153537 Reported-by: Tingting Mao <[email protected]> Signed-off-by: Kevin Wolf <[email protected]> Message-ID: <[email protected]> Signed-off-by: Kevin Wolf <[email protected]> (cherry picked from commit 59c1d31136688415e5d682a87942292dbb3caaeb) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/ide/core.c b/hw/ide/core.c index b14983ec54..9ca480f72e 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -799,6 +799,7 @@ static void ide_sector_read(IDEState *s) s->error = 0; /* not needed by IDE spec, but needed by Windows */ sector_num = ide_get_sector(s); n = s->nsector; + ide_set_retry(s); if (n == 0) { ide_transfer_stop(s); -- 2.47.3
