Commit d00567f7fb for qemu.org
commit d00567f7fb2312c71bfc65a338c1b046f623df81
Author: Christian Quante <christian@quante.one>
Date: Tue Jul 14 18:40:30 2026 +0200
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>
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 2c1681b7d0..9b2409cfa4 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1936,7 +1936,10 @@ static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
{
- FDrive *cur_drv = get_cur_drv(fdctrl);
+ FDrive *cur_drv;
+
+ SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
+ cur_drv = get_cur_drv(fdctrl);
cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +