From a465ec13463646f5da2f7a0a5842f67f73570498 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sat, 6 Jul 2024 22:36:13 +0800 Subject: [PATCH] Work around a QEMU bug in virtio console pasting --- .../comps/virtio/src/device/console/device.rs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/kernel/comps/virtio/src/device/console/device.rs b/kernel/comps/virtio/src/device/console/device.rs index 6d4babc29..6906929ad 100644 --- a/kernel/comps/virtio/src/device/console/device.rs +++ b/kernel/comps/virtio/src/device/console/device.rs @@ -106,14 +106,7 @@ impl ConsoleDevice { callbacks: RwLock::new(Vec::new()), }); - let mut receive_queue = device.receive_queue.lock_irq_disabled(); - receive_queue - .add_dma_buf(&[], &[&device.receive_buffer]) - .unwrap(); - if receive_queue.should_notify() { - receive_queue.notify(); - } - drop(receive_queue); + device.activate_receive_buffer(&mut device.receive_queue.lock_irq_disabled()); // Register irq callbacks let mut transport = device.transport.lock_irq_disabled(); @@ -149,9 +142,22 @@ impl ConsoleDevice { let reader = self.receive_buffer.reader().unwrap().limit(len as usize); callback(reader); } + + self.activate_receive_buffer(&mut receive_queue); + } + + fn activate_receive_buffer(&self, receive_queue: &mut VirtQueue) { receive_queue - .add_dma_buf(&[], &[&self.receive_buffer]) + // We limit the buffer length to one to work around a QEMU bug that causes incorrect + // results when pasting more than 32 bytes into the virtio console. This has no + // performance penalty, since QEMU always gets one byte at a time, regardless of + // whether we have this limit or not. + // + // For the QEMU bug, see details at + // . + .add_dma_buf(&[], &[&DmaStreamSlice::new(&self.receive_buffer, 0, 1)]) .unwrap(); + if receive_queue.should_notify() { receive_queue.notify(); }