diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 0cd1fee..b9be5a5 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -164,11 +164,39 @@ static int write_with_timestamp(int fd, const char *data, size_t sz,
 	return 0;
 }
 
-static void buffer_append(struct domain *dom)
+/*
+ * This function checks if the data is allowed to be buffered for that console.
+ * If not then it marks it pending for later receiving.
+ */
+static bool buffer_available(struct domain *dom, int console_type)
+{
+	if (discard_overflowed_data ||
+		!dom->buffer[console_type].max_capacity ||
+		dom->buffer[console_type].size < dom->buffer[console_type].max_capacity)
+	{
+		dom->console_data_pending &= ~(1<<console_type);
+		return true;
+	}
+	else
+	{
+		dom->console_data_pending |= (1<<console_type);
+		return false;
+	}
+}
+
+static void buffer_append(struct domain *dom, int console_type)
 {
-	struct buffer *buffer = &dom->buffer;
+	struct buffer *buffer = &dom->buffer[console_type];
+	struct xencons_interface *intf=dom->interface[console_type];
+	xenevtchn_port_or_error_t port=dom->local_port[console_type];
+
 	XENCONS_RING_IDX cons, prod, size;
-	struct xencons_interface *intf = dom->interface;
+
+	/*
+	 * check if more data is allowed to be buffered
+	 */
+	if (!buffer_available(dom, console_type))
+		return;
 
 	cons = intf->out_cons;
 	prod = intf->out_prod;
@@ -193,22 +221,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, 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 (dom->log_fd[console_type] != -1) {
 		int logret;
 		if (log_time_guest) {
 			logret = write_with_timestamp(
-				dom->log_fd,
+				dom->log_fd[console_type],
 				buffer->data + buffer->size - size,
 				size, &log_time_guest_needts);
 		} else {
 			logret = write_all(
-				dom->log_fd,
+				dom->log_fd[console_type],
 				buffer->data + buffer->size - size,
 				size);
 		}
@@ -296,12 +324,13 @@ static int create_hv_log(void)
 	return fd;
 }
 
-static int create_domain_log(struct domain *dom)
+static int create_domain_log(struct domain *dom, int console_type)
 {
 	char logfile[PATH_MAX];
 	char *namepath, *data, *s;
 	int fd;
 	unsigned int len;
+	char *console_name[]={"pv", "vcon"};
 
 	namepath = xs_get_domain_path(xs, dom->domid);
 	s = realloc(namepath, strlen(namepath) + 6);
@@ -320,7 +349,7 @@ static int create_domain_log(struct domain *dom)
 		return -1;
 	}
 
-	snprintf(logfile, PATH_MAX-1, "%s/guest-%s.log", log_dir, data);
+	snprintf(logfile, PATH_MAX-1, "%s/guest-%s-%s.log", log_dir, console_name[console_type], data);
 	free(data);
 	logfile[PATH_MAX-1] = '\0';
 
@@ -344,14 +373,24 @@ 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;
+	if (dom->master_fd[CONSOLE_TYPE_PV] != -1) {
+		close(dom->master_fd[CONSOLE_TYPE_PV]);
+		dom->master_fd[CONSOLE_TYPE_PV] = -1;
+	}
+
+	if (dom->slave_fd[CONSOLE_TYPE_PV] != -1) {
+		close(dom->slave_fd[CONSOLE_TYPE_PV]);
+		dom->slave_fd[CONSOLE_TYPE_PV] = -1;
+	}
+
+	if (dom->master_fd[CONSOLE_TYPE_VCON] != -1) {
+		close(dom->master_fd[CONSOLE_TYPE_VCON]);
+		dom->master_fd[CONSOLE_TYPE_VCON] = -1;
 	}
 
-	if (dom->slave_fd != -1) {
-		close(dom->slave_fd);
-		dom->slave_fd = -1;
+	if (dom->slave_fd[CONSOLE_TYPE_VCON] != -1) {
+		close(dom->slave_fd[CONSOLE_TYPE_VCON]);
+		dom->slave_fd[CONSOLE_TYPE_VCON] = -1;
 	}
 }
 
@@ -424,63 +463,86 @@ static int domain_create_tty(struct domain *dom)
 	char *data;
 	unsigned int len;
 	struct termios term;
+	int console_type=0;
 
-	assert(dom->slave_fd == -1);
-	assert(dom->master_fd == -1);
+	assert(dom->master_fd[CONSOLE_TYPE_PV] == -1);
+	assert(dom->slave_fd[CONSOLE_TYPE_PV] == -1);
+	assert(dom->master_fd[CONSOLE_TYPE_VCON] == -1);
+	assert(dom->slave_fd[CONSOLE_TYPE_VCON] == -1);
 
-	if (openpty(&dom->master_fd, &dom->slave_fd, NULL, NULL, NULL) < 0) {
-		err = errno;
-		dolog(LOG_ERR, "Failed to create tty for domain-%d "
-		      "(errno = %i, %s)",
-		      dom->domid, err, strerror(err));
-		return 0;
-	}
+	/*
+	 * Open pty for both PV and vcon consoles.
+	 */
+	for (console_type=0; console_type<MAX_CONSOLE; console_type++)
+	{
+		if (openpty(&dom->master_fd[console_type], &dom->slave_fd[console_type], NULL, NULL, NULL) < 0) {
+			err = errno;
+			dolog(LOG_ERR, "Failed to create tty for domain-%d "
+				  "(errno = %i, %s)",
+				  dom->domid, err, strerror(err));
+			return 0;
+		}
 
-	if (tcgetattr(dom->slave_fd, &term) < 0) {
-		err = errno;
-		dolog(LOG_ERR, "Failed to get tty attributes for domain-%d "
-			"(errno = %i, %s)",
-			dom->domid, err, strerror(err));
-		goto out;
-	}
-	cfmakeraw(&term);
-	if (tcsetattr(dom->slave_fd, TCSANOW, &term) < 0) {
-		err = errno;
-		dolog(LOG_ERR, "Failed to set tty attributes for domain-%d "
-			"(errno = %i, %s)",
-			dom->domid, err, strerror(err));
-		goto out;
-	}
+		if (tcgetattr(dom->slave_fd[console_type], &term) < 0) {
+			err = errno;
+			dolog(LOG_ERR, "Failed to get tty attributes for domain-%d "
+				"(errno = %i, %s)",
+				dom->domid, err, strerror(err));
+			goto out;
+		}
+		cfmakeraw(&term);
+		if (tcsetattr(dom->slave_fd[console_type], TCSANOW, &term) < 0) {
+			err = errno;
+			dolog(LOG_ERR, "Failed to set tty attributes for domain-%d "
+				"(errno = %i, %s)",
+				dom->domid, err, strerror(err));
+			goto out;
+		}
 
-	if ((slave = ptsname(dom->master_fd)) == NULL) {
-		err = errno;
-		dolog(LOG_ERR, "Failed to get slave name for domain-%d "
-		      "(errno = %i, %s)",
-		      dom->domid, err, strerror(err));
-		goto out;
-	}
+		if ((slave = ptsname(dom->master_fd[console_type])) == NULL) {
+			err = errno;
+			dolog(LOG_ERR, "Failed to get slave name for domain-%d "
+				  "(errno = %i, %s)",
+				  dom->domid, err, strerror(err));
+			goto out;
+		}
 
-	success = asprintf(&path, "%s/limit", dom->conspath) !=
-		-1;
-	if (!success)
-		goto out;
-	data = xs_read(xs, XBT_NULL, path, &len);
-	if (data) {
-		dom->buffer.max_capacity = strtoul(data, 0, 0);
-		free(data);
+		/*
+		 * Initialize the console buffer capacity.
+		 */
+		success = asprintf(&path, "%s/limit", dom->conspath) !=
+			-1;
+		if (!success)
+			goto out;
+		data = xs_read(xs, XBT_NULL, path, &len);
+		if (data) {
+			dom->buffer[console_type].max_capacity = strtoul(data, 0, 0);
+			free(data);
+		}
+		free(path);
+
+		/*
+		 * Write console slave name to xen store.
+		 */
+		if (console_type == CONSOLE_TYPE_VCON)
+			success = (asprintf(&path, "%s/vtty", dom->conspath) != -1);
+		else
+			success = (asprintf(&path, "%s/tty", dom->conspath) != -1);
+
+		if (!success)
+			goto out;
+		success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
+		free(path);
+
+		if (fcntl(dom->master_fd[console_type], F_SETFL, O_NONBLOCK) == -1)
+			goto out;
+
+		if (!dom->vcon_enabled)
+			break;
 	}
-	free(path);
 
-	success = (asprintf(&path, "%s/tty", dom->conspath) != -1);
 	if (!success)
 		goto out;
-	success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
-	free(path);
-	if (!success)
-		goto out;
-
-	if (fcntl(dom->master_fd, F_SETFL, O_NONBLOCK) == -1)
-		goto out;
 
 	return 1;
 out:
@@ -523,21 +585,53 @@ static int xs_gather(struct xs_handle *xs, const char *dir, ...)
 	return ret;
 }
 
-static void domain_unmap_interface(struct domain *dom)
+static void domain_unmap_interface(struct domain *dom, int console_type)
 {
-	if (dom->interface == NULL)
+	if (dom->interface[console_type] == NULL)
 		return;
-	if (xgt_handle && dom->ring_ref == -1)
-		xengnttab_unmap(xgt_handle, dom->interface, 1);
+	if (xgt_handle && dom->ring_ref[console_type] == -1)
+		xengnttab_unmap(xgt_handle, dom->interface[console_type], 1);
 	else
-		munmap(dom->interface, XC_PAGE_SIZE);
-	dom->interface = NULL;
-	dom->ring_ref = -1;
+		munmap(dom->interface[console_type], XC_PAGE_SIZE);
+	dom->interface[console_type] = NULL;
+	dom->ring_ref[console_type] = -1;
+}
+
+static int bind_event_channel(struct domain *dom, int new_rport, int *lport, int *rport)
+{
+	int err = 0, rc;
+
+	/* Go no further if port has not changed and we are still bound. */
+	if (new_rport == *rport) {
+		xc_evtchn_status_t status = {
+		.dom = DOMID_SELF,
+		.port = *lport };
+		if ((xc_evtchn_status(xc, &status) == 0) &&
+			(status.status == EVTCHNSTAT_interdomain))
+			goto out;
+	}
+
+	*lport = -1;
+	*rport = -1;
+	rc = xenevtchn_bind_interdomain(dom->xce_handle,
+									dom->domid, new_rport);
+
+	if (rc == -1) {
+		err = errno;
+		xenevtchn_close(dom->xce_handle);
+		dom->xce_handle = NULL;
+		goto out;
+	}
+
+	*lport = rc;
+	*rport = new_rport;
+out:
+	return err;
 }
  
 static int domain_create_ring(struct domain *dom)
 {
-	int err, remote_port, ring_ref, rc;
+	int err, remote_port, ring_ref, vcon_remote_port, vcon_ring_ref;
 	char *type, path[PATH_MAX];
 
 	err = xs_gather(xs, dom->conspath,
@@ -547,6 +641,17 @@ static int domain_create_ring(struct domain *dom)
 	if (err)
 		goto out;
 
+	/* vcon console is optional. */
+	err = xs_gather(xs, dom->conspath,
+		"vcon-ring-ref", "%u", &vcon_ring_ref,
+		"vcon-port", "%i", &vcon_remote_port,
+		NULL);
+
+	if (err || vcon_ring_ref == -1)
+		dom->vcon_enabled = false;
+	else
+		dom->vcon_enabled = true;
+
 	snprintf(path, sizeof(path), "%s/type", dom->conspath);
 	type = xs_read(xs, XBT_NULL, path, NULL);
 	if (type && strcmp(type, "xenconsoled") != 0) {
@@ -556,41 +661,51 @@ 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)
-		domain_unmap_interface(dom);
+	if (ring_ref != dom->ring_ref[CONSOLE_TYPE_PV] && dom->ring_ref[CONSOLE_TYPE_PV] != -1)
+		domain_unmap_interface(dom, CONSOLE_TYPE_PV);
+
+	/* If using vcon ring_ref and it has changed, remap */
+	if (dom->vcon_enabled &&
+		vcon_ring_ref != dom->ring_ref[CONSOLE_TYPE_VCON] &&
+		dom->ring_ref[CONSOLE_TYPE_VCON] != -1 )
+		domain_unmap_interface(dom, CONSOLE_TYPE_VCON);
 
-	if (!dom->interface && xgt_handle) {
+	if (!dom->interface[CONSOLE_TYPE_PV] && xgt_handle) {
 		/* Prefer using grant table */
-		dom->interface = xengnttab_map_grant_ref(xgt_handle,
-			dom->domid, GNTTAB_RESERVED_CONSOLE,
-			PROT_READ|PROT_WRITE);
-		dom->ring_ref = -1;
+		dom->interface[CONSOLE_TYPE_PV] = xengnttab_map_grant_ref(xgt_handle,
+																  dom->domid, GNTTAB_RESERVED_CONSOLE,
+																  PROT_READ|PROT_WRITE);
+		dom->ring_ref[CONSOLE_TYPE_PV] = -1;
 	}
-	if (!dom->interface) {
+
+	if (!dom->interface[CONSOLE_TYPE_PV]) {
 		/* Fall back to xc_map_foreign_range */
-		dom->interface = xc_map_foreign_range(
+		dom->interface[CONSOLE_TYPE_PV] = xc_map_foreign_range(
 			xc, dom->domid, XC_PAGE_SIZE,
 			PROT_READ|PROT_WRITE,
 			(unsigned long)ring_ref);
-		if (dom->interface == NULL) {
+		if (dom->interface[CONSOLE_TYPE_PV] == NULL) {
 			err = EINVAL;
 			goto out;
 		}
-		dom->ring_ref = ring_ref;
+		dom->ring_ref[CONSOLE_TYPE_PV] = ring_ref;
 	}
 
-	/* Go no further if port has not changed and we are still bound. */
-	if (remote_port == dom->remote_port) {
-		xc_evtchn_status_t status = {
-			.dom = DOMID_SELF,
-			.port = dom->local_port };
-		if ((xc_evtchn_status(xc, &status) == 0) &&
-		    (status.status == EVTCHNSTAT_interdomain))
+	/* Map vcon console ring buffer. */
+	if (dom->vcon_enabled && !dom->interface[CONSOLE_TYPE_VCON]) {
+
+		/* Fall back to xc_map_foreign_range */
+		dom->interface[CONSOLE_TYPE_VCON] = xc_map_foreign_range(
+		xc, dom->domid, XC_PAGE_SIZE,
+		PROT_READ|PROT_WRITE,
+		(unsigned long)vcon_ring_ref);
+		if ( dom->interface[CONSOLE_TYPE_VCON] == NULL ) {
+			err = EINVAL;
 			goto out;
+		}
+		dom->ring_ref[CONSOLE_TYPE_VCON] = vcon_ring_ref;
 	}
 
-	dom->local_port = -1;
-	dom->remote_port = -1;
 	if (dom->xce_handle != NULL)
 		xenevtchn_close(dom->xce_handle);
 
@@ -602,31 +717,46 @@ static int domain_create_ring(struct domain *dom)
 		goto out;
 	}
  
-	rc = xenevtchn_bind_interdomain(dom->xce_handle,
-		dom->domid, remote_port);
-
-	if (rc == -1) {
-		err = errno;
+	err = bind_event_channel(dom, remote_port,
+							 &dom->local_port[CONSOLE_TYPE_PV],
+							 &dom->remote_port[CONSOLE_TYPE_PV]);
+	if (err)
+	{
 		xenevtchn_close(dom->xce_handle);
-		dom->xce_handle = NULL;
 		goto out;
 	}
-	dom->local_port = rc;
-	dom->remote_port = remote_port;
 
-	if (dom->master_fd == -1) {
+	if (dom->vcon_enabled)
+	{
+		err = bind_event_channel(dom, vcon_remote_port,
+								 &dom->local_port[CONSOLE_TYPE_VCON],
+								 &dom->remote_port[CONSOLE_TYPE_VCON]);
+		if (err)
+		{
+			xenevtchn_close(dom->xce_handle);
+			goto out;
+		}
+	}
+
+	if (dom->master_fd[CONSOLE_TYPE_PV] == -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;
+			dom->local_port[CONSOLE_TYPE_PV] = -1;
+			dom->remote_port[CONSOLE_TYPE_PV] = -1;
+			dom->local_port[CONSOLE_TYPE_VCON] = -1;
+			dom->remote_port[CONSOLE_TYPE_VCON] = -1;
+			dom->vcon_enabled = false;
 			goto out;
 		}
 	}
 
-	if (log_guest && (dom->log_fd == -1))
-		dom->log_fd = create_domain_log(dom);
+	if (log_guest && (dom->log_fd[CONSOLE_TYPE_PV] == -1))
+		dom->log_fd[CONSOLE_TYPE_PV] = create_domain_log(dom, CONSOLE_TYPE_PV);
+
+	if (log_guest && dom->vcon_enabled && (dom->log_fd[CONSOLE_TYPE_VCON] == -1))
+		dom->log_fd[CONSOLE_TYPE_VCON] = create_domain_log(dom, CONSOLE_TYPE_VCON);
 
  out:
 	return err;
@@ -681,17 +811,24 @@ static struct domain *create_domain(int domid)
 	dom->conspath = s;
 	strcat(dom->conspath, "/console");
 
-	dom->master_fd = -1;
-	dom->master_pollfd_idx = -1;
-	dom->slave_fd = -1;
-	dom->log_fd = -1;
+	dom->master_fd[CONSOLE_TYPE_PV] = -1;
+	dom->master_pollfd_idx[CONSOLE_TYPE_PV] = -1;
+	dom->slave_fd[CONSOLE_TYPE_PV] = -1;
+	dom->master_fd[CONSOLE_TYPE_VCON] = -1;
+	dom->master_pollfd_idx[CONSOLE_TYPE_VCON] = -1;
+	dom->slave_fd[CONSOLE_TYPE_VCON] = -1;
+	dom->log_fd[CONSOLE_TYPE_PV] = -1;
+	dom->log_fd[CONSOLE_TYPE_VCON] = -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;
+	dom->ring_ref[CONSOLE_TYPE_PV] = -1;
+	dom->ring_ref[CONSOLE_TYPE_VCON] = -1;
+	dom->local_port[CONSOLE_TYPE_PV] = -1;
+	dom->remote_port[CONSOLE_TYPE_PV] = -1;
+	dom->local_port[CONSOLE_TYPE_VCON] = -1;
+	dom->remote_port[CONSOLE_TYPE_VCON] = -1;
 
 	if (!watch_domain(dom, true))
 		goto out;
@@ -737,13 +874,21 @@ static void cleanup_domain(struct domain *d)
 {
 	domain_close_tty(d);
 
-	if (d->log_fd != -1) {
-		close(d->log_fd);
-		d->log_fd = -1;
+	if (d->log_fd[CONSOLE_TYPE_PV] != -1) {
+		close(d->log_fd[CONSOLE_TYPE_PV]);
+		d->log_fd[CONSOLE_TYPE_PV] = -1;
+	}
+
+	if (d->log_fd[CONSOLE_TYPE_VCON] != -1) {
+		close(d->log_fd[CONSOLE_TYPE_VCON]);
+		d->log_fd[CONSOLE_TYPE_VCON] = -1;
 	}
 
-	free(d->buffer.data);
-	d->buffer.data = NULL;
+	free(d->buffer[CONSOLE_TYPE_PV].data);
+	free(d->buffer[CONSOLE_TYPE_VCON].data);
+
+	d->buffer[CONSOLE_TYPE_PV].data = NULL;
+	d->buffer[CONSOLE_TYPE_VCON].data = NULL;
 
 	free(d->conspath);
 	d->conspath = NULL;
@@ -755,7 +900,8 @@ static void shutdown_domain(struct domain *d)
 {
 	d->is_dead = true;
 	watch_domain(d, false);
-	domain_unmap_interface(d);
+	domain_unmap_interface(d, CONSOLE_TYPE_PV);
+	domain_unmap_interface(d, CONSOLE_TYPE_VCON);
 	if (d->xce_handle != NULL)
 		xenevtchn_close(d->xce_handle);
 	d->xce_handle = NULL;
@@ -786,9 +932,9 @@ static void enum_domains(void)
 	}
 }
 
-static int ring_free_bytes(struct domain *dom)
+static int ring_free_bytes(struct domain *dom, int console_type)
 {
-	struct xencons_interface *intf = dom->interface;
+	struct xencons_interface *intf = dom->interface[console_type];
 	XENCONS_RING_IDX cons, prod, space;
 
 	cons = intf->in_cons;
@@ -813,25 +959,26 @@ static void domain_handle_broken_tty(struct domain *dom, int recreate)
 	}
 }
 
-static void handle_tty_read(struct domain *dom)
+static void handle_tty_read(struct domain *dom, int console_type)
 {
 	ssize_t len = 0;
 	char msg[80];
 	int i;
-	struct xencons_interface *intf = dom->interface;
 	XENCONS_RING_IDX prod;
+	struct xencons_interface *intf=dom->interface[console_type];
+	xenevtchn_port_or_error_t port=dom->local_port[console_type];
 
 	if (dom->is_dead)
 		return;
 
-	len = ring_free_bytes(dom);
+	len = ring_free_bytes(dom, console_type);
 	if (len == 0)
 		return;
 
 	if (len > sizeof(msg))
 		len = sizeof(msg);
 
-	len = read(dom->master_fd, msg, len);
+	len = read(dom->master_fd[console_type], 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
@@ -847,28 +994,29 @@ 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, port);
 	} else {
 		domain_close_tty(dom);
 		shutdown_domain(dom);
 	}
 }
 
-static void handle_tty_write(struct domain *dom)
+static void handle_tty_write(struct domain *dom, int console_type)
 {
 	ssize_t len;
 
 	if (dom->is_dead)
 		return;
 
-	len = write(dom->master_fd, dom->buffer.data + dom->buffer.consumed,
-		    dom->buffer.size - dom->buffer.consumed);
+	len = write(dom->master_fd[console_type],
+				dom->buffer[console_type].data + dom->buffer[console_type].consumed,
+				dom->buffer[console_type].size - dom->buffer[console_type].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(&dom->buffer[console_type], len);
 	}
 }
 
@@ -884,7 +1032,10 @@ static void handle_ring_read(struct domain *dom)
 
 	dom->event_count++;
 
-	buffer_append(dom);
+	if (port == dom->local_port[CONSOLE_TYPE_VCON])
+		buffer_append(dom, CONSOLE_TYPE_VCON);
+	else
+		buffer_append(dom, CONSOLE_TYPE_PV);
 
 	if (dom->event_count < RATE_LIMIT_ALLOWANCE)
 		(void)xenevtchn_unmask(dom->xce_handle, port);
@@ -954,9 +1105,16 @@ 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);
+			if (d->log_fd[CONSOLE_TYPE_PV] != -1)
+				close(d->log_fd[CONSOLE_TYPE_PV]);
+			d->log_fd[CONSOLE_TYPE_PV] = create_domain_log(d, CONSOLE_TYPE_PV);
+
+			if (d->vcon_enabled)
+			{
+				if (d->log_fd[CONSOLE_TYPE_VCON] != -1)
+					close(d->log_fd[CONSOLE_TYPE_VCON]);
+				d->log_fd[CONSOLE_TYPE_PV] = create_domain_log(d, CONSOLE_TYPE_VCON);
+			}
 		}
 	}
 
@@ -1074,7 +1232,9 @@ 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, d->local_port[CONSOLE_TYPE_PV]);
+					if (d->vcon_enabled)
+						(void)xenevtchn_unmask(d->xce_handle, d->local_port[CONSOLE_TYPE_VCON]);
 				}
 				d->event_count = 0;
 			}
@@ -1087,27 +1247,47 @@ void handle_io(void)
 				    d->next_period < next_timeout)
 					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) {
+
+				if (buffer_available(d, CONSOLE_TYPE_PV)) {
+					int evtchn_fd = xenevtchn_fd(d->xce_handle);
+					d->xce_pollfd_idx = set_fds(evtchn_fd,
+												POLLIN|POLLPRI);
+				}
+
+				if (buffer_available(d, CONSOLE_TYPE_VCON ) )
+				{
 					int evtchn_fd = xenevtchn_fd(d->xce_handle);
 					d->xce_pollfd_idx = set_fds(evtchn_fd,
-								    POLLIN|POLLPRI);
+												POLLIN|POLLPRI);
 				}
 			}
 
