Skip to content

Commit 3844a46

Browse files
committed
vdpa: fix RX failure after device reset by always using base 0
After a vDPA device reset, activate_vdpa() read avail_idx from guest memory to pass as the vring base via VHOST_SET_VRING_BASE. However, the guest memory still contained the stale avail_idx from the previous session. For a 256-entry ring, this meant base=256, causing the hardware to believe the entire RX ring was consumed with no available buffers — RX silently stopped while TX continued to work. QEMU handles this correctly by tracking last_avail_idx internally (reset to 0 in virtio_reset()) and passing that value, rather than reading from guest memory. Fix by always passing base=0 to set_vring_base(). After a device reset, both the guest driver and the vhost backend restart their rings from index 0. For live migration, the correct base should come from VHOST_GET_VRING_BASE (saved before the migration), not guest memory. Tested with mlx5_vdpa (ConnectX-6 Dx) + Windows Server 2025 (netkvm). Before: RX=0 after 3rd driver activation. After: full connectivity. Fixes: cloud-hypervisor#7529 Signed-off-by: Max Makarov <maxpain@linux.com>
1 parent 676c0d3 commit 3844a46

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

virtio-devices/src/vdpa.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,16 +266,15 @@ impl Vdpa {
266266
.unwrap()
267267
.set_vring_addr(*queue_index, &config_data)
268268
.map_err(Error::SetVringAddr)?;
269+
// Always start from base 0. After device reset the guest
270+
// driver restarts its rings from 0, but the old avail_idx
271+
// value may still be present in guest memory (e.g. 256 for
272+
// a 256-entry ring), which makes the hardware think the
273+
// ring is full and no RX buffers are available.
269274
self.vhost
270275
.as_ref()
271276
.unwrap()
272-
.set_vring_base(
273-
*queue_index,
274-
queue
275-
.avail_idx(mem, Ordering::Acquire)
276-
.map_err(Error::GetAvailableIndex)?
277-
.0,
278-
)
277+
.set_vring_base(*queue_index, 0)
279278
.map_err(Error::SetVringBase)?;
280279

281280
if let Some(eventfd) =

0 commit comments

Comments
 (0)