The changelog is too long. I wrote it incrementally while investigating the stale response-HVA case. English is not my first language, so some parts came out wrong. In particular, saying that the ioctl waits for pre-update commands may have suggested a full stop-new -> flush -> swap -> start-new sequence. That was not what I meant; sorry about the confusion. If the patch is otherwise acceptable, I will shorten the changelog in v2.
I wrote the patch myself. I used AI assistance only for notes and wording help; it did not author or submit the code. For this specific stale-response-HVA issue, I believe the patch is correct. The patch is a return barrier: vhost_dev_ioctl() publishes the new memory table, and vhost_scsi_flush() switches each vhost virtqueue to a new inflight generation, flushes the vhost work, and waits for the old generation's references. The completion path copies the response through cmd->tvc_resp_iovs before releasing the old-generation reference. There is no separate stop-new phase or full quiesce. A command can arrive after vhost_dev_ioctl() returns and before vhost_scsi_flush() switches that virtqueue's generation. It is assigned to the old generation and is included in the flush, but vhost_set_memory() has already updated that virtqueue's memory table, so its response iov uses the new table. It therefore does not introduce another stale-HVA case. This is why stopping new commands is not needed here. An old-generation command may complete while this ioctl is still running in the kernel, including while it is blocked in vhost_scsi_flush(); that is expected. The same userspace thread cannot perform the remap and follow-up TUR before this ioctl returns, because the thread is still blocked inside the ioctl. The owner must keep the old mappings valid until the ioctl returns. Remapping or dropping them from another userspace thread before then is outside the lifetime assumption of this transition barrier.
