Skip to content

Commit 7f00003

Browse files
committed
fix: only set MSI-X vector for valid queues
This is the equivalent to the fix in 741c29f but for guest writes. We need to make sure that `queue_select` points to a valid queue before setting the MSI-X vector otherwise we'll hit a panic when accessing the underlying `Vec`. Signed-off-by: Babis Chalios <[email protected]>
1 parent 9f6fc31 commit 7f00003

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/vmm/src/devices/virtio/transport/pci/common_config.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,18 @@ impl VirtioPciCommonConfig {
258258
0x10 => self.msix_config.store(value, Ordering::Release),
259259
0x16 => self.queue_select = value,
260260
0x18 => self.with_queue_mut(queues, |q| q.size = value),
261-
0x1a => self.msix_queues.lock().unwrap()[self.queue_select as usize] = value,
261+
0x1a => {
262+
// Make sure that `queue_select` points to a valid queue. If not, we won't do
263+
// anything here and subsequent reads at 0x1a will return `NO_VECTOR`.
264+
if let Some(msix_queue) = self
265+
.msix_queues
266+
.lock()
267+
.unwrap()
268+
.get_mut(self.queue_select as usize)
269+
{
270+
*msix_queue = value;
271+
}
272+
}
262273
0x1c => self.with_queue_mut(queues, |q| {
263274
q.ready = value == 1;
264275
}),
@@ -426,7 +437,17 @@ mod tests {
426437

427438
// Getting the MSI vector when `queue_select` points to an invalid queue should return
428439
// NO_VECTOR (0xffff)
429-
regs.read(0x1a, &mut read_back, dev);
440+
regs.read(0x1a, &mut read_back, dev.clone());
430441
assert_eq!(read_back, [0xff, 0xff]);
442+
443+
// Writing the MSI vector of an invalid `queue_select` does not have any effect.
444+
regs.write(0x1a, &[0x12, 0x13], dev.clone());
445+
assert_eq!(read_back, [0xff, 0xff]);
446+
// Valid `queue_select` though should setup the corresponding MSI-X queue.
447+
regs.write(0x16, &[0x1, 0x0], dev.clone());
448+
assert_eq!(regs.queue_select, 1);
449+
regs.write(0x1a, &[0x12, 0x13], dev.clone());
450+
regs.read(0x1a, &mut read_back, dev);
451+
assert_eq!(LittleEndian::read_u16(&read_back[..2]), 0x1312);
431452
}
432453
}

0 commit comments

Comments
 (0)