diff --git a/content/news/rsoc-virtio-2.md b/content/news/rsoc-virtio-2.md
new file mode 100644
index 0000000000000000000000000000000000000000..0d454ed5afa441e9219a94c0a36b71c8b38db99a
--- /dev/null
+++ b/content/news/rsoc-virtio-2.md
@@ -0,0 +1,56 @@
++++
+title = "RSoC: virtio drivers - 2"
+author = "Andy-Python-Programmer"
+date = "2023-09-04"
++++
+
+*This is a continuation of https://redox-os.org/news/rsoc-virtio-1/*
+
+Over the past few weeks, there has been significant progress with the `virtio-gpu` drivers, resulting in working 2D acceleration! 🎉
+
+In addition to writing the driver itself, changes were required on how applications interact with the display device.
+
+## The `inputd` driver. 
+This driver is responsible for multiplexing the input from multiple input devices ("producer channel") and provide it to Orbital 
+("consumer channel"). This before was done inside of the VESA driver, however with the introduction of other display
+drivers, isolating the input handling into a separate driver made the interface much cleaner.
+
+In addition, every display device now opens an "inputd handle" to register the device and a VT# is assigned to each display. When a user 
+switches to a different VT, the inputd driver sends an event to the respective device, disabling the current one and enabling the newly 
+selected device. Additionally, the inputd driver offers functionality to set the VT mode (text or graphics) using `inputd -G VT#` and 
+to switch between VTs using `inputd -A VT#`.
+
+## Asynchronous Virtio Drivers - Experimentation
+The virtio drivers are now asynchronous. I've been experimenting with different ways to implement asynchronous schemes. 
+However, due to the blocking nature of POSIX syscalls, asynchronous calls are currently converted into synchronous calls. 
+Despite this, I believe that having an async driver codebase is better because it enhances code readability.
+
+### Example
+
+```rust
+// Synchronous Approach
+fn read_at(&self, _: usize, buffer: &mut [u8] -> usize {
+    if self.buffer.is_empty() && self.flags & O_NONBLOCK == O_NONBLOCK {
+	    return Err(WOULDBLOCK);
+    }
+
+    // Wait until there is an item in the buffer. 
+    while self.buffer.is_empty() { yield(); }
+    buffer[0] = self.buffer.pop();
+    return 1;
+} 
+```
+
+```rust
+// Aynchronous Approach
+async fn read_at(&self, _: usize, buffer: &mut [u8]) -> usize {
+	buffer[0] = self.buffer.pop().await; // Talking advantage of asynchronous rust syntax.
+	return 1;
+} 
+```
+
+## Other changes
+* Implementation of a mechanism to reinitialize the queues following a device reset.
+* Added support for legacy transport. Wanna try it out, append "disable-modern=on" to the device arguments when running Qemu!
+
+Stay tuned for more exciting updates! 🚀