svn commit: r259301 - in stable/10/usr.sbin: bhyve bhyveload

Peter Grehan grehan at FreeBSD.org
Fri Dec 13 06:59:21 UTC 2013


Author: grehan
Date: Fri Dec 13 06:59:18 2013
New Revision: 259301
URL: http://svnweb.freebsd.org/changeset/base/259301

Log:
  MFC r256657,r257018,r257347,r257423,r257729,r257767,
      r257933,r258609,r258614,r258668,r258673,r258855
  
  Pull in some minor bugfixes and functionality enhancements
  from CURRENT. These are candidates to be moved to 10.0-release.
  
  r258855
  mdoc: quote string properly.
  
  r258673
  Don't create an initial value for the host filesystem of "/".
  
  r258668
  Allow bhyve and bhyveload to attach to tty devices.
  
  r258614
  The 22-bit Data Byte Count (DBC) field of a Physical Region Descriptor was
  being read as a 32-bit quantity by the bhyve AHCI driver.
  
  r258609
  Fix discrepancy between the IOAPIC ID advertised by firmware tables and the
  actual value read by the guest.
  
  r257933
  Route the legacy timer interrupt (IRQ0) to pin 2 of the IOAPIC.
  
  r257767
  Fix an off-by-one error when iterating over the emulated PCI BARs.
  
  r257729
  Add the VM name to the process name with setproctitle().
  
  r257423
  Make the virtual ioapic available unconditionally in a bhyve virtual machine.
  
  r257347
  Update copyright to include the author of the LPC bridge emulation code.
  
  hand-merge r257018
  Tidy usage messages for bhyve and bhyveload.
  
  r256657
  Add an option to bhyveload(8) that allows setting a loader environment variable
  from the command line.
  
  Discussed with:	neel

Modified:
  stable/10/usr.sbin/bhyve/acpi.c
  stable/10/usr.sbin/bhyve/acpi.h
  stable/10/usr.sbin/bhyve/bhyverun.c
  stable/10/usr.sbin/bhyve/block_if.c
  stable/10/usr.sbin/bhyve/mevent.c
  stable/10/usr.sbin/bhyve/mptbl.c
  stable/10/usr.sbin/bhyve/mptbl.h
  stable/10/usr.sbin/bhyve/pci_ahci.c
  stable/10/usr.sbin/bhyve/pci_emul.c
  stable/10/usr.sbin/bhyve/pci_virtio_net.c
  stable/10/usr.sbin/bhyve/pit_8254.c
  stable/10/usr.sbin/bhyve/uart_emul.c
  stable/10/usr.sbin/bhyveload/bhyveload.8
  stable/10/usr.sbin/bhyveload/bhyveload.c

Modified: stable/10/usr.sbin/bhyve/acpi.c
==============================================================================
--- stable/10/usr.sbin/bhyve/acpi.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/acpi.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -253,13 +253,23 @@ basl_fwrite_madt(FILE *fp)
 	EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n");
 	EFPRINTF(fp, "[0001]\t\tLength : 0C\n");
 	/* iasl expects a hex value for the i/o apic id */
-	EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", basl_ncpu);
+	EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", 0);
 	EFPRINTF(fp, "[0001]\t\tReserved : 00\n");
 	EFPRINTF(fp, "[0004]\t\tAddress : fec00000\n");
 	EFPRINTF(fp, "[0004]\t\tInterrupt : 00000000\n");
 	EFPRINTF(fp, "\n");
 
-	/* Override the 8259 chained vector. XXX maybe not needed */
+	/* Legacy IRQ0 is connected to pin 2 of the IOAPIC */
+	EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n");
+	EFPRINTF(fp, "[0001]\t\tLength : 0A\n");
+	EFPRINTF(fp, "[0001]\t\tBus : 00\n");
+	EFPRINTF(fp, "[0001]\t\tSource : 00\n");
+	EFPRINTF(fp, "[0004]\t\tInterrupt : 00000002\n");
+	EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n");
+	EFPRINTF(fp, "\t\t\tPolarity : 1\n");
+	EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n");
+	EFPRINTF(fp, "\n");
+
 	EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n");
 	EFPRINTF(fp, "[0001]\t\tLength : 0A\n");
 	EFPRINTF(fp, "[0001]\t\tBus : 00\n");
@@ -806,7 +816,7 @@ static struct {
 };
 
 int
