From 7a3e6caca4599390e318894ef7e4a13ced8189a8 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 8 Jan 2020 11:55:30 +0100 Subject: [PATCH] vm-virtio: Simplify virtio-console input processing The existing code was a bit too complex and it was introducing a bug when trying to paste long lines directly to the console. By simplifying the code, and by doing proper usage of the drain() function, the bug is fixed by this commit. Here is the similar output one could have gotten from time to time, when pasting important amounts of bytes: ERROR:vm-virtio/src/console.rs:104 -- Failed to write slice: InvalidGuestAddress(GuestAddress(1040617472)) Signed-off-by: Sebastien Boeuf --- vm-virtio/src/console.rs | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/vm-virtio/src/console.rs b/vm-virtio/src/console.rs index 994357044..b27e73e5e 100755 --- a/vm-virtio/src/console.rs +++ b/vm-virtio/src/console.rs @@ -79,37 +79,27 @@ impl ConsoleEpollHandler { */ fn process_input_queue(&mut self) -> bool { let mut in_buffer = self.in_buffer.lock().unwrap(); - let count = in_buffer.len(); let recv_queue = &mut self.queues[0]; //receiveq let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize]; let mut used_count = 0; - let mut write_count = 0; + + if in_buffer.is_empty() { + return false; + } let mem = self.mem.load(); for avail_desc in recv_queue.iter(&mem) { - let len; - - let limit = cmp::min(write_count + avail_desc.len as u32, count as u32); - let source_slice = in_buffer - .drain(write_count as usize..limit as usize) - .collect::>(); - let write_result = mem.write_slice(&source_slice[..], avail_desc.addr); - - match write_result { - Ok(_) => { - len = limit - write_count; //avail_desc.len; - write_count = limit; - } - Err(e) => { - error!("Failed to write slice: {:?}", e); - break; - } + let len = cmp::min(avail_desc.len as u32, in_buffer.len() as u32); + let source_slice = in_buffer.drain(..len as usize).collect::>(); + if let Err(e) = mem.write_slice(&source_slice[..], avail_desc.addr) { + error!("Failed to write slice: {:?}", e); + break; } used_desc_heads[used_count] = (avail_desc.index, len); used_count += 1; - if write_count >= count as u32 { + if in_buffer.is_empty() { break; } } @@ -117,6 +107,7 @@ impl ConsoleEpollHandler { for &(desc_index, len) in &used_desc_heads[..used_count] { recv_queue.add_used(&mem, desc_index, len); } + used_count > 0 }