-			if (d->master_fd != -1) {
+			if (d->master_fd[CONSOLE_TYPE_PV] != -1) {
 				short events = 0;
-				if (!d->is_dead && ring_free_bytes(d))
+				if (!d->is_dead && ring_free_bytes(d, CONSOLE_TYPE_PV))
 					events |= POLLIN;
 
-				if (!buffer_empty(&d->buffer))
+				if (!buffer_empty(&d->buffer[CONSOLE_TYPE_PV]))
 					events |= POLLOUT;
 
 				if (events)
-					d->master_pollfd_idx =
-						set_fds(d->master_fd,
-							events|POLLPRI);
+					d->master_pollfd_idx[CONSOLE_TYPE_PV] =
+						set_fds(d->master_fd[CONSOLE_TYPE_PV],
+								events|POLLPRI);
+			}
+
+			if (d->vcon_enabled && d->master_fd[CONSOLE_TYPE_VCON] != -1) {
+				short events = 0;
+				if (!d->is_dead && ring_free_bytes(d, CONSOLE_TYPE_VCON))
+					events |= POLLIN;
+
+				if (!buffer_empty(&d->buffer[CONSOLE_TYPE_VCON]))
+					events |= POLLOUT;
+
+				if (events)
+					d->master_pollfd_idx[CONSOLE_TYPE_VCON] =
+						set_fds(d->master_fd[CONSOLE_TYPE_VCON],
+								events|POLLPRI);
 			}
 		}
 
