* [Qemu-devel] [PATCH] backends: Introduce chr-testdev
@ 2014-07-11 7:44 Andrew Jones
2014-07-11 15:30 ` Eric Blake
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Jones @ 2014-07-11 7:44 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, kvmarm, christoffer.dall
From: Paolo Bonzini <pbonzini@redhat.com>
From: Paolo Bonzini <pbonzini@redhat.com>
chr-testdev enables a virtio serial channel to be used for guest
initiated qemu exits. hw/misc/debugexit already enables guest
initiated qemu exits, but only for PC targets. chr-testdev supports
any virtio-capable target. kvm-unit-tests/arm is already making use
of this backend.
Currently there is a single command implemented, "q". It takes a
(prefix) argument for the exit code, thus an exit is implemented by
writing, e.g. "1q", to the virtio-serial port.
It can be used as:
$QEMU ... \
-device virtio-serial-device \
-device virtserialport,chardev=ctd -chardev testdev,id=ctd
or, use:
$QEMU ... \
-device virtio-serial-device \
-device virtconsole,chardev=ctd -chardev testdev,id=ctd
to bind it to virtio-serial port0.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
backends/Makefile.objs | 2 +-
backends/testdev.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++
include/sysemu/char.h | 3 ++
qapi-schema.json | 1 +
qemu-char.c | 4 ++
5 files changed, 140 insertions(+), 1 deletion(-)
create mode 100644 backends/testdev.c
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 506a46c33b057..31a3a894f5ead 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -1,7 +1,7 @@
common-obj-y += rng.o rng-egd.o
common-obj-$(CONFIG_POSIX) += rng-random.o
-common-obj-y += msmouse.o
+common-obj-y += msmouse.o testdev.o
common-obj-$(CONFIG_BRLAPI) += baum.o
baum.o-cflags := $(SDL_CFLAGS)
diff --git a/backends/testdev.c b/backends/testdev.c
new file mode 100644
index 0000000000000..70d63b3b8d6bc
--- /dev/null
+++ b/backends/testdev.c
@@ -0,0 +1,131 @@
+/*
+ * QEMU Char Device for testsuite control
+ *
+ * Copyright (c) 2014 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-common.h"
+#include "sysemu/char.h"
+
+#define BUF_SIZE 32
+
+typedef struct {
+ CharDriverState *chr;
+ uint8_t in_buf[32];
+ int in_buf_used;
+} TestdevCharState;
+
+/* Try to interpret a whole incoming packet */
+static int testdev_eat_packet(TestdevCharState *testdev)
+{
+ const uint8_t *cur = testdev->in_buf;
+ int len = testdev->in_buf_used;
+ uint8_t c;
+ int arg;
+
+#define EAT(c) do { \
+ if (!len--) { \
+ return 0; \
+ } \
+ c = *cur++; \
+} while (0)
+
+ EAT(c);
+
+ while (isspace(c)) {
+ EAT(c);
+ }
+
+ arg = 0;
+ while (isdigit(c)) {
+ arg = arg * 10 + c - '0';
+ EAT(c);
+ }
+
+ while (isspace(c)) {
+ EAT(c);
+ }
+
+ switch (c) {
+ case 'q':
+ exit((arg << 1) | 1);
+ break;
+ default:
+ break;
+ }
+ return cur - testdev->in_buf;
+}
+
+/* The other end is writing some data. Store it and try to interpret */
+static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+ TestdevCharState *testdev = chr->opaque;
+ int tocopy, eaten, orig_len = len;
+
+ while (len) {
+ /* Complete our buffer as much as possible */
+ tocopy = MIN(len, BUF_SIZE - testdev->in_buf_used);
+
+ memcpy(testdev->in_buf + testdev->in_buf_used, buf, tocopy);
+ testdev->in_buf_used += tocopy;
+ buf += tocopy;
+ len -= tocopy;
+
+ /* Interpret it as much as possible */
+ while (testdev->in_buf_used > 0 &&
+ (eaten = testdev_eat_packet(testdev)) > 0) {
+ memmove(testdev->in_buf, testdev->in_buf + eaten,
+ testdev->in_buf_used - eaten);
+ testdev->in_buf_used -= eaten;
+ }
+ }
+ return orig_len;
+}
+
+static void testdev_close(struct CharDriverState *chr)
+{
+ TestdevCharState *testdev = chr->opaque;
+
+ g_free(testdev);
+}
+
+CharDriverState *chr_testdev_init(void)
+{
+ TestdevCharState *testdev;
+ CharDriverState *chr;
+
+ testdev = g_malloc0(sizeof(TestdevCharState));
+ testdev->chr = chr = g_malloc0(sizeof(CharDriverState));
+
+ chr->opaque = testdev;
+ chr->chr_write = testdev_write;
+ chr->chr_close = testdev_close;
+
+ return chr;
+}
+
+static void register_types(void)
+{
+ register_char_driver_qapi("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL);
+}
+
+type_init(register_types);
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 0bbd631e72a47..98cd4c958e723 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -358,6 +358,9 @@ CharDriverState *qemu_char_get_next_serial(void);
/* msmouse */
CharDriverState *qemu_chr_open_msmouse(void);
+/* testdev.c */
+CharDriverState *chr_testdev_init(void);
+
/* baum.c */
CharDriverState *chr_baum_init(void);
diff --git a/qapi-schema.json b/qapi-schema.json
index b11aad2068118..80b8f9cf5d677 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2764,6 +2764,7 @@
'mux' : 'ChardevMux',
'msmouse': 'ChardevDummy',
'braille': 'ChardevDummy',
+ 'testdev': 'ChardevDummy',
'stdio' : 'ChardevStdio',
'console': 'ChardevDummy',
'spicevmc' : 'ChardevSpiceChannel',
diff --git a/qemu-char.c b/qemu-char.c
index 55e372cf320d2..544c21a4937ca 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3234,6 +3234,7 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)
strcmp(filename, "pty") == 0 ||
strcmp(filename, "msmouse") == 0 ||
strcmp(filename, "braille") == 0 ||
+ strcmp(filename, "testdev") == 0 ||
strcmp(filename, "stdio") == 0) {
qemu_opt_set(opts, "backend", filename);
return opts;
@@ -4031,6 +4032,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
chr = chr_baum_init();
break;
#endif
+ case CHARDEV_BACKEND_KIND_TESTDEV:
+ chr = chr_testdev_init();
+ break;
case CHARDEV_BACKEND_KIND_STDIO:
chr = qemu_chr_open_stdio(backend->stdio);
break;
--
1.9.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] backends: Introduce chr-testdev
2014-07-11 7:44 [Qemu-devel] [PATCH] backends: Introduce chr-testdev Andrew Jones
@ 2014-07-11 15:30 ` Eric Blake
2014-07-11 15:49 ` Paolo Bonzini
0 siblings, 1 reply; 3+ messages in thread
From: Eric Blake @ 2014-07-11 15:30 UTC (permalink / raw)
To: Andrew Jones, qemu-devel; +Cc: pbonzini, kvmarm, christoffer.dall
[-- Attachment #1: Type: text/plain, Size: 1929 bytes --]
On 07/11/2014 01:44 AM, Andrew Jones wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
>
> From: Paolo Bonzini <pbonzini@redhat.com>
>
> chr-testdev enables a virtio serial channel to be used for guest
> initiated qemu exits. hw/misc/debugexit already enables guest
> initiated qemu exits, but only for PC targets. chr-testdev supports
> any virtio-capable target. kvm-unit-tests/arm is already making use
> of this backend.
>
> Currently there is a single command implemented, "q". It takes a
> (prefix) argument for the exit code, thus an exit is implemented by
> writing, e.g. "1q", to the virtio-serial port.
>
> It can be used as:
> $QEMU ... \
> -device virtio-serial-device \
> -device virtserialport,chardev=ctd -chardev testdev,id=ctd
>
> or, use:
> $QEMU ... \
> -device virtio-serial-device \
> -device virtconsole,chardev=ctd -chardev testdev,id=ctd
>
> to bind it to virtio-serial port0.
>
> +
> + switch (c) {
> + case 'q':
> + exit((arg << 1) | 1);
> + break;
I'm trying to figure out the motive for only exiting with odd numbers.
That is, 'q' => 1, '1q' => 3, '2q' => 5, '3q' => 7. It means that at
most, I can do '127q' => 255 before I suffer from exit() limiting things
to 8 bits. This wasn't explained in the commit message.
> +++ b/qapi-schema.json
> @@ -2764,6 +2764,7 @@
> 'mux' : 'ChardevMux',
> 'msmouse': 'ChardevDummy',
> 'braille': 'ChardevDummy',
> + 'testdev': 'ChardevDummy',
> 'stdio' : 'ChardevStdio',
It would be nice to have some sort of 'testdev since 2.2' documentation.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] backends: Introduce chr-testdev
2014-07-11 15:30 ` Eric Blake
@ 2014-07-11 15:49 ` Paolo Bonzini
0 siblings, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2014-07-11 15:49 UTC (permalink / raw)
To: Eric Blake, Andrew Jones, qemu-devel; +Cc: kvmarm, christoffer.dall
Il 11/07/2014 17:30, Eric Blake ha scritto:
> On 07/11/2014 01:44 AM, Andrew Jones wrote:
>> From: Paolo Bonzini <pbonzini@redhat.com>
>>
>> From: Paolo Bonzini <pbonzini@redhat.com>
>>
>> chr-testdev enables a virtio serial channel to be used for guest
>> initiated qemu exits. hw/misc/debugexit already enables guest
>> initiated qemu exits, but only for PC targets. chr-testdev supports
>> any virtio-capable target. kvm-unit-tests/arm is already making use
>> of this backend.
>>
>> Currently there is a single command implemented, "q". It takes a
>> (prefix) argument for the exit code, thus an exit is implemented by
>> writing, e.g. "1q", to the virtio-serial port.
>>
>> It can be used as:
>> $QEMU ... \
>> -device virtio-serial-device \
>> -device virtserialport,chardev=ctd -chardev testdev,id=ctd
>>
>> or, use:
>> $QEMU ... \
>> -device virtio-serial-device \
>> -device virtconsole,chardev=ctd -chardev testdev,id=ctd
>>
>> to bind it to virtio-serial port0.
>>
>
>> +
>> + switch (c) {
>> + case 'q':
>> + exit((arg << 1) | 1);
>> + break;
>
> I'm trying to figure out the motive for only exiting with odd numbers.
> That is, 'q' => 1, '1q' => 3, '2q' => 5, '3q' => 7. It means that at
> most, I can do '127q' => 255 before I suffer from exit() limiting things
> to 8 bits. This wasn't explained in the commit message.
It's just for parity with isa-debugexit.
Paolo
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-07-11 15:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-11 7:44 [Qemu-devel] [PATCH] backends: Introduce chr-testdev Andrew Jones
2014-07-11 15:30 ` Eric Blake
2014-07-11 15:49 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).