From: Bhupinder Thakur <bhupinder.thakur@linaro.org>
To: xen-devel@lists.xenproject.org
Cc: Wei Liu <wei.liu2@citrix.com>,
Julien Grall <julien.grall@arm.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 08/14 v4] xen/arm: vpl011: Modify xenconsole to define and use a new console structure
Date: Tue, 6 Jun 2017 22:55:23 +0530 [thread overview]
Message-ID: <1496769929-23355-9-git-send-email-bhupinder.thakur@linaro.org> (raw)
In-Reply-To: <1496769929-23355-1-git-send-email-bhupinder.thakur@linaro.org>
Xenconsole uses a domain structure which contains console specific fields. This
patch defines a new console structure, which would be used by the xenconsole
functions to perform console specific operations like reading/writing data from/to
the console ring buffer or reading/writing data from/to console tty.
This patch is in preparation to support multiple consoles to support vuart console.
Signed-off-by: Bhupinder Thakur <bhupinder.thakur@linaro.org>
---
CC: ij
CC: wl
CC: ss
CC: jg
Changes since v3:
- The changes in xenconsole have been split into four patches. This is the first patch
which modifies the xenconsole to use a new console structure.
Changes since v2:
- Defined a new function console_create_ring() which sets up the ring buffer and
event channel a new console. domain_create_ring() uses this function to setup
a console.
- This patch does not contain vuart specific changes, which would be introduced in
the next patch.
- Changes for keeping the PV log file name unchanged.
Changes since v1:
- Split the domain struture to a separate console structure
- Modified the functions to operate on the console struture
- Replaced repetitive per console code with generic code
tools/console/daemon/io.c | 226 ++++++++++++++++++++++++++--------------------
1 file changed, 127 insertions(+), 99 deletions(-)
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 947f13a..0402ddf 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -89,25 +89,30 @@ struct buffer {
size_t max_capacity;
};
-struct domain {
- int domid;
+struct console {
int master_fd;
int master_pollfd_idx;
int slave_fd;
int log_fd;
- bool is_dead;
- unsigned last_seen;
struct buffer buffer;
- struct domain *next;
char *conspath;
int ring_ref;
xenevtchn_port_or_error_t local_port;
xenevtchn_port_or_error_t remote_port;
+ struct xencons_interface *interface;
+ struct domain *d;
+};
+
+struct domain {
+ int domid;
+ bool is_dead;
+ unsigned last_seen;
+ struct domain *next;
xenevtchn_handle *xce_handle;
int xce_pollfd_idx;
- struct xencons_interface *interface;
int event_count;
long long next_period;
+ struct console console;
};
static struct domain *dom_head;
@@ -160,9 +165,10 @@ static int write_with_timestamp(int fd, const char *data, size_t sz,
static void buffer_append(struct domain *dom)
{
- struct buffer *buffer = &dom->buffer;
+ struct console *con = &dom->console;
+ struct buffer *buffer = &con->buffer;
XENCONS_RING_IDX cons, prod, size;
- struct xencons_interface *intf = dom->interface;
+ struct xencons_interface *intf = con->interface;
cons = intf->out_cons;
prod = intf->out_prod;
@@ -187,22 +193,22 @@ static void buffer_append(struct domain *dom)
xen_mb();
intf->out_cons = cons;
- xenevtchn_notify(dom->xce_handle, dom->local_port);
+ xenevtchn_notify(dom->xce_handle, con->local_port);
/* Get the data to the logfile as early as possible because if
* no one is listening on the console pty then it will fill up
* and handle_tty_write will stop being called.
*/
- if (dom->log_fd != -1) {
+ if (con->log_fd != -1) {
int logret;
if (log_time_guest) {
logret = write_with_timestamp(
- dom->log_fd,
+ con->log_fd,
buffer->data + buffer->size - size,
size, &log_time_guest_needts);
} else {
logret = write_all(
- dom->log_fd,
+ con->log_fd,
buffer->data + buffer->size - size,
size);
}
@@ -338,14 +344,16 @@ static int create_domain_log(struct domain *dom)
static void domain_close_tty(struct domain *dom)
{
- if (dom->master_fd != -1) {
- close(dom->master_fd);
- dom->master_fd = -1;
+ struct console *con = &dom->console;
+
+ if (con->master_fd != -1) {
+ close(con->master_fd);
+ con->master_fd = -1;
}
- if (dom->slave_fd != -1) {
- close(dom->slave_fd);
- dom->slave_fd = -1;
+ if (con->slave_fd != -1) {
+ close(con->slave_fd);
+ con->slave_fd = -1;
}
}
@@ -418,11 +426,12 @@ static int domain_create_tty(struct domain *dom)
char *data;
unsigned int len;
struct termios term;
+ struct console *con = &dom->console;
- assert(dom->slave_fd == -1);
- assert(dom->master_fd == -1);
+ assert(con->slave_fd == -1);
+ assert(con->master_fd == -1);
- if (openpty(&dom->master_fd, &dom->slave_fd, NULL, NULL, NULL) < 0) {
+ if (openpty(&con->master_fd, &con->slave_fd, NULL, NULL, NULL) < 0) {
err = errno;
dolog(LOG_ERR, "Failed to create tty for domain-%d "
"(errno = %i, %s)",
@@ -430,7 +439,7 @@ static int domain_create_tty(struct domain *dom)
return 0;
}
- if (tcgetattr(dom->slave_fd, &term) < 0) {
+ if (tcgetattr(con->slave_fd, &term) < 0) {
err = errno;
dolog(LOG_ERR, "Failed to get tty attributes for domain-%d "
"(errno = %i, %s)",
@@ -438,7 +447,7 @@ static int domain_create_tty(struct domain *dom)
goto out;
}
cfmakeraw(&term);
- if (tcsetattr(dom->slave_fd, TCSANOW, &term) < 0) {
+ if (tcsetattr(con->slave_fd, TCSANOW, &term) < 0) {
err = errno;
dolog(LOG_ERR, "Failed to set tty attributes for domain-%d "
"(errno = %i, %s)",
@@ -446,7 +455,7 @@ static int domain_create_tty(struct domain *dom)
goto out;
}
- if ((slave = ptsname(dom->master_fd)) == NULL) {
+ if ((slave = ptsname(con->master_fd)) == NULL) {
err = errno;
dolog(LOG_ERR, "Failed to get slave name for domain-%d "
"(errno = %i, %s)",
@@ -454,18 +463,18 @@ static int domain_create_tty(struct domain *dom)
goto out;
}
- success = asprintf(&path, "%s/limit", dom->conspath) !=
+ success = asprintf(&path, "%s/limit", con->conspath) !=
-1;
if (!success)
goto out;
data = xs_read(xs, XBT_NULL, path, &len);
if (data) {
- dom->buffer.max_capacity = strtoul(data, 0, 0);
+ con->buffer.max_capacity = strtoul(data, 0, 0);
free(data);
}
free(path);
- success = (asprintf(&path, "%s/tty", dom->conspath) != -1);
+ success = (asprintf(&path, "%s/tty", con->conspath) != -1);
if (!success)
goto out;
success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
@@ -473,7 +482,7 @@ static int domain_create_tty(struct domain *dom)
if (!success)
goto out;
- if (fcntl(dom->master_fd, F_SETFL, O_NONBLOCK) == -1)
+ if (fcntl(con->master_fd, F_SETFL, O_NONBLOCK) == -1)
goto out;
return 1;
@@ -519,29 +528,32 @@ static int xs_gather(struct xs_handle *xs, const char *dir, ...)
static void domain_unmap_interface(struct domain *dom)
{
- if (dom->interface == NULL)
+ struct console *con = &dom->console;
+
+ if (con->interface == NULL)
return;
- if (xgt_handle && dom->ring_ref == -1)
- xengnttab_unmap(xgt_handle, dom->interface, 1);
+ if (xgt_handle && con->ring_ref == -1)
+ xengnttab_unmap(xgt_handle, con->interface, 1);
else
- munmap(dom->interface, XC_PAGE_SIZE);
- dom->interface = NULL;
- dom->ring_ref = -1;
+ munmap(con->interface, XC_PAGE_SIZE);
+ con->interface = NULL;
+ con->ring_ref = -1;
}
static int domain_create_ring(struct domain *dom)
{
int err, remote_port, ring_ref, rc;
char *type, path[PATH_MAX];
+ struct console *con = &dom->console;
- err = xs_gather(xs, dom->conspath,
+ err = xs_gather(xs, con->conspath,
"ring-ref", "%u", &ring_ref,
"port", "%i", &remote_port,
NULL);
if (err)
goto out;
- snprintf(path, sizeof(path), "%s/type", dom->conspath);
+ snprintf(path, sizeof(path), "%s/type", con->conspath);
type = xs_read(xs, XBT_NULL, path, NULL);
if (type && strcmp(type, "xenconsoled") != 0) {
free(type);
@@ -550,41 +562,41 @@ static int domain_create_ring(struct domain *dom)
free(type);
/* If using ring_ref and it has changed, remap */
- if (ring_ref != dom->ring_ref && dom->ring_ref != -1)
+ if (ring_ref != con->ring_ref && con->ring_ref != -1)
domain_unmap_interface(dom);
- if (!dom->interface && xgt_handle) {
+ if (!con->interface && xgt_handle) {
/* Prefer using grant table */
- dom->interface = xengnttab_map_grant_ref(xgt_handle,
+ con->interface = xengnttab_map_grant_ref(xgt_handle,
dom->domid, GNTTAB_RESERVED_CONSOLE,
PROT_READ|PROT_WRITE);
- dom->ring_ref = -1;
+ con->ring_ref = -1;
}
- if (!dom->interface) {
+ if (!con->interface) {
/* Fall back to xc_map_foreign_range */
- dom->interface = xc_map_foreign_range(
+ con->interface = xc_map_foreign_range(
xc, dom->domid, XC_PAGE_SIZE,
PROT_READ|PROT_WRITE,
(unsigned long)ring_ref);
- if (dom->interface == NULL) {
+ if (con->interface == NULL) {
err = EINVAL;
goto out;
}
- dom->ring_ref = ring_ref;
+ con->ring_ref = ring_ref;
}
/* Go no further if port has not changed and we are still bound. */
- if (remote_port == dom->remote_port) {
+ if (remote_port == con->remote_port) {
xc_evtchn_status_t status = {
.dom = DOMID_SELF,
- .port = dom->local_port };
+ .port = con->local_port };
if ((xc_evtchn_status(xc, &status) == 0) &&
(status.status == EVTCHNSTAT_interdomain))
goto out;
}
- dom->local_port = -1;
- dom->remote_port = -1;
+ con->local_port = -1;
+ con->remote_port = -1;
if (dom->xce_handle != NULL)
xenevtchn_close(dom->xce_handle);
@@ -605,22 +617,22 @@ static int domain_create_ring(struct domain *dom)
dom->xce_handle = NULL;
goto out;
}
- dom->local_port = rc;
- dom->remote_port = remote_port;
+ con->local_port = rc;
+ con->remote_port = remote_port;
- if (dom->master_fd == -1) {
+ if (con->master_fd == -1) {
if (!domain_create_tty(dom)) {
err = errno;
xenevtchn_close(dom->xce_handle);
dom->xce_handle = NULL;
- dom->local_port = -1;
- dom->remote_port = -1;
+ con->local_port = -1;
+ con->remote_port = -1;
goto out;
}
}
- if (log_guest && (dom->log_fd == -1))
- dom->log_fd = create_domain_log(dom);
+ if (log_guest && (con->log_fd == -1))
+ con->log_fd = create_domain_log(dom);
out:
return err;
@@ -630,16 +642,17 @@ static bool watch_domain(struct domain *dom, bool watch)
{
char domid_str[3 + MAX_STRLEN(dom->domid)];
bool success;
+ struct console *con = &dom->console;
snprintf(domid_str, sizeof(domid_str), "dom%u", dom->domid);
if (watch) {
- success = xs_watch(xs, dom->conspath, domid_str);
+ success = xs_watch(xs, con->conspath, domid_str);
if (success)
domain_create_ring(dom);
else
- xs_unwatch(xs, dom->conspath, domid_str);
+ xs_unwatch(xs, con->conspath, domid_str);
} else {
- success = xs_unwatch(xs, dom->conspath, domid_str);
+ success = xs_unwatch(xs, con->conspath, domid_str);
}
return success;
@@ -651,6 +664,7 @@ static struct domain *create_domain(int domid)
struct domain *dom;
char *s;
struct timespec ts;
+ struct console *con;
if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d",
@@ -667,25 +681,26 @@ static struct domain *create_domain(int domid)
dom->domid = domid;
- dom->conspath = xs_get_domain_path(xs, dom->domid);
- s = realloc(dom->conspath, strlen(dom->conspath) +
+ con = &dom->console;
+ con->conspath = xs_get_domain_path(xs, dom->domid);
+ s = realloc(con->conspath, strlen(con->conspath) +
strlen("/console") + 1);
if (s == NULL)
goto out;
- dom->conspath = s;
- strcat(dom->conspath, "/console");
+ con->conspath = s;
+ strcat(con->conspath, "/console");
- dom->master_fd = -1;
- dom->master_pollfd_idx = -1;
- dom->slave_fd = -1;
- dom->log_fd = -1;
+ con->master_fd = -1;
+ con->master_pollfd_idx = -1;
+ con->slave_fd = -1;
+ con->log_fd = -1;
dom->xce_pollfd_idx = -1;
dom->next_period = ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000) + RATE_LIMIT_PERIOD;
- dom->ring_ref = -1;
- dom->local_port = -1;
- dom->remote_port = -1;
+ con->ring_ref = -1;
+ con->local_port = -1;
+ con->remote_port = -1;
if (!watch_domain(dom, true))
goto out;
@@ -697,7 +712,7 @@ static struct domain *create_domain(int domid)
return dom;
out:
- free(dom->conspath);
+ free(con->conspath);
free(dom);
return NULL;
}
@@ -729,18 +744,20 @@ static void remove_domain(struct domain *dom)
static void cleanup_domain(struct domain *d)
{
+ struct console *con = &d->console;
+
domain_close_tty(d);
- if (d->log_fd != -1) {
- close(d->log_fd);
- d->log_fd = -1;
+ if (con->log_fd != -1) {
+ close(con->log_fd);
+ con->log_fd = -1;
}
- free(d->buffer.data);
- d->buffer.data = NULL;
+ free(con->buffer.data);
+ con->buffer.data = NULL;
- free(d->conspath);
- d->conspath = NULL;
+ free(con->conspath);
+ con->conspath = NULL;
remove_domain(d);
}
@@ -782,7 +799,8 @@ static void enum_domains(void)
static int ring_free_bytes(struct domain *dom)
{
- struct xencons_interface *intf = dom->interface;
+ struct console *con = &dom->console;
+ struct xencons_interface *intf = con->interface;
XENCONS_RING_IDX cons, prod, space;
cons = intf->in_cons;
@@ -812,7 +830,8 @@ static void handle_tty_read(struct domain *dom)
ssize_t len = 0;
char msg[80];
int i;
- struct xencons_interface *intf = dom->interface;
+ struct console *con = &dom->console;
+ struct xencons_interface *intf = con->interface;
XENCONS_RING_IDX prod;
if (dom->is_dead)
@@ -825,7 +844,7 @@ static void handle_tty_read(struct domain *dom)
if (len > sizeof(msg))
len = sizeof(msg);
- len = read(dom->master_fd, msg, len);
+ len = read(con->master_fd, msg, len);
/*
* Note: on Solaris, len == 0 means the slave closed, and this
* is no problem, but Linux can't handle this usefully, so we
@@ -841,7 +860,7 @@ static void handle_tty_read(struct domain *dom)
}
xen_wmb();
intf->in_prod = prod;
- xenevtchn_notify(dom->xce_handle, dom->local_port);
+ xenevtchn_notify(dom->xce_handle, con->local_port);
} else {
domain_close_tty(dom);
shutdown_domain(dom);
@@ -851,18 +870,19 @@ static void handle_tty_read(struct domain *dom)
static void handle_tty_write(struct domain *dom)
{
ssize_t len;
+ struct console *con = &dom->console;
if (dom->is_dead)
return;
- len = write(dom->master_fd, dom->buffer.data + dom->buffer.consumed,
- dom->buffer.size - dom->buffer.consumed);
+ len = write(con->master_fd, con->buffer.data + con->buffer.consumed,
+ con->buffer.size - con->buffer.consumed);
if (len < 1) {
dolog(LOG_DEBUG, "Write failed on domain %d: %zd, %d\n",
dom->domid, len, errno);
domain_handle_broken_tty(dom, domain_is_valid(dom->domid));
} else {
- buffer_advance(&dom->buffer, len);
+ buffer_advance(&con->buffer, len);
}
}
@@ -948,9 +968,11 @@ static void handle_log_reload(void)
if (log_guest) {
struct domain *d;
for (d = dom_head; d; d = d->next) {
- if (d->log_fd != -1)
- close(d->log_fd);
- d->log_fd = create_domain_log(d);
+ struct console *con = &d->console;
+
+ if (con->log_fd != -1)
+ close(con->log_fd);
+ con->log_fd = create_domain_log(d);
}
}
@@ -1059,6 +1081,8 @@ void handle_io(void)
/* Re-calculate any event counter allowances & unblock
domains with new allowance */
for (d = dom_head; d; d = d->next) {
+ struct console *con = &d->console;
+
/* CS 16257:955ee4fa1345 introduces a 5ms fuzz
* for select(), it is not clear poll() has
* similar behavior (returning a couple of ms
@@ -1068,13 +1092,15 @@ void handle_io(void)
if ((now+5) > d->next_period) {
d->next_period = now + RATE_LIMIT_PERIOD;
if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
- (void)xenevtchn_unmask(d->xce_handle, d->local_port);
+ (void)xenevtchn_unmask(d->xce_handle, con->local_port);
}
d->event_count = 0;
}
}
for (d = dom_head; d; d = d->next) {
+ struct console *con = &d->console;
+
if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
/* Determine if we're going to be the next time slice to expire */
if (!next_timeout ||
@@ -1082,25 +1108,25 @@ void handle_io(void)
next_timeout = d->next_period;
} else if (d->xce_handle != NULL) {
if (discard_overflowed_data ||
- !d->buffer.max_capacity ||
- d->buffer.size < d->buffer.max_capacity) {
+ !con->buffer.max_capacity ||
+ con->buffer.size < con->buffer.max_capacity) {
int evtchn_fd = xenevtchn_fd(d->xce_handle);
d->xce_pollfd_idx = set_fds(evtchn_fd,
POLLIN|POLLPRI);
}
}
- if (d->master_fd != -1) {
+ if (con->master_fd != -1) {
short events = 0;
if (!d->is_dead && ring_free_bytes(d))
events |= POLLIN;
- if (!buffer_empty(&d->buffer))
+ if (!buffer_empty(&con->buffer))
events |= POLLOUT;
if (events)
- d->master_pollfd_idx =
- set_fds(d->master_fd,
+ con->master_pollfd_idx =
+ set_fds(con->master_fd,
events|POLLPRI);
}
}
@@ -1159,6 +1185,8 @@ void handle_io(void)
}
for (d = dom_head; d; d = n) {
+ struct console *con = &d->console;
+
n = d->next;
if (d->event_count < RATE_LIMIT_ALLOWANCE) {
if (d->xce_handle != NULL &&
@@ -1170,22 +1198,22 @@ void handle_io(void)
handle_ring_read(d);
}
- if (d->master_fd != -1 && d->master_pollfd_idx != -1) {
- if (fds[d->master_pollfd_idx].revents &
+ if (con->master_fd != -1 && con->master_pollfd_idx != -1) {
+ if (fds[con->master_pollfd_idx].revents &
~(POLLIN|POLLOUT|POLLPRI))
domain_handle_broken_tty(d,
domain_is_valid(d->domid));
else {
- if (fds[d->master_pollfd_idx].revents &
+ if (fds[con->master_pollfd_idx].revents &
POLLIN)
handle_tty_read(d);
- if (fds[d->master_pollfd_idx].revents &
+ if (fds[con->master_pollfd_idx].revents &
POLLOUT)
handle_tty_write(d);
}
}
- d->xce_pollfd_idx = d->master_pollfd_idx = -1;
+ d->xce_pollfd_idx = con->master_pollfd_idx = -1;
if (d->last_seen != enum_pass)
shutdown_domain(d);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-06-06 17:26 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-06 17:25 [PATCH 00/14 v4] PL011 emulation support in Xen Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 01/14 v4] xen/arm: vpl011: Move vgic register access functions to vreg.h Bhupinder Thakur
2017-06-09 12:49 ` Julien Grall
2017-06-06 17:25 ` [PATCH 02/14 v4] xen/arm: vpl011: Define generic vreg_reg* access functions in vreg.h Bhupinder Thakur
2017-06-09 12:54 ` Julien Grall
2017-06-19 9:33 ` Andre Przywara
2017-06-19 16:53 ` Bhupinder Thakur
2017-06-19 16:59 ` Andre Przywara
2017-06-06 17:25 ` [PATCH 03/14 v4] xen/arm: vpl011: Add pl011 uart emulation in Xen Bhupinder Thakur
2017-06-06 23:02 ` Stefano Stabellini
2017-06-09 13:15 ` Julien Grall
2017-06-09 18:02 ` Stefano Stabellini
2017-06-13 8:58 ` Bhupinder Thakur
2017-06-13 9:25 ` Julien Grall
2017-06-09 13:54 ` Julien Grall
2017-06-13 10:57 ` Bhupinder Thakur
2017-06-13 12:44 ` Julien Grall
2017-06-13 17:50 ` Stefano Stabellini
2017-06-14 5:47 ` Bhupinder Thakur
2017-06-14 9:33 ` Julien Grall
2017-06-19 10:14 ` Andre Przywara
2017-06-22 5:16 ` Bhupinder Thakur
2017-06-23 12:45 ` Julien Grall
2017-06-06 17:25 ` [PATCH 04/14 v4] xen/arm: vpl011: Add support for vuart in libxl Bhupinder Thakur
2017-06-06 23:07 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 05/14 v4] xen/arm: vpl011: Allocate a new GFN in the toolstack for vuart Bhupinder Thakur
2017-06-06 23:17 ` Stefano Stabellini
2017-06-07 16:43 ` Wei Liu
2017-06-06 17:25 ` [PATCH 06/14 v4] xen/arm: vpl011: Add a new domctl API to initialize vpl011 Bhupinder Thakur
2017-06-06 23:26 ` Stefano Stabellini
2017-06-09 14:06 ` Julien Grall
2017-06-09 18:32 ` Stefano Stabellini
2017-06-14 7:35 ` Bhupinder Thakur
2017-06-14 8:34 ` Bhupinder Thakur
2017-06-09 14:13 ` Julien Grall
2017-06-14 9:16 ` Bhupinder Thakur
2017-06-14 10:15 ` Julien Grall
2017-06-15 6:33 ` Bhupinder Thakur
2017-06-19 10:59 ` Bhupinder Thakur
2017-06-19 11:01 ` Julien Grall
2017-06-19 11:47 ` Wei Liu
2017-06-19 13:11 ` Bhupinder Thakur
2017-06-20 11:16 ` Julien Grall
2017-06-20 11:42 ` Wei Liu
2017-06-21 10:18 ` Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 07/14 v4] xen/arm: vpl011: Add a new vuart node in the xenstore Bhupinder Thakur
2017-06-06 23:38 ` Stefano Stabellini
2017-06-06 17:25 ` Bhupinder Thakur [this message]
2017-06-07 1:13 ` [PATCH 08/14 v4] xen/arm: vpl011: Modify xenconsole to define and use a new console structure Stefano Stabellini
2017-06-06 17:25 ` [PATCH 09/14 v4] xen/arm: vpl011: Modify xenconsole functions to take console structure as input Bhupinder Thakur
2017-06-07 0:43 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 10/14 v4] xen/arm: vpl011: Modify xenconsole to support multiple consoles Bhupinder Thakur
2017-06-07 1:03 ` Stefano Stabellini
2017-06-07 3:51 ` Bhupinder Thakur
2017-06-07 16:46 ` Wei Liu
2017-06-07 17:54 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 11/14 v4] xen/arm: vpl011: Add support for vuart console in xenconsole Bhupinder Thakur
2017-06-07 1:08 ` Stefano Stabellini
2017-06-07 16:44 ` Wei Liu
2017-06-06 17:25 ` [PATCH 12/14 v4] xen/arm: vpl011: Add a new vuart console type to xenconsole client Bhupinder Thakur
2017-06-06 23:41 ` Stefano Stabellini
2017-06-06 17:25 ` [PATCH 13/14 v4] xen/arm: vpl011: Add a pl011 uart DT node in the guest device tree Bhupinder Thakur
2017-06-06 17:25 ` [PATCH 14/14 v4] xen/arm: vpl011: Update documentation for vuart console support Bhupinder Thakur
2017-06-09 13:58 ` [PATCH 00/14 v4] PL011 emulation support in Xen Julien Grall
-- strict thread matches above, loose matches on Subject: below --
2017-06-06 10:03 [PATCH 08/14 v4] xen/arm: vpl011: Modify xenconsole to define and use a new console structure Bhupinder Thakur
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=1496769929-23355-9-git-send-email-bhupinder.thakur@linaro.org \
--to=bhupinder.thakur@linaro.org \
--cc=ian.jackson@eu.citrix.com \
--cc=julien.grall@arm.com \
--cc=sstabellini@kernel.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/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 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).