Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Jan 2013 07:33:48 +0000 (UTC)
From:      Peter Grehan <grehan@svn.freebsd.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r245127 - projects/bhyve/usr.sbin/bhyve
Message-ID:  <50ea7a5c.19f3.7682b587@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grehan
Date: Mon Jan  7 07:33:48 2013
New Revision: 245127
URL: http://svnweb.freebsd.org/changeset/base/245127

Log:
  Don't completely drain the read file descriptor. Instead, only
  fill up to the uart's rx fifo size, and leave any remaining input
  for when the rx fifo is read. This allows cut'n'paste of long lines
  to be done into the bhyve console without truncation.
  
  Also, introduce a mutex since the file input will run in the mevent
  thread context and may corrupt state accessed by a vCPU thread.
  
  Reviewed by:	neel
  Approved by:	NetApp

Modified:
  projects/bhyve/usr.sbin/bhyve/pci_uart.c

Modified: projects/bhyve/usr.sbin/bhyve/pci_uart.c
==============================================================================
--- projects/bhyve/usr.sbin/bhyve/pci_uart.c	Mon Jan  7 07:30:41 2013	(r245126)
+++ projects/bhyve/usr.sbin/bhyve/pci_uart.c	Mon Jan  7 07:33:48 2013	(r245127)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 #include <stdbool.h>
 #include <string.h>
+#include <pthread.h>
 
 #include "bhyverun.h"
 #include "pci_emul.h"
@@ -97,6 +98,7 @@ struct fifo {
 
 struct pci_uart_softc {
 	struct pci_devinst *pi;
+	pthread_mutex_t mtx;	/* protects all softc elements */
 	uint8_t data;		/* Data register (R/W) */
 	uint8_t ier;		/* Interrupt enable register (R/W) */
 	uint8_t lcr;		/* Line control register (R/W) */
@@ -214,6 +216,13 @@ fifo_numchars(struct fifo *fifo)
 	return (fifo->num);
 }
 
+static int
+fifo_available(struct fifo *fifo)
+{
+
+	return (fifo->num < fifo->size);
+}
+
 static void
 pci_uart_opentty(struct pci_uart_softc *sc)
 {
@@ -304,19 +313,25 @@ pci_uart_drain(int fd, enum ev_type ev, 
 
 	assert(fd == STDIN_FILENO);
 	assert(ev == EVF_READ);
+	
+	/*
+	 * This routine is called in the context of the mevent thread
+	 * to take out the softc lock to protect against concurrent
+	 * access from a vCPU i/o exit
+	 */
+	pthread_mutex_lock(&sc->mtx);
 
-	while ((ch = ttyread()) != -1) {
-		/*
-		 * If we are in loopback mode then drop this character.
-		 */
-		if ((sc->mcr & MCR_LOOPBACK) != 0)
-			continue;
-
-		if (fifo_putchar(&sc->rxfifo, ch) != 0)
-			sc->lsr |= LSR_OE;
+	if ((sc->mcr & MCR_LOOPBACK) != 0) {
+		(void) ttyread();
+	} else {
+		while (fifo_available(&sc->rxfifo) &&
+		       ((ch = ttyread()) != -1)) {
+			fifo_putchar(&sc->rxfifo, ch);
+		}
+		pci_uart_toggle_intr(sc);
 	}
 
-	pci_uart_toggle_intr(sc);
+	pthread_mutex_unlock(&sc->mtx);
 }
 
 static void
@@ -337,6 +352,8 @@ pci_uart_write(struct vmctx *ctx, int vc
 		pci_uart_opentty(sc);
 		sc->opened = 1;
 	}
+
+	pthread_mutex_lock(&sc->mtx);
 	
 	/*
 	 * Take care of the special case DLAB accesses first
@@ -458,6 +475,7 @@ pci_uart_write(struct vmctx *ctx, int vc
 
 done:
 	pci_uart_toggle_intr(sc);
+	pthread_mutex_unlock(&sc->mtx);
 }
 
 uint64_t
@@ -479,6 +497,8 @@ pci_uart_read(struct vmctx *ctx, int vcp
 		sc->opened = 1;
 	}
 
+	pthread_mutex_lock(&sc->mtx);
+
 	/*
 	 * Take care of the special case DLAB accesses first
 	 */
@@ -554,6 +574,8 @@ pci_uart_read(struct vmctx *ctx, int vcp
 
 done:
 	pci_uart_toggle_intr(sc);
+	pthread_mutex_unlock(&sc->mtx);
+
 	return (reg);
 }
 
@@ -570,6 +592,8 @@ pci_uart_init(struct vmctx *ctx, struct 
 	pi->pi_arg = sc;
 	sc->pi = pi;
 
+	pthread_mutex_init(&sc->mtx, NULL);
+
 	/* initialize config space */
 	pci_set_cfgdata16(pi, PCIR_DEVICE, COM_DEV);
 	pci_set_cfgdata16(pi, PCIR_VENDOR, COM_VENDOR);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50ea7a5c.19f3.7682b587>