@samitouri / QOSamiQemu / commits / d00567f7fb

hw/block/fdc: select the drive named by the READ ID command

Every other command handler begins by latching the drive from the command byte: SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); fdctrl_handle_readid() does not, so it works on whichever drive happened to be selected last. A guest that issues READ ID for a drive other than the one currently selected gets an answer about the wrong one. It has gone unnoticed because a driver normally writes the DOR to spin up the motor first, and that write selects the drive as a side effect. The controller does not require it, though, and the command carries the drive number for a reason. Reported-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Christian Quante <christian@quante.one> Message-ID: <20260714164031.60551-2-christian@quante.one> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Christian Quante committed Jul 14, 2026 at 18:40 UTC d00567f7fb2312c71bfc65a338c1b046f623df81
1 file changed +4 -1
hw/block/fdc.c
+4 -1
@@ -1936,7 +1936,10 @@ static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
1936
1937 static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
1938 {
1939 - FDrive *cur_drv = get_cur_drv(fdctrl);
1939 + FDrive *cur_drv;
1940 +
1941 + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
1942 + cur_drv = get_cur_drv(fdctrl);
1943
1944 cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
1945 timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +