From f700b10cfd8d02d807c90786469b39a59ec7b9e5 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 15 May 2026 01:29:54 +0200 Subject: [PATCH] vm-virtio: checked_descriptor: Add unit test for translation failure Introduce a FailingTranslator stub whose translate_gva always returns an error and verify CheckedDescriptorIter rejects the descriptor, with failed_addr returning the original descriptor address before translation. Signed-off-by: Anatol Belski --- vm-virtio/src/checked_descriptor.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/vm-virtio/src/checked_descriptor.rs b/vm-virtio/src/checked_descriptor.rs index 9a90e45b3..e5e419bd2 100644 --- a/vm-virtio/src/checked_descriptor.rs +++ b/vm-virtio/src/checked_descriptor.rs @@ -430,4 +430,32 @@ mod unit_tests { assert_eq!(desc.addr().0, gpa); assert_eq!(desc.len(), LEN); } + + /// AccessPlatform stub that always fails translation. + #[derive(Debug)] + struct FailingTranslator; + + impl AccessPlatform for FailingTranslator { + fn translate_gva(&self, _base: u64, _size: u64) -> std::io::Result { + Err(std::io::Error::other("translation failed")) + } + fn translate_gpa(&self, _base: u64, _size: u64) -> std::io::Result { + Err(std::io::Error::other("translation failed")) + } + } + + #[test] + fn rejects_descriptor_when_translation_fails() { + const MEM_SIZE: usize = 128 * 1024; + let gva = 0x4000u64; + let (_mem, mem_atomic, mut queue) = setup_vq(MEM_SIZE, gva, 256, 0); + let mem_guard = mem_atomic.memory(); + let mut chain = queue.pop_descriptor_chain(mem_guard).unwrap(); + let ap = FailingTranslator; + let mut it = chain.checked_iter(Some(&ap)); + let result = it.next().expect("must yield an item"); + // The error reports the original descriptor address, not a + // translated one. + assert_eq!(result.unwrap_err(), GuestAddress(gva)); + } }