@@ -1166,6 +1346,16 @@ void handle_io(void)
 
 		for (d = dom_head; d; d = n) {
 			n = d->next;
+
+			/*
+			 * Check if the data pending flag is set for any of the consoles.
+			 * If yes then service those first.
+			 */
+			if ( d->console_data_pending & (1<<CONSOLE_TYPE_PV) )
+				buffer_append(d, CONSOLE_TYPE_PV);
+			else if ( d->console_data_pending & (1<<CONSOLE_TYPE_VCON) )
+				buffer_append(d, CONSOLE_TYPE_VCON);
+
 			if (d->event_count < RATE_LIMIT_ALLOWANCE) {
 				if (d->xce_handle != NULL &&
 				    d->xce_pollfd_idx != -1 &&
@@ -1176,22 +1366,36 @@ 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 (d->master_fd[CONSOLE_TYPE_PV] != -1 && d->master_pollfd_idx[CONSOLE_TYPE_PV] != -1) {
+				if (fds[d->master_pollfd_idx[CONSOLE_TYPE_PV]].revents &
+				    ~(POLLIN|POLLOUT|POLLPRI))
+					domain_handle_broken_tty(d, domain_is_valid(d->domid));
+				else {
+					if (fds[d->master_pollfd_idx[CONSOLE_TYPE_PV]].revents &
+					    POLLIN)
+						handle_tty_read(d, CONSOLE_TYPE_PV);
+					if (fds[d->master_pollfd_idx[CONSOLE_TYPE_PV]].revents &
+					    POLLOUT)
+						handle_tty_write(d, CONSOLE_TYPE_PV);
+				}
+			}
+
+			if (d->master_fd[CONSOLE_TYPE_VCON] != -1 && d->master_pollfd_idx[CONSOLE_TYPE_VCON] != -1) {
+				if (fds[d->master_pollfd_idx[CONSOLE_TYPE_VCON]].revents &
 				    ~(POLLIN|POLLOUT|POLLPRI))
-					domain_handle_broken_tty(d,
-						   domain_is_valid(d->domid));
+					domain_handle_broken_tty(d, domain_is_valid(d->domid));
 				else {
-					if (fds[d->master_pollfd_idx].revents &
+					if (fds[d->master_pollfd_idx[CONSOLE_TYPE_VCON]].revents &
 					    POLLIN)
-						handle_tty_read(d);
-					if (fds[d->master_pollfd_idx].revents &
+						handle_tty_read(d, CONSOLE_TYPE_VCON);
+					if (fds[d->master_pollfd_idx[CONSOLE_TYPE_VCON]].revents &
 					    POLLOUT)
-						handle_tty_write(d);
+						handle_tty_write(d, CONSOLE_TYPE_VCON);
 				}
 			}
 
-			d->xce_pollfd_idx = d->master_pollfd_idx = -1;
+			d->xce_pollfd_idx = d->master_pollfd_idx[CONSOLE_TYPE_PV] =
+									d->master_pollfd_idx[CONSOLE_TYPE_VCON] = -1;
 
 			if (d->last_seen != enum_pass)
 				shutdown_domain(d);
