[PATCH v7 08/14] Introduce chr-testdev

Andrew Jones
2014-07-16T08:48:03Z

chr-testdev is a qemu backend that can be used by test code to send qemu
commands. It communicates with qemu through a virtio-console device. The
only command currently implemented is "quit", which allows the test code
to exit with a given status code, i.e. chr_testdev_exit(code).

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
lib/chr-testdev.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/chr-testdev.h | 14 +++++++++++
lib/virtio.h | 2 ++
3 files changed, 88 insertions(+)
create mode 100644 lib/chr-testdev.c
create mode 100644 lib/chr-testdev.h

diff --git a/lib/chr-testdev.c b/lib/chr-testdev.c
new file mode 100644
index 0000000000000..0c9a173a04886
--- /dev/null
+++ b/lib/chr-testdev.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "libcflat.h"
+#include "virtio.h"
+#include "asm/spinlock.h"
+
+#define TESTDEV_NAME "chr-testdev"
+
+static struct virtio_device *vcon;
+static struct virtqueue *in_vq, *out_vq;
+static struct spinlock lock;
+
+static void __testdev_send(char *buf, size_t len)
+{
+ int ret;
+
+ ret = virtqueue_add_outbuf(out_vq, buf, len);
+ virtqueue_kick(out_vq);
+
+ if (ret < 0)
+ return;
+
+ while (!virtqueue_get_buf(out_vq, &len))
+ ;
+}
+
+void chr_testdev_exit(int code)
+{
+ char buf[8];
+ int len;
+
+ snprintf(buf, sizeof(buf), "%dq", code);
+ len = strlen(buf);
+
+ spin_lock(&lock);
+
+ if (!vcon)
+ goto out;
+
+ __testdev_send(buf, len);
+
+out:
+ spin_unlock(&lock);
+}
+
+void chr_testdev_init(void)
+{
+ const char *io_names[] = { "input", "output" };
+ struct virtqueue *vqs[2];
+ int ret;
+
+ vcon = virtio_bind(VIRTIO_ID_CONSOLE);
+ if (vcon == NULL) {
+ printf("%s: %s: can't find a virtio-console\n",
+ __func__, TESTDEV_NAME);
+ return;
+ }
+
+ ret = vcon->config->find_vqs(vcon, 2, vqs, NULL, io_names);
+ if (ret < 0) {
+ printf("%s: %s: can't init virtqueues\n",
+ __func__, TESTDEV_NAME);
+ vcon = NULL;
+ return;
+ }
+
+ in_vq = vqs[0];
+ out_vq = vqs[1];
+}
diff --git a/lib/chr-testdev.h b/lib/chr-testdev.h
new file mode 100644
index 0000000000000..ffd9a851aa9b9
--- /dev/null
+++ b/lib/chr-testdev.h
@@ -0,0 +1,14 @@
+#ifndef _CHR_TESTDEV_H_
+#define _CHR_TESTDEV_H_
+/*
+ * chr-testdev is a driver for the chr-testdev qemu backend.
+ * The chr-testdev backend exposes a simple control interface to
+ * qemu for kvm-unit-tests accessible through virtio-console.
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+extern void chr_testdev_init(void);
+extern void chr_testdev_exit(int code);
+#endif
diff --git a/lib/virtio.h b/lib/virtio.h
index 37ce028b2c2bb..b51899ab998b6 100644
--- a/lib/virtio.h
+++ b/lib/virtio.h
@@ -10,6 +10,8 @@
*/
#include "libcflat.h"

+#define VIRTIO_ID_CONSOLE 3
+
struct virtio_device_id {
u32 device;
u32 vendor;
--
1.9.3