virtio-devices: Enable F_EVENT_IDX on control queue if negotiated

With the VIRTIO_F_EVENT_IDX handling now conducted inside the
virtio-queue crate it is necessary to activate the functionality on
every queue if it is negotiatated. Otherwise this leads to a failure of
the guest to signal to the host that there is something in the available
queue as the queue's internal state has not been configured correctly.

Fixes: #3829

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
(cherry picked from commit 223d0cf787)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-03-10 09:01:38 +00:00
parent 6275d4f87e
commit c6307865eb

View File

@ -563,10 +563,13 @@ impl VirtioDevice for Net {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
let queue_num = queues.len();
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && queue_num % 2 != 0 {
let cvq_queue = queues.remove(queue_num - 1);
let mut cvq_queue = queues.remove(queue_num - 1);
let cvq_queue_evt = queue_evts.remove(queue_num - 1);
cvq_queue.set_event_idx(event_idx);
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let mut ctrl_handler = NetCtrlEpollHandler {
kill_evt,
@ -599,8 +602,6 @@ impl VirtioDevice for Net {
self.ctrl_queue_epoll_thread = Some(epoll_threads.remove(0));
}
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
let mut epoll_threads = Vec::new();
let mut taps = self.taps.clone();
for i in 0..queues.len() / 2 {