[RFC] KVMTOOL: Early printk support for virtio-mmio console.

Message ID 1366311243-6731-1-git-send-email-pranavkumar@linaro.org
State New
Headers show

Commit Message

PranavkumarSawargaonkar April 18, 2013, 6:54 p.m.
From: "Pranavkumar Sawargaonkar" <pranavkumar@linaro.org>

This patch is a counterpart implementation of virtio-mmio console early printk support in kvmtool for a rfc i posted today on kvm-arm i.e. ([RFC] arm64: Early printk support for virtio-mmio console devices)
This is initial reference version (might not be very clean).
This allows guest to print early printk on virtio-mmio console.

Signed-off-by: Anup Patel <anup.patel@linaro.org>
---
 tools/kvm/include/kvm/virtio-console.h |    5 +++++
 tools/kvm/virtio/console.c             |   30 +++++++++++++++++++++++++++++-
 tools/kvm/virtio/mmio.c                |   24 +++++++++++++++++++-----
 3 files changed, 53 insertions(+), 6 deletions(-)

Patch

diff --git a/tools/kvm/include/kvm/virtio-console.h b/tools/kvm/include/kvm/virtio-console.h
index 8980920..063c8bb 100644
--- a/tools/kvm/include/kvm/virtio-console.h
+++ b/tools/kvm/include/kvm/virtio-console.h
@@ -1,10 +1,15 @@ 
 #ifndef KVM__CONSOLE_VIRTIO_H
 #define KVM__CONSOLE_VIRTIO_H
 
+#include <linux/types.h>
+
 struct kvm;
 
 int virtio_console__init(struct kvm *kvm);
 void virtio_console__inject_interrupt(struct kvm *kvm);
 int virtio_console__exit(struct kvm *kvm);
 
+void console_write_config(struct kvm *kvm, void *dev, u64 addr, u32 i, u8 *data);
+void console_read_config(struct kvm *kvm, void *dev, u64 addr, u32 i, u8 *data);
+
 #endif /* KVM__CONSOLE_VIRTIO_H */
diff --git a/tools/kvm/virtio/console.c b/tools/kvm/virtio/console.c
index b18d3a9..47ae890 100644
--- a/tools/kvm/virtio/console.c
+++ b/tools/kvm/virtio/console.c
@@ -118,9 +118,37 @@  static u8 *get_config(struct kvm *kvm, void *dev)
 	return ((u8 *)(&cdev->config));
 }
 
+void console_write_config(struct kvm *kvm, void *dev, u64 addr, u32 i, u8 *data)
+{
+	struct con_dev *cdev = dev;
+	u8 *p;
+
+	if (addr != offsetof(struct virtio_console_config, early_rw)) {
+		p = ((u8 *)(&cdev->config));
+		p[addr + i] = *(u8 *)data + i;
+
+	} else {
+		/* early_rw write */
+		term_putc((char *) (data + i), 1, 0);
+	}
+}
+
+void console_read_config(struct kvm *kvm, void *dev, u64 addr, u32 i, u8 *data)
+{
+	struct con_dev *cdev = dev;
+	u8 *p;
+
+	if (addr != offsetof(struct virtio_console_config, early_rw)) {
+		p = ((u8 *)(&cdev->config));
+		data[i] = p[addr + i];
+	} else {
+		/* TBD: implement early_rw read with the help of term_getc */
+	}
+}
+
 static u32 get_host_features(struct kvm *kvm, void *dev)
 {
-	return 0;
+	return (1 << VIRTIO_CONSOLE_F_EARLY_WRITE);
 }
 
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
diff --git a/tools/kvm/virtio/mmio.c b/tools/kvm/virtio/mmio.c
index bd30f37..6b116e9 100644
--- a/tools/kvm/virtio/mmio.c
+++ b/tools/kvm/virtio/mmio.c
@@ -3,9 +3,11 @@ 
 #include "kvm/ioeventfd.h"
 #include "kvm/ioport.h"
 #include "kvm/virtio.h"
+#include "kvm/virtio-console.h"
 #include "kvm/kvm.h"
 #include "kvm/irq.h"
 
+#include <linux/virtio_ids.h>
 #include <linux/virtio_mmio.h>
 #include <string.h>
 
@@ -94,12 +96,24 @@  static void virtio_mmio_device_specific(u64 addr, u8 *data, u32 len,
 	u32 i;
 
 	for (i = 0; i < len; i++) {
-		if (is_write)
-			vdev->ops->get_config(vmmio->kvm, vmmio->dev)[addr + i] =
-					      *(u8 *)data + i;
-		else
-			data[i] = vdev->ops->get_config(vmmio->kvm,
+		if (is_write) {
+			if (vmmio->hdr.device_id == VIRTIO_ID_CONSOLE) {
+				console_write_config(vmmio->kvm, vmmio->dev,
+								addr, i, data);
+			} else {
+				vdev->ops->get_config(vmmio->kvm,
+							vmmio->dev)[addr + i] =
+							*(u8 *)data + i;
+			}
+		} else {
+			if (vmmio->hdr.device_id == VIRTIO_ID_CONSOLE) {
+				console_read_config(vmmio->kvm, vmmio->dev,
+							addr, i, data);
+			} else {
+				data[i] = vdev->ops->get_config(vmmio->kvm,
 							vmmio->dev)[addr + i];
+			}
+		}
 	}
 }