From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Cc: xen-devel@lists.xensource.com, Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 3/7] xen: add console backend driver.
Date: Mon, 28 Jul 2008 09:17:35 -0500 [thread overview]
Message-ID: <488DD4FF.9030400@codemonkey.ws> (raw)
In-Reply-To: <1217251078-6591-4-git-send-email-kraxel@redhat.com>
Gerd Hoffmann wrote:
> This patch adds a xenconsole backend driver. It it based on current
> xen-unstable code. It has been changed to make use of the common
> backend driver code.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> Makefile.target | 1 +
> hw/xen-backend.h | 3 +
> hw/xen-console.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/xen-machine.c | 2 +
> 4 files changed, 277 insertions(+), 0 deletions(-)
> create mode 100644 hw/xen-console.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 0451048..05619fa 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -517,6 +517,7 @@ endif
>
> # xen backend driver support
> XEN_OBJS := xen-machine.o xen-backend.o
> +XEN_OBJS += xen-console.o
> ifeq ($(CONFIG_XEN), yes)
> OBJS += $(XEN_OBJS)
> LIBS += $(XEN_LIBS)
> diff --git a/hw/xen-backend.h b/hw/xen-backend.h
> index db36ae7..55ffd31 100644
> --- a/hw/xen-backend.h
> +++ b/hw/xen-backend.h
> @@ -114,3 +114,6 @@ int xen_be_send_notify(struct xendev *xendev);
> void xen_be_printf(struct xendev *xendev, int msg_level, const char *fmt, ...)
> __attribute__ ((format(printf, 3, 4)));
>
> +/* actual backend drivers */
> +struct devops xen_console_ops; /* xen_console.c */
> +
> diff --git a/hw/xen-console.c b/hw/xen-console.c
> new file mode 100644
> index 0000000..9c67f1b
> --- /dev/null
> +++ b/hw/xen-console.c
> @@ -0,0 +1,271 @@
> +/*
> + * Copyright (C) International Business Machines Corp., 2005
> + * Author(s): Anthony Liguori <aliguori@us.ibm.com>
> + *
> + * Copyright (C) Red Hat 2007
> + *
> + * Xen Console
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; under version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#include <malloc.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/select.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <termios.h>
> +#include <stdarg.h>
> +#include <sys/mman.h>
> +#include <xs.h>
> +#include <xen/io/console.h>
> +#include <xenctrl.h>
> +
> +#include "hw.h"
> +#include "sysemu.h"
> +#include "qemu-char.h"
> +#include "xen-backend.h"
> +
> +#define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__)
> +
> +struct buffer {
> + uint8_t *data;
> + size_t consumed;
> + size_t size;
> + size_t capacity;
> + size_t max_capacity;
> +};
> +
> +struct xen_console {
> + struct xendev xendev; /* must be first */
> + struct buffer buffer;
> + char console[BUFSIZE];
> + int ring_ref;
> + void *sring;
> + CharDriverState *chr;
> + int backlog;
> +};
> +
> +static void buffer_append(struct xen_console *con)
> +{
> + struct buffer *buffer = &con->buffer;
> + XENCONS_RING_IDX cons, prod, size;
> + struct xencons_interface *intf = con->sring;
> +
> + cons = intf->out_cons;
> + prod = intf->out_prod;
> + xen_mb();
> +
> + size = prod - cons;
> + if ((size == 0) || (size > sizeof(intf->out)))
> + return;
> +
> + if ((buffer->capacity - buffer->size) < size) {
> + buffer->capacity += (size + 1024);
> + buffer->data = realloc(buffer->data, buffer->capacity);
> + if (buffer->data == NULL) {
> + dolog(LOG_ERR, "Memory allocation failed");
> + exit(ENOMEM);
> + }
> + }
> +
> + while (cons != prod)
> + buffer->data[buffer->size++] = intf->out[
> + MASK_XENCONS_IDX(cons++, intf->out)];
> +
> + xen_mb();
> + intf->out_cons = cons;
> + xen_be_send_notify(&con->xendev);
> +
> + if (buffer->max_capacity &&
> + buffer->size > buffer->max_capacity) {
> + /* Discard the middle of the data. */
> +
> + size_t over = buffer->size - buffer->max_capacity;
> + uint8_t *maxpos = buffer->data + buffer->max_capacity;
> +
> + memmove(maxpos - over, maxpos, over);
> + buffer->data = realloc(buffer->data, buffer->max_capacity);
> + buffer->size = buffer->capacity = buffer->max_capacity;
> +
> + if (buffer->consumed > buffer->max_capacity - over)
> + buffer->consumed = buffer->max_capacity - over;
> + }
> +}
> +
> +static void buffer_advance(struct buffer *buffer, size_t len)
> +{
> + buffer->consumed += len;
> + if (buffer->consumed == buffer->size) {
> + buffer->consumed = 0;
> + buffer->size = 0;
> + }
> +}
> +
> +static int ring_free_bytes(struct xen_console *con)
> +{
> + struct xencons_interface *intf = con->sring;
> + XENCONS_RING_IDX cons, prod, space;
> +
> + cons = intf->in_cons;
> + prod = intf->in_prod;
> + xen_mb();
> +
> + space = prod - cons;
> + if (space > sizeof(intf->in))
> + return 0; /* ring is screwed: ignore it */
> +
> + return (sizeof(intf->in) - space);
> +}
> +
> +static int xencons_can_receive(void *opaque)
> +{
> + struct xen_console *con = opaque;
> + return ring_free_bytes(con);
> +}
> +
> +static void xencons_receive(void *opaque, const uint8_t *buf, int len)
> +{
> + struct xen_console *con = opaque;
> + struct xencons_interface *intf = con->sring;
> + XENCONS_RING_IDX prod;
> + int i, max;
> +
> + max = ring_free_bytes(con);
> + /* The can_receive() func limits this, but check again anyway */
> + if (max < len)
> + len = max;
> +
> + prod = intf->in_prod;
> + for (i = 0; i < len; i++) {
> + intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
> + buf[i];
> + }
> + xen_wmb();
> + intf->in_prod = prod;
> + xen_be_send_notify(&con->xendev);
> +}
> +
> +static void xencons_send(struct xen_console *con)
> +{
> + ssize_t len, size;
> +
> + size = con->buffer.size - con->buffer.consumed;
> + len = qemu_chr_write(con->chr, con->buffer.data + con->buffer.consumed,
> + size);
> + if (len < 1) {
> + if (!con->backlog) {
> + con->backlog = 1;
> + xen_be_printf(&con->xendev, 1, "backlog piling up, nobody listening?\n");
> + }
> + } else {
> + buffer_advance(&con->buffer, len);
> + if (con->backlog && len == size) {
> + con->backlog = 0;
> + xen_be_printf(&con->xendev, 1, "backlog is gone\n");
> + }
> + }
> +}
> +
> +/* -------------------------------------------------------------------- */
> +
> +static int con_init(struct xendev *xendev)
> +{
> + struct xen_console *con = container_of(xendev, struct xen_console, xendev);
> + char *type;
> +
> + if (!serial_hds[con->xendev.dev]) {
> + xen_be_printf(xendev, 1, "serial line %d not configured\n", con->xendev.dev);
> + return -1;
> + }
> +
> + /* setup */
> + snprintf(con->console, sizeof(con->console),
> + "/local/domain/%d/console", con->xendev.dom);
> + con->chr = serial_hds[con->xendev.dev];
> +
> + type = xenstore_read_str(con->console, "type");
> + if (!type || 0 != strcmp(type, "ioemu")) {
> + xen_be_printf(xendev, 1, "not for me (type=%s)\n", type);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int con_connect(struct xendev *xendev)
> +{
> + struct xen_console *con = container_of(xendev, struct xen_console, xendev);
> + int limit;
> +
> + if (-1 == xenstore_read_int(con->console, "ring-ref", &con->ring_ref))
> + return -1;
> + if (-1 == xenstore_read_int(con->console, "port", &con->xendev.remote_port))
> + return -1;
> + if (0 == xenstore_read_int(con->console, "limit", &limit))
> + con->buffer.max_capacity = limit;
> +
> + con->sring = xc_map_foreign_range(xen_xc, con->xendev.dom,
> + XC_PAGE_SIZE,
> + PROT_READ|PROT_WRITE,
> + con->ring_ref);
> + if (!con->sring)
> + return -1;
> +
> + xen_be_bind_evtchn(&con->xendev);
> + qemu_chr_add_handlers(con->chr, xencons_can_receive, xencons_receive,
> + NULL, con);
> +
> + xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
> + con->ring_ref,
> + con->xendev.remote_port,
> + con->xendev.local_port,
> + con->buffer.max_capacity);
> + return 0;
> +}
> +
> +static void con_disconnect(struct xendev *xendev)
> +{
> + struct xen_console *con = container_of(xendev, struct xen_console, xendev);
> +
> + qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
> + xen_be_unbind_evtchn(&con->xendev);
> +
> + if (con->sring) {
> + munmap(con->sring, XC_PAGE_SIZE);
> + con->sring = NULL;
> + }
> +}
> +
> +static void con_event(struct xendev *xendev)
> +{
> + struct xen_console *con = container_of(xendev, struct xen_console, xendev);
> +
> + buffer_append(con);
> + if (con->buffer.size - con->buffer.consumed)
> + xencons_send(con);
> +}
> +
> +/* -------------------------------------------------------------------- */
> +
> +struct devops xen_console_ops = {
>
I missed it in the previous patchset, but it would be nice to QEMU-ify
these things. For instance, 'struct xen_console' => 'XenConsole',
'struct devopts' => 'XenDevOpts', etc.
Regards,
Anthony Liguori
> + .size = sizeof(struct xen_console),
> + .flags = DEVOPS_FLAG_IGNORE_STATE,
> + .init = con_init,
> + .connect = con_connect,
> + .event = con_event,
> + .disconnect = con_disconnect,
> +};
> diff --git a/hw/xen-machine.c b/hw/xen-machine.c
> index 798c0a7..da10982 100644
> --- a/hw/xen-machine.c
> +++ b/hw/xen-machine.c
> @@ -57,6 +57,8 @@ static void xenpv_init(ram_addr_t ram_size, int vga_ram_size,
>
> /* setup xen backend handlers */
> xen_be_init();
> +
> + xen_be_register("console", &xen_console_ops);
> }
>
> QEMUMachine xenpv_machine = {
>
next prev parent reply other threads:[~2008-07-28 14:18 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-28 13:17 [Qemu-devel] [PATCH 0/7] merge some xen bits into qemu Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 13:17 ` [Qemu-devel] [PATCH 1/7] xen: groundwork for xen support Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:04 ` [Qemu-devel] " Anthony Liguori
2008-07-28 14:52 ` Gerd Hoffmann
2008-07-29 8:10 ` [Xen-devel] " Daniel P. Berrange
2008-07-29 8:10 ` Daniel P. Berrange
2008-07-29 13:32 ` [Xen-devel] " Anthony Liguori
2008-07-29 13:32 ` Anthony Liguori
2008-07-29 14:24 ` [Xen-devel] " Daniel P. Berrange
2008-07-29 14:24 ` Daniel P. Berrange
2008-07-29 19:11 ` [Xen-devel] " Anthony Liguori
2008-07-29 19:11 ` Anthony Liguori
2008-07-29 21:36 ` [Xen-devel] " Gerd Hoffmann
2008-07-29 21:36 ` Gerd Hoffmann
2008-07-29 21:48 ` [Xen-devel] " Anthony Liguori
2008-07-29 21:48 ` Anthony Liguori
2008-07-29 14:32 ` [Xen-devel] " Gerd Hoffmann
2008-07-29 14:32 ` Gerd Hoffmann
2008-07-28 23:14 ` [Xen-devel] " Samuel Thibault
2008-07-28 23:14 ` Samuel Thibault
2008-07-29 7:38 ` [Xen-devel] " Gerd Hoffmann
2008-07-29 7:38 ` Gerd Hoffmann
2008-07-29 8:12 ` [Xen-devel] " Daniel P. Berrange
2008-07-29 8:12 ` Daniel P. Berrange
2008-07-29 8:55 ` [Xen-devel] " Gerd Hoffmann
2008-07-29 8:55 ` Gerd Hoffmann
2008-07-28 13:17 ` [Qemu-devel] [PATCH 2/7] xen: backend driver core Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:13 ` [Qemu-devel] " Anthony Liguori
2008-07-28 15:51 ` Gerd Hoffmann
2008-07-28 13:17 ` [Qemu-devel] [PATCH 3/7] xen: add console backend driver Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:17 ` Anthony Liguori [this message]
2008-07-28 15:43 ` [Qemu-devel] " Gerd Hoffmann
2008-07-28 19:04 ` Anthony Liguori
2008-07-28 13:17 ` [Qemu-devel] [PATCH 4/7] xen: add framebuffer " Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:22 ` [Qemu-devel] " Anthony Liguori
2008-07-28 14:41 ` Andreas Färber
2008-07-28 14:41 ` Andreas Färber
2008-07-30 9:59 ` [Qemu-devel] " Gerd Hoffmann
2008-08-01 14:57 ` Anthony Liguori
2008-07-30 9:20 ` Gerd Hoffmann
2008-07-30 9:20 ` Gerd Hoffmann
2008-07-30 16:31 ` [Qemu-devel] " Markus Armbruster
2008-07-30 16:31 ` Markus Armbruster
2008-08-01 15:05 ` Anthony Liguori
2008-07-28 13:17 ` [Qemu-devel] [PATCH 5/7] xen: add block device " Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:25 ` [Qemu-devel] " Anthony Liguori
2008-07-28 13:17 ` [Qemu-devel] [PATCH 6/7] xen: add net " Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
2008-07-28 14:27 ` [Qemu-devel] " Anthony Liguori
2008-07-28 15:45 ` Gerd Hoffmann
2008-07-28 13:17 ` [Qemu-devel] [PATCH 7/7] xen: blk & nic configuration via cmd line Gerd Hoffmann
2008-07-28 13:17 ` Gerd Hoffmann
-- strict thread matches above, loose matches on Subject: below --
2008-08-04 15:50 [Qemu-devel] [PATCH 0/7] merge some xen bits into qemu Gerd Hoffmann
2008-08-04 15:50 ` [Qemu-devel] [PATCH 3/7] xen: add console backend driver Gerd Hoffmann
2008-08-04 16:52 ` Blue Swirl
2008-08-04 18:15 ` Gerd Hoffmann
2008-08-04 20:47 ` Blue Swirl
2008-10-28 12:23 [Qemu-devel] [PATCH 0/7] merge some xen bits into qemu Gerd Hoffmann
2008-10-28 12:23 ` [Qemu-devel] [PATCH 3/7] xen: add console backend driver Gerd Hoffmann
2008-10-28 17:16 ` Blue Swirl
2008-10-29 10:53 ` Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=488DD4FF.9030400@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.