-acpi_build(struct vmctx *ctx, int ncpu, int ioapic)
+acpi_build(struct vmctx *ctx, int ncpu)
 {
 	int err;
 	int i;
@@ -814,11 +824,6 @@ acpi_build(struct vmctx *ctx, int ncpu, 
 	err = 0;
 	basl_ncpu = ncpu;
 
-	if (!ioapic) {
-		fprintf(stderr, "ACPI tables require an ioapic\n");
-		return (EINVAL);
-	}
-
 	/*
 	 * For debug, allow the user to have iasl compiler output sent
 	 * to stdout rather than /dev/null

Modified: stable/10/usr.sbin/bhyve/acpi.h
==============================================================================
--- stable/10/usr.sbin/bhyve/acpi.h	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/acpi.h	Fri Dec 13 06:59:18 2013	(r259301)
@@ -29,6 +29,6 @@
 #ifndef _ACPI_H_
 #define _ACPI_H_
 
-int	acpi_build(struct vmctx *ctx, int ncpu, int ioapic);
+int	acpi_build(struct vmctx *ctx, int ncpu);
 
 #endif /* _ACPI_H_ */

Modified: stable/10/usr.sbin/bhyve/bhyverun.c
==============================================================================
--- stable/10/usr.sbin/bhyve/bhyverun.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/bhyverun.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -132,7 +132,6 @@ usage(int code)
 		"       -c: # cpus (default 1)\n"
 		"       -p: pin vcpu 'n' to host cpu 'pincpu + n'\n"
 		"       -H: vmexit from the guest on hlt\n"
-		"       -I: present an ioapic to the guest\n"
 		"       -P: vmexit from the guest on pause\n"
 		"       -W: force virtio to use single-vector MSI\n"
 		"       -e: exit on unhandled I/O access\n"
@@ -191,7 +190,7 @@ fbsdrun_start_thread(void *param)
 	mtp = param;
 	vcpu = mtp->mt_vcpu;
 
-	snprintf(tname, sizeof(tname), "%s vcpu %d", vmname, vcpu);
+	snprintf(tname, sizeof(tname), "vcpu %d", vcpu);
 	pthread_set_name_np(mtp->mt_thr, tname);
 
 	vm_loop(mtp->mt_ctx, vcpu, vmexit[vcpu].rip);
@@ -543,7 +542,7 @@ fbsdrun_set_capabilities(struct vmctx *c
 int
 main(int argc, char *argv[])
 {
-	int c, error, gdb_port, err, ioapic, bvmcons;
+	int c, error, gdb_port, err, bvmcons;
 	int max_vcpus;
 	struct vmctx *ctx;
 	uint64_t rip;
@@ -553,7 +552,6 @@ main(int argc, char *argv[])
 	progname = basename(argv[0]);
 	gdb_port = 0;
 	guest_ncpus = 1;
-	ioapic = 0;
 	memsize = 256 * MB;
 
 	while ((c = getopt(argc, argv, "abehAHIPWp:g:c:s:S:m:l:")) != -1) {
@@ -601,7 +599,13 @@ main(int argc, char *argv[])
 			guest_vmexit_on_hlt = 1;
 			break;
 		case 'I':
-			ioapic = 1;
+			/*
+			 * The "-I" option was used to add an ioapic to the
+			 * virtual machine.
+			 *
+			 * An ioapic is now provided unconditionally for each
+			 * virtual machine and this option is now deprecated.
+			 */
 			break;
 		case 'P':
 			guest_vmexit_on_pause = 1;
@@ -659,8 +663,7 @@ main(int argc, char *argv[])
 	if (init_pci(ctx) != 0)
 		exit(1);
 
-	if (ioapic)
-		ioapic_init(0);
+	ioapic_init(0);
 
 	if (gdb_port != 0)
 		init_dbgport(gdb_port);
@@ -674,14 +677,19 @@ main(int argc, char *argv[])
 	/*
 	 * build the guest tables, MP etc.
 	 */
-	mptable_build(ctx, guest_ncpus, ioapic);
+	mptable_build(ctx, guest_ncpus);
 
 	if (acpi) {
-		error = acpi_build(ctx, guest_ncpus, ioapic);
+		error = acpi_build(ctx, guest_ncpus);
 		assert(error == 0);
 	}
 
 	/*
+	 * Change the proc title to include the VM name.
+	 */
+	setproctitle("%s", vmname); 
+	
+	/*
 	 * Add CPU 0
 	 */
 	fbsdrun_addcpu(ctx, BSP, rip);

Modified: stable/10/usr.sbin/bhyve/block_if.c
==============================================================================
--- stable/10/usr.sbin/bhyve/block_if.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/block_if.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -293,7 +293,7 @@ blockif_open(const char *optstr, const c
 
 	pthread_create(&bc->bc_btid, NULL, blockif_thr, bc);
 
-	snprintf(tname, sizeof(tname), "%s blk-%s", vmname, ident);
+	snprintf(tname, sizeof(tname), "blk-%s", ident);
 	pthread_set_name_np(bc->bc_btid, tname);
 
 	return (bc);

Modified: stable/10/usr.sbin/bhyve/mevent.c
==============================================================================
--- stable/10/usr.sbin/bhyve/mevent.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/mevent.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -381,10 +381,8 @@ mevent_delete_close(struct mevent *evp)
 static void
 mevent_set_name(void)
 {
-	char tname[MAXCOMLEN + 1];
 
-	snprintf(tname, sizeof(tname), "%s mevent", vmname);
-	pthread_set_name_np(mevent_tid, tname);
+	pthread_set_name_np(mevent_tid, "mevent");
 }
 
 void

Modified: stable/10/usr.sbin/bhyve/mptbl.c
==============================================================================
--- stable/10/usr.sbin/bhyve/mptbl.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/mptbl.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -242,7 +242,7 @@ mptable_add_oemtbl(void *tbl, int tblsz)
 }
 
 int
-mptable_build(struct vmctx *ctx, int ncpu, int ioapic)
+mptable_build(struct vmctx *ctx, int ncpu)
 {
 	mpcth_t			mpch;
 	bus_entry_ptr		mpeb;
@@ -278,15 +278,13 @@ mptable_build(struct vmctx *ctx, int ncp
 	curraddr += sizeof(*mpeb) * MPE_NUM_BUSES;
 	mpch->entry_count += MPE_NUM_BUSES;
 
-	if (ioapic) {
-		mpei = (io_apic_entry_ptr)curraddr;
-		mpt_build_ioapic_entries(mpei, ncpu + 1);
-		curraddr += sizeof(*mpei);
-		mpch->entry_count++;
-	}
+	mpei = (io_apic_entry_ptr)curraddr;
+	mpt_build_ioapic_entries(mpei, 0);
+	curraddr += sizeof(*mpei);
+	mpch->entry_count++;
 
 	mpie = (int_entry_ptr) curraddr;
-	mpt_build_ioint_entries(mpie, MPEII_MAX_IRQ, ncpu + 1);
+	mpt_build_ioint_entries(mpie, MPEII_MAX_IRQ, 0);
 	curraddr += sizeof(*mpie) * MPEII_MAX_IRQ;
 	mpch->entry_count += MPEII_MAX_IRQ;
 

Modified: stable/10/usr.sbin/bhyve/mptbl.h
==============================================================================
--- stable/10/usr.sbin/bhyve/mptbl.h	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/mptbl.h	Fri Dec 13 06:59:18 2013	(r259301)
@@ -29,7 +29,7 @@
 #ifndef _MPTBL_H_
 #define _MPTBL_H_
 
-int	mptable_build(struct vmctx *ctx, int ncpu, int ioapic);
+int	mptable_build(struct vmctx *ctx, int ncpu);
 void	mptable_add_oemtbl(void *tbl, int tblsz);
 
 #endif /* _MPTBL_H_ */

Modified: stable/10/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- stable/10/usr.sbin/bhyve/pci_ahci.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/pci_ahci.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -165,6 +165,7 @@ struct ahci_cmd_hdr {
 struct ahci_prdt_entry {
 	uint64_t dba;
 	uint32_t reserved;
+#define	DBCMASK		0x3fffff
 	uint32_t dbc;
 };
 
@@ -461,10 +462,13 @@ ahci_handle_dma(struct ahci_port *p, int
 	 * Build up the iovec based on the prdt
 	 */
 	for (i = 0; i < iovcnt; i++) {
+		uint32_t dbcsz;
+
+		dbcsz = (prdt->dbc & DBCMASK) + 1;
 		breq->br_iov[i].iov_base = paddr_guest2host(ahci_ctx(sc),
-				prdt->dba, prdt->dbc + 1);
-		breq->br_iov[i].iov_len = prdt->dbc + 1;
-		aior->done += (prdt->dbc + 1);
+		    prdt->dba, dbcsz);
+		breq->br_iov[i].iov_len = dbcsz;
+		aior->done += dbcsz;
 		prdt++;
 	}
 	if (readop)
@@ -513,11 +517,14 @@ write_prdt(struct ahci_port *p, int slot
 	from = buf;
 	prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
 	for (i = 0; i < hdr->prdtl && len; i++) {
-		uint8_t *ptr = paddr_guest2host(ahci_ctx(p->pr_sc),
-				prdt->dba, prdt->dbc + 1);
-		memcpy(ptr, from, prdt->dbc + 1);
-		len -= (prdt->dbc + 1);
-		from += (prdt->dbc + 1);
+		uint8_t *ptr;
+		uint32_t dbcsz;
+
+		dbcsz = (prdt->dbc & DBCMASK) + 1;
+		ptr = paddr_guest2host(ahci_ctx(p->pr_sc), prdt->dba, dbcsz);
+		memcpy(ptr, from, dbcsz);
+		len -= dbcsz;
+		from += dbcsz;
 		prdt++;
 	}
 	hdr->prdbc = size - len;
@@ -908,10 +915,13 @@ atapi_read(struct ahci_port *p, int slot
 	 * Build up the iovec based on the prdt
 	 */
 	for (i = 0; i < iovcnt; i++) {
+		uint32_t dbcsz;
+
+		dbcsz = (prdt->dbc & DBCMASK) + 1;
 		breq->br_iov[i].iov_base = paddr_guest2host(ahci_ctx(sc),
-		    prdt->dba, prdt->dbc + 1);
-		breq->br_iov[i].iov_len = prdt->dbc + 1;
-		aior->done += (prdt->dbc + 1);
+		    prdt->dba, dbcsz);
+		breq->br_iov[i].iov_len = dbcsz;
+		aior->done += dbcsz;
 		prdt++;
 	}
 	err = blockif_read(p->bctx, breq);
@@ -1714,11 +1724,9 @@ pci_ahci_init(struct vmctx *ctx, struct 
 
 	/*
 	 * Attempt to open the backing image. Use the PCI
-	 * slot/func/ahci_port for the identifier string
-	 * since that uniquely identifies a storage device.
+	 * slot/func for the identifier string.
 	 */
-	snprintf(bident, sizeof(bident), "%d:%d:%d", pi->pi_slot, pi->pi_func,
-	    0);
+	snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func);
 	bctxt = blockif_open(opts, bident);
 	if (bctxt == NULL) {       	
 		ret = 1;

Modified: stable/10/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- stable/10/usr.sbin/bhyve/pci_emul.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/pci_emul.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -1252,7 +1252,7 @@ pci_emul_cmdwrite(struct pci_devinst *pi
 	 * If the MMIO or I/O address space decoding has changed then
 	 * register/unregister all BARs that decode that address space.
 	 */
-	for (i = 0; i < PCI_BARMAX; i++) {
+	for (i = 0; i <= PCI_BARMAX; i++) {
 		switch (pi->pi_bar[i].type) {
 			case PCIBAR_NONE:
 			case PCIBAR_MEMHI64:

Modified: stable/10/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- stable/10/usr.sbin/bhyve/pci_virtio_net.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/pci_virtio_net.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -588,7 +588,7 @@ pci_vtnet_init(struct vmctx *ctx, struct
 	 */
 	if (!mac_provided) {
 		snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot,
-	            pi->pi_func, vmname);
+		    pi->pi_func, vmname);
 
 		MD5Init(&mdctx);
 		MD5Update(&mdctx, nstr, strlen(nstr));
@@ -632,7 +632,8 @@ pci_vtnet_init(struct vmctx *ctx, struct
 	pthread_mutex_init(&sc->tx_mtx, NULL);
 	pthread_cond_init(&sc->tx_cond, NULL);
 	pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc);
-        snprintf(tname, sizeof(tname), "%s vtnet%d tx", vmname, pi->pi_slot);
+	snprintf(tname, sizeof(tname), "vtnet-%d:%d tx", pi->pi_slot,
+	    pi->pi_func);
         pthread_set_name_np(sc->tx_tid, tname);
 
 	return (0);

Modified: stable/10/usr.sbin/bhyve/pit_8254.c
==============================================================================
--- stable/10/usr.sbin/bhyve/pit_8254.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/pit_8254.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -106,8 +106,8 @@ pit_mevent_cb(int fd, enum ev_type type,
 
 	pit_mev_count++;
 
-	ioapic_assert_pin(c->ctx, 0);
-	ioapic_deassert_pin(c->ctx, 0);
+	ioapic_assert_pin(c->ctx, 2);
+	ioapic_deassert_pin(c->ctx, 2);
 
 	/*
 	 * Delete the timer for one-shots

Modified: stable/10/usr.sbin/bhyve/uart_emul.c
==============================================================================
--- stable/10/usr.sbin/bhyve/uart_emul.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyve/uart_emul.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <fcntl.h>
 #include <termios.h>
 #include <unistd.h>
 #include <stdbool.h>
@@ -67,6 +68,7 @@ __FBSDID("$FreeBSD$");
 #define	FIFOSZ	16
 
 static bool uart_stdio;		/* stdio in use for i/o */
+static struct termios tio_stdio_orig;
 
 static struct {
 	int	baseaddr;
@@ -87,6 +89,12 @@ struct fifo {
 	int	size;		/* size of the fifo */
 };
 
+struct ttyfd {
+	bool	opened;
+	int	fd;		/* tty device file descriptor */
+	struct termios tio_orig, tio_new;    /* I/O Terminals */
+};
+
 struct uart_softc {
 	pthread_mutex_t mtx;	/* protects all softc elements */
 	uint8_t	data;		/* Data register (R/W) */
@@ -103,8 +111,7 @@ struct uart_softc {
 
 	struct fifo rxfifo;
 
-	bool	opened;
-	bool	stdio;
+	struct ttyfd tty;
 	bool	thre_int_pending;	/* THRE interrupt pending */
 
 	void	*arg;
@@ -114,38 +121,41 @@ struct uart_softc {
 
 static void uart_drain(int fd, enum ev_type ev, void *arg);
 
-static struct termios tio_orig, tio_new;	/* I/O Terminals */
-
 static void
 ttyclose(void)
 {
 
-	tcsetattr(STDIN_FILENO, TCSANOW, &tio_orig);
+	tcsetattr(STDIN_FILENO, TCSANOW, &tio_stdio_orig);
 }
 
 static void
-ttyopen(void)
+ttyopen(struct ttyfd *tf)
 {
 
-	tcgetattr(STDIN_FILENO, &tio_orig);
+	tcgetattr(tf->fd, &tf->tio_orig);
 
-	cfmakeraw(&tio_new);
-	tcsetattr(STDIN_FILENO, TCSANOW, &tio_new);
+	tf->tio_new = tf->tio_orig;
+	cfmakeraw(&tf->tio_new);
+	tf->tio_new.c_cflag |= CLOCAL;
+	tcsetattr(tf->fd, TCSANOW, &tf->tio_new);
 
-	atexit(ttyclose);
+	if (tf->fd == STDIN_FILENO) {
+		tio_stdio_orig = tf->tio_orig;
+		atexit(ttyclose);
+	}
 }
 
 static bool
-tty_char_available(void)
+tty_char_available(struct ttyfd *tf)
 {
 	fd_set rfds;
 	struct timeval tv;
 
 	FD_ZERO(&rfds);
-	FD_SET(STDIN_FILENO, &rfds);
+	FD_SET(tf->fd, &rfds);
 	tv.tv_sec = 0;
 	tv.tv_usec = 0;
-	if (select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) > 0 ) {
+	if (select(tf->fd + 1, &rfds, NULL, NULL, &tv) > 0 ) {
 		return (true);
 	} else {
 		return (false);
@@ -153,12 +163,12 @@ tty_char_available(void)
 }
 
 static int
-ttyread(void)
+ttyread(struct ttyfd *tf)
 {
 	char rb;
 
-	if (tty_char_available()) {
-		read(STDIN_FILENO, &rb, 1);
+	if (tty_char_available(tf)) {
+		read(tf->fd, &rb, 1);
 		return (rb & 0xff);
 	} else {
 		return (-1);
@@ -166,10 +176,10 @@ ttyread(void)
 }
 
 static void
-ttywrite(unsigned char wb)
+ttywrite(struct ttyfd *tf, unsigned char wb)
 {
 
-	(void)write(STDIN_FILENO, &wb, 1);
+	(void)write(tf->fd, &wb, 1);
 }
 
 static void
@@ -226,10 +236,8 @@ uart_opentty(struct uart_softc *sc)
 {
 	struct mevent *mev;
 
-	assert(!sc->opened && sc->stdio);
-
-	ttyopen();
-	mev = mevent_add(STDIN_FILENO, EVF_READ, uart_drain, sc);
+	ttyopen(&sc->tty);
+	mev = mevent_add(sc->tty.fd, EVF_READ, uart_drain, sc);
 	assert(mev);
 }
 
@@ -294,7 +302,7 @@ uart_drain(int fd, enum ev_type ev, void
 
 	sc = arg;	
 
-	assert(fd == STDIN_FILENO);
+	assert(fd == sc->tty.fd);
 	assert(ev == EVF_READ);
 	
 	/*
@@ -305,10 +313,10 @@ uart_drain(int fd, enum ev_type ev, void
 	pthread_mutex_lock(&sc->mtx);
 
 	if ((sc->mcr & MCR_LOOPBACK) != 0) {
-		(void) ttyread();
+		(void) ttyread(&sc->tty);
 	} else {
 		while (fifo_available(&sc->rxfifo) &&
-		       ((ch = ttyread()) != -1)) {
+		       ((ch = ttyread(&sc->tty)) != -1)) {
 			fifo_putchar(&sc->rxfifo, ch);
 		}
 		uart_toggle_intr(sc);
@@ -323,12 +331,6 @@ uart_write(struct uart_softc *sc, int of
 	int fifosz;
 	uint8_t msr;
 
-	/* Open terminal */
-	if (!sc->opened && sc->stdio) {
-		uart_opentty(sc);
-		sc->opened = true;
-	}
-
 	pthread_mutex_lock(&sc->mtx);
 	
 	/*
@@ -351,8 +353,8 @@ uart_write(struct uart_softc *sc, int of
 		if (sc->mcr & MCR_LOOPBACK) {
 			if (fifo_putchar(&sc->rxfifo, value) != 0)
 				sc->lsr |= LSR_OE;
-		} else if (sc->stdio) {
-			ttywrite(value);
+		} else if (sc->tty.opened) {
+			ttywrite(&sc->tty, value);
 		} /* else drop on floor */
 		sc->thre_int_pending = true;
 		break;
@@ -459,12 +461,6 @@ uart_read(struct uart_softc *sc, int off
 {
 	uint8_t iir, intr_reason, reg;
 
-	/* Open terminal */
-	if (!sc->opened && sc->stdio) {
-		uart_opentty(sc);
-		sc->opened = true;
-	}
-
 	pthread_mutex_lock(&sc->mtx);
 
 	/*
@@ -581,19 +577,47 @@ uart_init(uart_intr_func_t intr_assert, 
 	return (sc);
 }
 
+static int
+uart_tty_backend(struct uart_softc *sc, const char *opts)
+{
+	int fd;
+	int retval;
+
+	retval = -1;
+
+	fd = open(opts, O_RDWR);
+	if (fd > 0 && isatty(fd)) {
+		sc->tty.fd = fd;
+		sc->tty.opened = true;
+		retval = 0;
+	}
+	    
+	return (retval);
+}
+
 int
 uart_set_backend(struct uart_softc *sc, const char *opts)
 {
-	/*
-	 * XXX one stdio backend supported at this time.
-	 */
+	int retval;
+
+	retval = -1;
+
 	if (opts == NULL)
 		return (0);
 
-	if (strcmp("stdio", opts) == 0 && !uart_stdio) {
-		sc->stdio = true;
-		uart_stdio = true;
-		return (0);
-	} else
-		return (-1);
+	if (strcmp("stdio", opts) == 0) {
+		if (!uart_stdio) {
+			sc->tty.fd = STDIN_FILENO;
+			sc->tty.opened = true;
+			uart_stdio = true;
+			retval = 0;
+		}
+	} else if (uart_tty_backend(sc, opts) == 0) {
+		retval = 0;
+	}
+
+	if (retval == 0)
+		uart_opentty(sc);
+
+	return (retval);
 }

Modified: stable/10/usr.sbin/bhyveload/bhyveload.8
==============================================================================
--- stable/10/usr.sbin/bhyveload/bhyveload.8	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyveload/bhyveload.8	Fri Dec 13 06:59:18 2013	(r259301)
@@ -38,6 +38,8 @@ guest inside a bhyve virtual machine
 .Op Fl m Ar mem-size
 .Op Fl d Ar disk-path
 .Op Fl h Ar host-path
+.Op Fl e Ar name=value
+.Op Fl c Ar cons-dev
 .Ar vmname
 .Sh DESCRIPTION
 .Nm
@@ -91,6 +93,24 @@ is the pathname of the guest's boot disk
 The
 .Ar host-path
 is the directory at the top of the guest's boot filesystem.
+.It Fl e Ar name=value
+Set the FreeBSD loader environment variable
+.Ar name
+to
+.Ar value .
+.Pp
+The option may be used more than once to set more than one environment
+variable.
+.It Fl c Ar cons-dev
+.Ar cons-dev
+is a
+.Xr tty 4
+device to use for
+.Nm
+terminal I/O.
+.Pp
+The text string "stdio" is also accepted and selects the use of
+unbuffered standard I/O. This is the default value.
 .El
 .Sh EXAMPLES
 To create a virtual machine named
@@ -100,10 +120,23 @@ that boots off the ISO image
 and has 1GB memory allocated to it:
 .Pp
 .Dl "bhyveload -m 1G -d /freebsd/release.iso freebsd-vm"
+.Pp
+To create a virtual machine named
+.Ar test-vm
+with 256MB of memory allocated, the guest root filesystem under the host
+directory
+.Pa /user/images/test
+and terminal I/O sent to the
+.Xr nmdm 4
+device
+.Pa /dev/nmdm1B
+.Pp
+.Dl "bhyveload -m 256MB -h /usr/images/test -c /dev/nmdm1B test-vm"
 .Sh SEE ALSO
 .Xr bhyve 4 ,
 .Xr bhyve 8 ,
 .Xr loader 8 ,
+.Xr nmdm 4,
 .Xr vmm 4
 .Sh HISTORY
 .Nm

Modified: stable/10/usr.sbin/bhyveload/bhyveload.c
==============================================================================
--- stable/10/usr.sbin/bhyveload/bhyveload.c	Fri Dec 13 06:29:02 2013	(r259300)
+++ stable/10/usr.sbin/bhyveload/bhyveload.c	Fri Dec 13 06:59:18 2013	(r259301)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/disk.h>
+#include <sys/queue.h>
 
 #include <machine/specialreg.h>
 #include <machine/vmm.h>
@@ -70,6 +71,7 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <libgen.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -86,9 +88,10 @@ __FBSDID("$FreeBSD$");
 #define	GB	(1024 * 1024 * 1024UL)
 #define	BSP	0
 
-static char *host_base = "/";
+static char *host_base;
 static struct termios term, oldterm;
 static int disk_fd = -1;
+static int consin_fd, consout_fd;
 
 static char *vmname, *progname;
 static struct vmctx *ctx;
@@ -106,7 +109,7 @@ cb_putc(void *arg, int ch)
 {
 	char c = ch;
 
-	write(1, &c, 1);
+	(void) write(consout_fd, &c, 1);
 }
 
 static int
@@ -114,7 +117,7 @@ cb_getc(void *arg)
 {
 	char c;
 
-	if (read(0, &c, 1) == 1)
+	if (read(consin_fd, &c, 1) == 1)
 		return (c);
 	return (-1);
 }
@@ -124,7 +127,7 @@ cb_poll(void *arg)
 {
 	int n;
 
-	if (ioctl(0, FIONREAD, &n) >= 0)
+	if (ioctl(consin_fd, FIONREAD, &n) >= 0)
 		return (n > 0);
 	return (0);
 }
@@ -486,7 +489,7 @@ static void
 cb_exit(void *arg, int v)
 {
 
-	tcsetattr(0, TCSAFLUSH, &oldterm);
+	tcsetattr(consout_fd, TCSAFLUSH, &oldterm);
 	exit(v);
 }
 
@@ -498,23 +501,37 @@ cb_getmem(void *arg, uint64_t *ret_lowme
 	vm_get_memory_seg(ctx, 4 * GB, ret_highmem, NULL);
 }
 
+struct env {
+	const char *str;	/* name=value */
+	SLIST_ENTRY(env) next;
+};
+
+static SLIST_HEAD(envhead, env) envhead;
+
+static void
+addenv(const char *str)
+{
+	struct env *env;
+
+	env = malloc(sizeof(struct env));
+	env->str = str;
+	SLIST_INSERT_HEAD(&envhead, env, next);
+}
+
 static const char *
 cb_getenv(void *arg, int num)
 {
-	int max;
-
-	static const char * var[] = {
-		"smbios.bios.vendor=BHYVE",
-		"boot_serial=1",
-		NULL
-	};
+	int i;
+	struct env *env;
 
-	max = sizeof(var) / sizeof(var[0]);
+	i = 0;
+	SLIST_FOREACH(env, &envhead, next) {
+		if (i == num)
+			return (env->str);
+		i++;
+	}
 
-	if (num < max)
-		return (var[num]);
-	else
-		return (NULL);
+	return (NULL);
 }
 
 static struct loader_callbacks cb = {
@@ -548,13 +565,46 @@ static struct loader_callbacks cb = {
 	.getenv = cb_getenv,
 };
 
+static int
+altcons_open(char *path)
+{
+	struct stat sb;
+	int err;
+	int fd;
+
+	/*
+	 * Allow stdio to be passed in so that the same string
+	 * can be used for the bhyveload console and bhyve com-port
+	 * parameters
+	 */
+	if (!strcmp(path, "stdio"))
+		return (0);
+
+	err = stat(path, &sb);
+	if (err == 0) {
+		if (!S_ISCHR(sb.st_mode))
+			err = ENOTSUP;
+		else {
+			fd = open(path, O_RDWR | O_NONBLOCK);
+			if (fd < 0)
+				err = errno;
+			else
+				consin_fd = consout_fd = fd;
+		}
+	}
+
+	return (err);
+}
+
 static void
 usage(void)
 {
 
 	fprintf(stderr,
-		"usage: %s [-m mem-size][-d <disk-path>] [-h <host-path>] "
-		"<vmname>\n", progname);
+	    "usage: %s [-m mem-size] [-d <disk-path>] [-h <host-path>]\n"
+	    "       %*s [-e <name=value>] [-c <console-device>] <vmname>\n",
+	    progname,
+	    (int)strlen(progname), "");
 	exit(1);
 }
 
@@ -567,17 +617,29 @@ main(int argc, char** argv)
 	int opt, error;
 	char *disk_image;
 
-	progname = argv[0];
+	progname = basename(argv[0]);
 
 	mem_size = 256 * MB;
 	disk_image = NULL;
 
-	while ((opt = getopt(argc, argv, "d:h:m:")) != -1) {
+	consin_fd = STDIN_FILENO;
+	consout_fd = STDOUT_FILENO;
+
+	while ((opt = getopt(argc, argv, "c:d:e:h:m:")) != -1) {
 		switch (opt) {
+		case 'c':
+			error = altcons_open(optarg);
+			if (error != 0)
+				errx(EX_USAGE, "Could not open '%s'", optarg);
+			break;
 		case 'd':
 			disk_image = optarg;
 			break;
 
+		case 'e':
+			addenv(optarg);
+			break;
+
 		case 'h':
 			host_base = optarg;
 			break;
@@ -619,11 +681,13 @@ main(int argc, char** argv)
 		exit(1);
 	}
 
-	tcgetattr(0, &term);
+	tcgetattr(consout_fd, &term);
 	oldterm = term;
-	term.c_lflag &= ~(ICANON|ECHO);
-	term.c_iflag &= ~ICRNL;
-	tcsetattr(0, TCSAFLUSH, &term);
+	cfmakeraw(&term);
+	term.c_cflag |= CLOCAL;
+	
+	tcsetattr(consout_fd, TCSAFLUSH, &term);
+
 	h = dlopen("/boot/userboot.so", RTLD_LOCAL);
 	if (!h) {
 		printf("%s\n", dlerror());
@@ -638,5 +702,9 @@ main(int argc, char** argv)
 	if (disk_image) {
 		disk_fd = open(disk_image, O_RDONLY);
 	}
+
+	addenv("smbios.bios.vendor=BHYVE");
+	addenv("boot_serial=1");
+
 	func(&cb, NULL, USERBOOT_VERSION_3, disk_fd >= 0);
 }


More information about the svn-src-all mailing list