summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorDan McDonald <danmcd@mnx.io>2022-07-14 20:42:12 -0400
committerDan McDonald <danmcd@mnx.io>2022-07-14 20:42:12 -0400
commit964bebb5480b816d8a7d2dd58484eb826c732d52 (patch)
tree485159e8a28b01338bc963895ee0c2af4616d14b /usr
parent6638d136db644920fd3090c414ece292ca77b108 (diff)
parent62d03eda78495dc4dc79a65a6b1899e11dc34b12 (diff)
downloadillumos-joyent-964bebb5480b816d8a7d2dd58484eb826c732d52.tar.gz
Merge branch 'master' into OS-8394OS-8394
Diffstat (limited to 'usr')
-rw-r--r--usr/src/cmd/eeprom/i386/benv.c6
-rw-r--r--usr/src/cmd/sgs/dump/Makefile5
-rw-r--r--usr/src/cmd/sgs/dump/Makefile.com6
-rw-r--r--usr/src/cmd/sgs/dump/amd64/Makefile13
-rw-r--r--usr/src/cmd/sgs/dump/common/dump.c5
-rw-r--r--usr/src/cmd/sgs/dump/i386/Makefile33
-rw-r--r--usr/src/cmd/sgs/dump/sparc/Makefile33
-rw-r--r--usr/src/cmd/sgs/dump/sparcv9/Makefile13
-rw-r--r--usr/src/cmd/sgs/elfdump/Makefile4
-rw-r--r--usr/src/cmd/sgs/elfdump/Makefile.com9
-rw-r--r--usr/src/cmd/sgs/elfdump/amd64/Makefile13
-rw-r--r--usr/src/cmd/sgs/elfdump/common/main.c8
-rw-r--r--usr/src/cmd/sgs/elfdump/i386/Makefile35
-rw-r--r--usr/src/cmd/sgs/elfdump/sparc/Makefile33
-rw-r--r--usr/src/cmd/sgs/elfdump/sparcv9/Makefile12
-rw-r--r--usr/src/cmd/ttymon/tmchild.c2
-rw-r--r--usr/src/cmd/ttymon/tmexpress.c46
-rw-r--r--usr/src/cmd/ttymon/tmextern.h2
-rw-r--r--usr/src/cmd/ttymon/tmstruct.h1
-rw-r--r--usr/src/cmd/ttymon/tmterm.c2
-rw-r--r--usr/src/cmd/ttymon/ttymon.c88
-rw-r--r--usr/src/pkg/manifests/developer-object-file.p5m4
-rw-r--r--usr/src/pkg/manifests/system-bhyve-tests.p5m2
-rw-r--r--usr/src/test/bhyve-tests/runfiles/default.run6
-rw-r--r--usr/src/test/bhyve-tests/tests/Makefile2
-rw-r--r--usr/src/test/bhyve-tests/tests/viona/Makefile51
-rw-r--r--usr/src/test/bhyve-tests/tests/viona/interface_version.c51
-rw-r--r--usr/src/uts/common/io/scsi/impl/scsi_subr.c5
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_common.c27
-rw-r--r--usr/src/uts/intel/io/viona/viona_impl.h23
-rw-r--r--usr/src/uts/intel/io/viona/viona_main.c123
-rw-r--r--usr/src/uts/intel/io/viona/viona_ring.c194
-rw-r--r--usr/src/uts/intel/io/viona/viona_rx.c6
-rw-r--r--usr/src/uts/intel/io/viona/viona_tx.c89
-rw-r--r--usr/src/uts/intel/io/vmm/vmm_sol_dev.c18
-rw-r--r--usr/src/uts/intel/sys/viona_io.h30
36 files changed, 711 insertions, 289 deletions
diff --git a/usr/src/cmd/eeprom/i386/benv.c b/usr/src/cmd/eeprom/i386/benv.c
index 2119bdc3af..2e559f83d3 100644
--- a/usr/src/cmd/eeprom/i386/benv.c
+++ b/usr/src/cmd/eeprom/i386/benv.c
@@ -934,12 +934,13 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
+ optind = 0;
if (bootenv) {
int rv = 0;
if (argc == 1)
- value = argv[0];
+ value = argv[optind];
if (bootenv_print)
return (lzbe_bootenv_print(name, nvlist, stdout));
@@ -978,7 +979,7 @@ main(int argc, char **argv)
if (optind >= argc) {
print_vars(elist);
return (0);
- } else
+ } else {
while (optind < argc) {
/*
* If "-" specified, read variables from stdin;
@@ -996,6 +997,7 @@ main(int argc, char **argv)
optind++;
}
+ }
/*
* don't write benv if we are processing delayed writes since
diff --git a/usr/src/cmd/sgs/dump/Makefile b/usr/src/cmd/sgs/dump/Makefile
index 745dc3e005..a83ee1a5d7 100644
--- a/usr/src/cmd/sgs/dump/Makefile
+++ b/usr/src/cmd/sgs/dump/Makefile
@@ -20,10 +20,9 @@
# CDDL HEADER END
#
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# Copyright (c) 1994 by Sun Microsystems, Inc.
#
-# cmd/sgs/dump/Makefile
+
+BUILD32 = $(POUND_SIGN)
include ../Makefile.sub
diff --git a/usr/src/cmd/sgs/dump/Makefile.com b/usr/src/cmd/sgs/dump/Makefile.com
index 6fee454721..96a6b4aa58 100644
--- a/usr/src/cmd/sgs/dump/Makefile.com
+++ b/usr/src/cmd/sgs/dump/Makefile.com
@@ -40,12 +40,10 @@ OBJS = $(COMOBJS)
.PARALLEL: $(OBJS)
CPPFLAGS += -D__EXTENSIONS__
-LLDFLAGS = '$(LDPASS)-R$$ORIGIN/../../lib'
-LLDFLAGS64 = '$(LDPASS)-R$$ORIGIN/../../../lib/$(MACH64)'
-LDFLAGS += $(LLDFLAGS)
+LDFLAGS += '-R$$ORIGIN/../../lib/$(MACH64)'
CERRWARN += $(CNOWARN_UNINIT)
SMOFF += indenting
-LDLIBS += $(CONVLIBDIR) -lconv $(ELFLIBDIR) -lelf
+LDLIBS += $(CONVLIBDIR64) -lconv $(ELFLIBDIR64) -lelf
diff --git a/usr/src/cmd/sgs/dump/amd64/Makefile b/usr/src/cmd/sgs/dump/amd64/Makefile
index 10cef7c92d..20455f057c 100644
--- a/usr/src/cmd/sgs/dump/amd64/Makefile
+++ b/usr/src/cmd/sgs/dump/amd64/Makefile
@@ -30,14 +30,11 @@ include ../Makefile.com
.KEEP_STATE:
-LLDFLAGS = $(LLDFLAGS64)
-ELFLIBDIR = $(ELFLIBDIR64)
-CONVLIBDIR = $(CONVLIBDIR64)
-
-ROOTPROG= $(ROOTPROG64)
-ROOTCCSBINLINK= $(ROOTCCSBINLINK64)
-
include ../Makefile.targ
include $(SRC)/Makefile.master.64
-install: $(ROOTPROG64)
+install: $(ROOTPROG) $(ROOTPROG64) \
+ $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64)
+
+$(ROOTBIN64)/dump:
+ $(RM) $@; $(SYMLINK) ../../bin/dump $@
diff --git a/usr/src/cmd/sgs/dump/common/dump.c b/usr/src/cmd/sgs/dump/common/dump.c
index 204c0d52f1..20acf25d3d 100644
--- a/usr/src/cmd/sgs/dump/common/dump.c
+++ b/usr/src/cmd/sgs/dump/common/dump.c
@@ -2010,11 +2010,6 @@ main(int argc, char *argv[], char *envp[])
char *optstr = OPTSTR; /* option string used by getopt() */
int optchar;
- /*
- * Check for a binary that better fits this architecture.
- */
- (void) conv_check_native(argv, envp);
-
prog_name = argv[0];
(void) setlocale(LC_ALL, "");
diff --git a/usr/src/cmd/sgs/dump/i386/Makefile b/usr/src/cmd/sgs/dump/i386/Makefile
deleted file mode 100644
index ba0a4032e6..0000000000
--- a/usr/src/cmd/sgs/dump/i386/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/sgs/dump/sparc/Makefile b/usr/src/cmd/sgs/dump/sparc/Makefile
deleted file mode 100644
index ba0a4032e6..0000000000
--- a/usr/src/cmd/sgs/dump/sparc/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/sgs/dump/sparcv9/Makefile b/usr/src/cmd/sgs/dump/sparcv9/Makefile
index 5632b0ecf0..20455f057c 100644
--- a/usr/src/cmd/sgs/dump/sparcv9/Makefile
+++ b/usr/src/cmd/sgs/dump/sparcv9/Makefile
@@ -30,14 +30,11 @@ include ../Makefile.com
.KEEP_STATE:
-LLDFLAGS = $(LLDFLAGS64)
-ELFLIBDIR = $(ELFLIBDIR64)
-CONVLIBDIR = $(CONVLIBDIR64)
-
-ROOTPROG = $(ROOTPROG64)
-ROOTCCSBINLINK = $(ROOTCCSBINLINK64)
-
include ../Makefile.targ
include $(SRC)/Makefile.master.64
-install: $(ROOTPROG64)
+install: $(ROOTPROG) $(ROOTPROG64) \
+ $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64)
+
+$(ROOTBIN64)/dump:
+ $(RM) $@; $(SYMLINK) ../../bin/dump $@
diff --git a/usr/src/cmd/sgs/elfdump/Makefile b/usr/src/cmd/sgs/elfdump/Makefile
index 2f70df00c7..35c78efe07 100644
--- a/usr/src/cmd/sgs/elfdump/Makefile
+++ b/usr/src/cmd/sgs/elfdump/Makefile
@@ -23,7 +23,7 @@
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
+
+BUILD32 = $(POUND_SIGN)
include $(SRC)/cmd/sgs/Makefile.sub
diff --git a/usr/src/cmd/sgs/elfdump/Makefile.com b/usr/src/cmd/sgs/elfdump/Makefile.com
index c5190adcd4..1caec6d1bf 100644
--- a/usr/src/cmd/sgs/elfdump/Makefile.com
+++ b/usr/src/cmd/sgs/elfdump/Makefile.com
@@ -51,11 +51,10 @@ MAPOPT= $(MAPFILE:%=-Wl,-M%)
CPPFLAGS= -I. -I../common -I../../include -I../../include/$(MACH) \
-I$(SRC)/lib/libc/inc -I$(SRC)/uts/$(ARCH)/sys \
$(CPPFLAGS.master) -I$(ELFCAP)
-LLDFLAGS = '-R$$ORIGIN/../../lib'
-LLDFLAGS64 = '-R$$ORIGIN/../../../lib/$(MACH64)'
-LDFLAGS += $(VERSREF) $(MAPOPT) $(LLDFLAGS)
-LDLIBS += $(ELFLIBDIR) -lelf $(LDDBGLIBDIR) -llddbg \
- $(CONVLIBDIR) -lconv
+
+LDFLAGS += $(VERSREF) $(MAPOPT) '-R$$ORIGIN/../../lib/$(MACH64)'
+LDLIBS += $(ELFLIBDIR64) -lelf $(LDDBGLIBDIR64) -llddbg \
+ $(CONVLIBDIR64) -lconv
NATIVE_LDFLAGS = $(LDASSERTS) $(BDIRECT)
diff --git a/usr/src/cmd/sgs/elfdump/amd64/Makefile b/usr/src/cmd/sgs/elfdump/amd64/Makefile
index b04872649b..0294565bb4 100644
--- a/usr/src/cmd/sgs/elfdump/amd64/Makefile
+++ b/usr/src/cmd/sgs/elfdump/amd64/Makefile
@@ -31,17 +31,14 @@ include ../Makefile.com
.KEEP_STATE:
ARCH = amd64
-LLDFLAGS = $(LLDFLAGS64)
-ELFLIBDIR = $(ELFLIBDIR64)
-LDDBGLIBDIR = $(LDDBGLIBDIR64)
-CONVLIBDIR = $(CONVLIBDIR64)
-
-ROOTPROG = $(ROOTPROG64)
-ROOTCCSBINLINK = $(ROOTCCSBINLINK64)
install: all $(ROOTPROG64)
include ../Makefile.targ
include $(SRC)/Makefile.master.64
-install: $(ROOTPROG64)
+install: $(ROOTPROG) $(ROOTPROG64) \
+ $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64)
+
+$(ROOTBIN64)/elfdump:
+ $(RM) $@; $(SYMLINK) ../../bin/elfdump $@
diff --git a/usr/src/cmd/sgs/elfdump/common/main.c b/usr/src/cmd/sgs/elfdump/common/main.c
index ed95ad5892..7acecdaf96 100644
--- a/usr/src/cmd/sgs/elfdump/common/main.c
+++ b/usr/src/cmd/sgs/elfdump/common/main.c
@@ -174,7 +174,7 @@ detail_usage()
*/
void
dump_hex_bytes(const void *data, size_t n, int indent,
- int bytes_per_col, int col_per_row)
+ int bytes_per_col, int col_per_row)
{
const uchar_t *ldata = data;
int bytes_per_row = bytes_per_col * col_per_row;
@@ -735,12 +735,6 @@ main(int argc, char **argv, char **envp)
uchar_t osabi = ELFOSABI_NONE;
/*
- * If we're on a 64-bit kernel, try to exec a full 64-bit version of
- * the binary. If successful, conv_check_native() won't return.
- */
- (void) conv_check_native(argv, envp);
-
- /*
* Establish locale.
*/
(void) setlocale(LC_MESSAGES, MSG_ORIG(MSG_STR_EMPTY));
diff --git a/usr/src/cmd/sgs/elfdump/i386/Makefile b/usr/src/cmd/sgs/elfdump/i386/Makefile
deleted file mode 100644
index 95390a2899..0000000000
--- a/usr/src/cmd/sgs/elfdump/i386/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-ARCH = i386
-
-install: all $(ROOTPROG32)
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/sgs/elfdump/sparc/Makefile b/usr/src/cmd/sgs/elfdump/sparc/Makefile
deleted file mode 100644
index a2c6327b0b..0000000000
--- a/usr/src/cmd/sgs/elfdump/sparc/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-ARCH = sparc
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/sgs/elfdump/sparcv9/Makefile b/usr/src/cmd/sgs/elfdump/sparcv9/Makefile
index f24ce47957..2db168be93 100644
--- a/usr/src/cmd/sgs/elfdump/sparcv9/Makefile
+++ b/usr/src/cmd/sgs/elfdump/sparcv9/Makefile
@@ -31,16 +31,12 @@ include ../Makefile.com
.KEEP_STATE:
ARCH = sparcv9
-LLDFLAGS = $(LLDFLAGS64)
-ELFLIBDIR = $(ELFLIBDIR64)
-LDDBGLIBDIR = $(LDDBGLIBDIR64)
-CONVLIBDIR = $(CONVLIBDIR64)
-
-ROOTPROG = $(ROOTPROG64)
-ROOTCCSBINLINK = $(ROOTCCSBINLINK64)
include ../Makefile.targ
include $(SRC)/Makefile.master.64
-install: $(ROOTPROG64)
+install: $(ROOTPROG) $(ROOTPROG64) \
+ $(ROOTCCSBINLINK) $(ROOTCCSBINLINK64)
+$(ROOTBIN64)/elfdump:
+ $(RM) $@; $(SYMLINK) ../../bin/elfdump $@
diff --git a/usr/src/cmd/ttymon/tmchild.c b/usr/src/cmd/ttymon/tmchild.c
index a58099974b..960a9a816c 100644
--- a/usr/src/cmd/ttymon/tmchild.c
+++ b/usr/src/cmd/ttymon/tmchild.c
@@ -99,7 +99,7 @@ tmchild(struct pmtab *pmtab)
*/
(void) setsid();
}
- speedef = get_speed(pmtab->p_ttylabel);
+ speedef = get_speed(pmtab);
openline(pmtab, speedef);
if (pmtab->p_ttyflags & (C_FLAG|B_FLAG)) {
if (pmtab->p_fd >= 0) {
diff --git a/usr/src/cmd/ttymon/tmexpress.c b/usr/src/cmd/ttymon/tmexpress.c
index 345fdd1529..2a3f91d147 100644
--- a/usr/src/cmd/ttymon/tmexpress.c
+++ b/usr/src/cmd/ttymon/tmexpress.c
@@ -34,7 +34,6 @@
#include <ctype.h>
#include <string.h>
#include <signal.h>
-#include <sys/stat.h>
#include <utmpx.h>
#include <pwd.h>
#include <dirent.h>
@@ -42,6 +41,7 @@
#include <sys/acl.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/mkdev.h>
#include <sys/console.h>
#include <libdevinfo.h>
#include "ttymon.h"
@@ -143,6 +143,44 @@ ttymon_express(int argc, char **argv)
}
/*
+ * For serial device, return ttyX-mode property value.
+ */
+static char *
+get_ttymode_prop(dev_t rconsdev)
+{
+ char *rootpath = "/";
+ char path[MAXPATHLEN];
+ di_node_t root;
+ char *propname, *v;
+ struct stat st;
+
+ (void) snprintf(path, sizeof (path), "/dev/tty%c",
+ 'a' + minor(rconsdev));
+ if (stat(path, &st) < 0)
+ return (NULL);
+
+ if (st.st_rdev != rconsdev)
+ return (NULL);
+
+ if (asprintf(&propname, "%s-mode", path + 5) <= 0)
+ return (NULL);
+
+ root = di_init(rootpath, DINFOPROP);
+ if (root == DI_NODE_NIL) {
+ free(propname);
+ return (NULL);
+ }
+
+ v = NULL;
+ if (di_prop_lookup_strings(DDI_DEV_T_ANY, root, propname, &v) > 0)
+ v = strdup(v);
+
+ di_fini(root);
+ free(propname);
+ return (v);
+}
+
+/*
* parse_arg - parse cmd line arguments
*/
static int
@@ -172,11 +210,13 @@ parse_args(int argc, char **argv, struct pmtab *pmtab)
pmtab->p_termtype = "";
pmtab->p_device = "";
pmtab->p_status = GETTY;
+ pmtab->p_ttymode = NULL;
if (strcmp(lastname(argv[0]), "getty") == 0) {
pmtab->p_ttylabel = "300";
getty_options(argc, argv, pmtab);
} else {
int cn_fd;
+ struct cons_getdev cnd;
pmtab->p_ttylabel = "9600";
ttymon_options(argc, argv, pmtab);
@@ -200,6 +240,10 @@ parse_args(int argc, char **argv, struct pmtab *pmtab)
if (ioctl(cn_fd, CONS_GETTERM, &cnterm) != -1)
pmtab->p_termtype = cnterm.cn_term_type;
+
+ if (ioctl(cn_fd, CONS_GETDEV, &cnd) != -1)
+ pmtab->p_ttymode =
+ get_ttymode_prop(cnd.cnd_rconsdev);
(void) close(cn_fd);
}
}
diff --git a/usr/src/cmd/ttymon/tmextern.h b/usr/src/cmd/ttymon/tmextern.h
index b08c59f04d..955e5773ff 100644
--- a/usr/src/cmd/ttymon/tmextern.h
+++ b/usr/src/cmd/ttymon/tmextern.h
@@ -222,7 +222,7 @@ extern "C" {
extern int Splflag;
/* ttymon.c */
- extern struct Gdef *get_speed(char *);
+ extern struct Gdef *get_speed(struct pmtab *);
extern void open_device(struct pmtab *);
extern void set_softcar(struct pmtab *);
extern void setup_PCpipe(void);
diff --git a/usr/src/cmd/ttymon/tmstruct.h b/usr/src/cmd/ttymon/tmstruct.h
index 288c1ec122..8c4582896a 100644
--- a/usr/src/cmd/ttymon/tmstruct.h
+++ b/usr/src/cmd/ttymon/tmstruct.h
@@ -74,6 +74,7 @@ struct pmtab {
uid_t p_uid; /* uid of p_identity */
gid_t p_gid; /* gid of p_identity */
char *p_dir; /* home dir of p_identity */
+ char *p_ttymode; /* mode line for serial device */
struct pmtab *p_next;
};
diff --git a/usr/src/cmd/ttymon/tmterm.c b/usr/src/cmd/ttymon/tmterm.c
index 96e63af2d3..613cf2597d 100644
--- a/usr/src/cmd/ttymon/tmterm.c
+++ b/usr/src/cmd/ttymon/tmterm.c
@@ -244,7 +244,7 @@ initial_termio(int fd, struct pmtab *pmptr)
int ret;
struct Gdef *speedef;
- speedef = get_speed(pmptr->p_ttylabel);
+ speedef = get_speed(pmptr);
if (speedef->g_autobaud & A_FLAG) {
pmptr->p_ttyflags |= A_FLAG;
if (auto_termio(fd) == -1) {
diff --git a/usr/src/cmd/ttymon/ttymon.c b/usr/src/cmd/ttymon/ttymon.c
index 03ff520059..0c061a9c8c 100644
--- a/usr/src/cmd/ttymon/ttymon.c
+++ b/usr/src/cmd/ttymon/ttymon.c
@@ -26,6 +26,7 @@
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
+#include <ctype.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <fcntl.h>
@@ -597,25 +598,106 @@ free_defs(void)
}
/*
+ * rebuild flags entry using speed from ttymode.
+ */
+static char *
+merge_flags(char *src, char *ttymode)
+{
+ char *data, *ptr, *flags;
+
+ /* copy speed entry */
+ data = strsave(src);
+ flags = strsave(ttymode);
+ ptr = strchr(flags, ',');
+ if (ptr == NULL) { /* ttymode is corrupted */
+ free(flags);
+ return (data);
+ }
+ *ptr = '\0';
+ ptr = flags;
+ flags = strsave(flags);
+ free(ptr);
+
+ /*
+ * The flags line is supposed to have stty keywords separated by space.
+ * We need to split up the keywords, replace the speed and
+ * reconstruct the flags line.
+ */
+
+ ptr = strtok(data, " \t");
+ if (ptr == NULL) {
+ free(data);
+ return (flags);
+ }
+
+ do {
+ char *tmp;
+
+ /* skip speed */
+ if (isdigit(*ptr))
+ continue;
+
+ if (asprintf(&tmp, "%s %s", flags, ptr) <= 0) {
+ /* should we complain? */
+ break;
+ }
+ free(flags);
+ flags = tmp;
+ } while ((ptr = strtok(NULL, " \t")) != NULL);
+
+ free(data);
+ return (flags);
+}
+
+/*
* struct Gdef *get_speed(ttylabel)
* - search "/etc/ttydefs" for speed and term. specification
* using "ttylabel". If "ttylabel" is NULL, default
* to DEFAULT
+ * - for /dev/console, if we are in fact using serial console,
+ * use ttyX-mode value to get speed. This allows us to use
+ * the value set for serial console either from firmware (or BMC sol),
+ * or boot loader default.
* arg: ttylabel - label/id of speed settings.
*/
struct Gdef *
-get_speed(char *ttylabel)
+get_speed(struct pmtab *pmptr)
{
+ static struct Gdef serial = { 0 };
struct Gdef *sp;
+ char *ttylabel = pmptr->p_ttylabel;
if ((ttylabel != NULL) && (*ttylabel != '\0')) {
if ((sp = find_def(ttylabel)) == NULL) {
log("unable to find <%s> in \"%s\"", ttylabel, TTYDEFS);
sp = &DEFAULT; /* use default */
}
- } else sp = &DEFAULT; /* use default */
- return (sp);
+ } else {
+ sp = &DEFAULT; /* use default */
+ }
+
+ /*
+ * if this is not /dev/console or /dev/console is not using serial,
+ * we are done.
+ */
+ if (pmptr->p_ttymode == NULL ||
+ strcmp(pmptr->p_device, "/dev/console") != 0)
+ return (sp);
+
+ /* is entry for serial set up? */
+ if (serial.g_id == NULL) {
+ /*
+ * Copy data from sp, except we need to update inital and
+ * final flags.
+ */
+ serial.g_id = strsave(sp->g_id);
+ serial.g_iflags = merge_flags(sp->g_iflags, pmptr->p_ttymode);
+ serial.g_fflags = merge_flags(sp->g_fflags, pmptr->p_ttymode);
+ serial.g_autobaud = sp->g_autobaud;
+ serial.g_nextid = strsave(sp->g_nextid);
+ }
+ return (&serial);
}
/*
diff --git a/usr/src/pkg/manifests/developer-object-file.p5m b/usr/src/pkg/manifests/developer-object-file.p5m
index e80006c2bd..14f22cd0e5 100644
--- a/usr/src/pkg/manifests/developer-object-file.p5m
+++ b/usr/src/pkg/manifests/developer-object-file.p5m
@@ -35,8 +35,8 @@ dir path=usr group=sys
dir path=usr/bin
dir path=usr/bin/$(ARCH64)
file path=usr/bin/$(ARCH64)/ar mode=0555
-file path=usr/bin/$(ARCH64)/dump mode=0555
-file path=usr/bin/$(ARCH64)/elfdump mode=0555
+link path=usr/bin/$(ARCH64)/dump target=../../bin/dump
+link path=usr/bin/$(ARCH64)/elfdump target=../../bin/elfdump
file path=usr/bin/$(ARCH64)/elfedit mode=0555
file path=usr/bin/$(ARCH64)/mcs mode=0555
file path=usr/bin/$(ARCH64)/nm mode=0555
diff --git a/usr/src/pkg/manifests/system-bhyve-tests.p5m b/usr/src/pkg/manifests/system-bhyve-tests.p5m
index 1df6e67bd5..aae7d2807a 100644
--- a/usr/src/pkg/manifests/system-bhyve-tests.p5m
+++ b/usr/src/pkg/manifests/system-bhyve-tests.p5m
@@ -49,6 +49,8 @@ file path=opt/bhyve-tests/tests/mevent/read_pause mode=0555
file path=opt/bhyve-tests/tests/mevent/read_requeue mode=0555
file path=opt/bhyve-tests/tests/mevent/vnode_file mode=0555
file path=opt/bhyve-tests/tests/mevent/vnode_zvol mode=0555
+dir path=opt/bhyve-tests/tests/viona
+file path=opt/bhyve-tests/tests/viona/interface_version mode=0555
dir path=opt/bhyve-tests/tests/vmm
file path=opt/bhyve-tests/tests/vmm/check_iommu mode=0555
file path=opt/bhyve-tests/tests/vmm/fpu_getset mode=0555
diff --git a/usr/src/test/bhyve-tests/runfiles/default.run b/usr/src/test/bhyve-tests/runfiles/default.run
index 5cdd9647b6..8ec89a7a0a 100644
--- a/usr/src/test/bhyve-tests/runfiles/default.run
+++ b/usr/src/test/bhyve-tests/runfiles/default.run
@@ -49,6 +49,12 @@ tests = [
'triple_fault'
]
+[/opt/bhyve-tests/tests/viona]
+user = root
+tests = [
+ 'interface_version'
+ ]
+
# Tests of userspace mevent system, built from cmd/bhyve
[/opt/bhyve-tests/tests/mevent]
tests = ['lists_delete', 'read_disable', 'read_pause', 'read_requeue',
diff --git a/usr/src/test/bhyve-tests/tests/Makefile b/usr/src/test/bhyve-tests/tests/Makefile
index 5dc416db01..6742106ae0 100644
--- a/usr/src/test/bhyve-tests/tests/Makefile
+++ b/usr/src/test/bhyve-tests/tests/Makefile
@@ -15,6 +15,6 @@
.PARALLEL: $(SUBDIRS)
-SUBDIRS = inst_emul kdev vmm
+SUBDIRS = inst_emul kdev viona vmm
include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/bhyve-tests/tests/viona/Makefile b/usr/src/test/bhyve-tests/tests/viona/Makefile
new file mode 100644
index 0000000000..8b68c11d35
--- /dev/null
+++ b/usr/src/test/bhyve-tests/tests/viona/Makefile
@@ -0,0 +1,51 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2022 Oxide Computer Company
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/cmd/Makefile.cmd.64
+include $(SRC)/test/Makefile.com
+
+PROG = interface_version
+
+CLEAN_OBJS = $(PROG:%=%.o)
+
+ROOTOPTPKG = $(ROOT)/opt/bhyve-tests
+TESTDIR = $(ROOTOPTPKG)/tests/viona
+
+CMDS = $(PROG:%=$(TESTDIR)/%)
+$(CMDS) := FILEMODE = 0555
+
+CSTD= $(CSTD_GNU99)
+CPPFLAGS = $(CPPFLAGS.master) \
+ -I$(SRC)/uts/intel
+
+all: $(PROG)
+
+install: all $(CMDS)
+
+clean:
+ -$(RM) $(CLEAN_OBJS)
+clobber: clean
+ -$(RM) $(PROG)
+
+$(CMDS): $(TESTDIR) $(PROG)
+
+$(TESTDIR):
+ $(INS.dir)
+
+$(TESTDIR)/%: %
+ $(INS.file)
+
+%: %.o
+ $(LINK.c) -o $@ $< $(LDLIBS)
+ $(POST_PROCESS)
diff --git a/usr/src/test/bhyve-tests/tests/viona/interface_version.c b/usr/src/test/bhyve-tests/tests/viona/interface_version.c
new file mode 100644
index 0000000000..1b3cd585f0
--- /dev/null
+++ b/usr/src/test/bhyve-tests/tests/viona/interface_version.c
@@ -0,0 +1,51 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2022 Oxide Computer Company
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <libgen.h>
+
+#include <sys/viona_io.h>
+
+#define VIONA_DEV "/dev/viona"
+
+int
+main(int argc, char *argv[])
+{
+ const char *suite_name = basename(argv[0]);
+
+ int ctl_fd = open(VIONA_DEV, O_EXCL | O_RDWR);
+ if (ctl_fd < 0) {
+ perror("could not open viona device");
+ return (EXIT_FAILURE);
+ }
+
+ int version = ioctl(ctl_fd, VNA_IOC_VERSION, 0);
+ if (version < 0) {
+ perror("VNA_IOC_VERSION ioctl failed");
+ return (EXIT_FAILURE);
+ }
+ if (version != VIONA_CURRENT_INTERFACE_VERSION) {
+ (void) fprintf(stderr, "kernel version %d != expected %d\n",
+ version, VIONA_CURRENT_INTERFACE_VERSION);
+ return (EXIT_FAILURE);
+ }
+
+ (void) close(ctl_fd);
+ (void) printf("%s\tPASS\n", suite_name);
+ return (0);
+}
diff --git a/usr/src/uts/common/io/scsi/impl/scsi_subr.c b/usr/src/uts/common/io/scsi/impl/scsi_subr.c
index 1fd97aeeb3..6542098fe2 100644
--- a/usr/src/uts/common/io/scsi/impl/scsi_subr.c
+++ b/usr/src/uts/common/io/scsi/impl/scsi_subr.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2022 Garrett D'Amore
*/
#include <sys/scsi/scsi.h>
@@ -390,8 +391,6 @@ free_pktiopb(struct scsi_pkt *pkt, caddr_t datap, int datalen)
* Common naming functions
*/
-static char scsi_tmpname[64];
-
char *
scsi_dname(int dtyp)
{
@@ -479,7 +478,7 @@ scsi_cname(uchar_t cmd, register char **cmdvec)
}
cmdvec++;
}
- return (sprintf(scsi_tmpname, "<undecoded cmd 0x%x>", cmd));
+ return ("<undecoded cmd>");
}
char *
diff --git a/usr/src/uts/i86pc/io/pci/pci_common.c b/usr/src/uts/i86pc/io/pci/pci_common.c
index feb5fbfd25..fe1918d121 100644
--- a/usr/src/uts/i86pc/io/pci/pci_common.c
+++ b/usr/src/uts/i86pc/io/pci/pci_common.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2022 Oxide Computer Company
*/
/*
@@ -1018,6 +1019,31 @@ pci_common_get_reg_prop(dev_info_t *dip, pci_regspec_t *pci_rp)
for (i = 0; i < number; i++) {
if ((assigned_addr[i].pci_phys_hi & PCI_CONF_ADDR_MASK) ==
phys_hi) {
+ /*
+ * When the system does not manage to allocate PCI
+ * resources for a device, then the value that is stored
+ * in assigned addresses ends up being the hardware
+ * default reset value of '0'. On currently supported
+ * platforms, physical address zero is associated with
+ * memory; however, on other platforms this may be the
+ * exception vector table (ARM), etc. and so we opt to
+ * generally keep the idea in PCI that the reset value
+ * will not be used for actual MMIO allocations. If such
+ * a platform comes around where it is worth using that
+ * bit of MMIO for PCI then we should make this check
+ * platform-specific.
+ *
+ * Note, the +1 in the print statement is because a
+ * given regs[0] describes B/D/F information for the
+ * device.
+ */
+ if (assigned_addr[i].pci_phys_mid == 0 &&
+ assigned_addr[i].pci_phys_low == 0) {
+ dev_err(dip, CE_WARN, "regs[%u] does not have "
+ "a valid MMIO address", i + 1);
+ goto err;
+ }
+
pci_rp->pci_phys_mid = assigned_addr[i].pci_phys_mid;
pci_rp->pci_phys_low = assigned_addr[i].pci_phys_low;
ddi_prop_free(assigned_addr);
@@ -1025,6 +1051,7 @@ pci_common_get_reg_prop(dev_info_t *dip, pci_regspec_t *pci_rp)
}
}
+err:
ddi_prop_free(assigned_addr);
return (DDI_FAILURE);
}
diff --git a/usr/src/uts/intel/io/viona/viona_impl.h b/usr/src/uts/intel/io/viona/viona_impl.h
index 760474e78b..c99bd2c51e 100644
--- a/usr/src/uts/intel/io/viona/viona_impl.h
+++ b/usr/src/uts/intel/io/viona/viona_impl.h
@@ -35,7 +35,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2022 Oxide Computer Company
*/
#ifndef _VIONA_IMPL_H
@@ -76,7 +76,8 @@ enum viona_ring_state {
enum viona_ring_state_flags {
VRSF_REQ_START = 0x1, /* start running from INIT state */
VRSF_REQ_STOP = 0x2, /* stop running, clean up, goto RESET state */
- VRSF_RENEW = 0x4, /* ring renewing lease */
+ VRSF_REQ_PAUSE = 0x4, /* stop running, goto INIT state */
+ VRSF_RENEW = 0x8, /* ring renewing lease */
};
typedef struct viona_vring {
@@ -232,11 +233,6 @@ struct virtio_net_hdr {
};
#pragma pack()
-#define VRING_NEED_BAIL(ring, proc) \
- (((ring)->vr_state_flags & VRSF_REQ_STOP) != 0 || \
- ((proc)->p_flag & SEXITING) != 0)
-
-
#define VNETHOOK_INTERESTED_IN(neti) \
(neti)->vni_nethook.vnh_event_in.he_interested
#define VNETHOOK_INTERESTED_OUT(neti) \
@@ -288,12 +284,23 @@ struct virtio_net_hdr {
#define VIRTIO_F_RING_INDIRECT_DESC (1 << 28)
#define VIRTIO_F_RING_EVENT_IDX (1 << 29)
+struct viona_ring_params {
+ uint64_t vrp_pa;
+ uint16_t vrp_size;
+ uint16_t vrp_avail_idx;
+ uint16_t vrp_used_idx;
+};
void viona_ring_alloc(viona_link_t *, viona_vring_t *);
void viona_ring_free(viona_vring_t *);
+int viona_ring_get_state(viona_link_t *, uint16_t, struct viona_ring_params *);
+int viona_ring_set_state(viona_link_t *, uint16_t,
+ const struct viona_ring_params *);
int viona_ring_reset(viona_vring_t *, boolean_t);
-int viona_ring_init(viona_link_t *, uint16_t, uint16_t, uint64_t);
+int viona_ring_init(viona_link_t *, uint16_t, const struct viona_ring_params *);
boolean_t viona_ring_lease_renew(viona_vring_t *);
+bool vring_need_bail(const viona_vring_t *);
+int viona_ring_pause(viona_vring_t *);
int vq_popchain(viona_vring_t *, struct iovec *, uint_t, uint16_t *,
vmm_page_t **);
diff --git a/usr/src/uts/intel/io/viona/viona_main.c b/usr/src/uts/intel/io/viona/viona_main.c
index a34196ba1a..c6a750d532 100644
--- a/usr/src/uts/intel/io/viona/viona_main.c
+++ b/usr/src/uts/intel/io/viona/viona_main.c
@@ -35,7 +35,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2022 Oxide Computer Company
*/
/*
@@ -111,6 +111,14 @@
* | VRS_RESET and exit.
* | ^
* | |
+ * |<-------------------------------------------<+
+ * | | |
+ * | | ^
+ * | * If ring is requested to pause (but not stop)from the
+ * | VRS_RUN state, it will return to the VRS_INIT state.
+ * |
+ * | ^
+ * | |
* | ^
* V
* +-----------+ The worker thread associated with the ring has started
@@ -286,8 +294,11 @@ static int viona_ioc_delete(viona_soft_state_t *, boolean_t);
static int viona_ioc_set_notify_ioport(viona_link_t *, uint16_t);
static int viona_ioc_ring_init(viona_link_t *, void *, int);
+static int viona_ioc_ring_set_state(viona_link_t *, void *, int);
+static int viona_ioc_ring_get_state(viona_link_t *, void *, int);
static int viona_ioc_ring_reset(viona_link_t *, uint_t);
static int viona_ioc_ring_kick(viona_link_t *, uint_t);
+static int viona_ioc_ring_pause(viona_link_t *, uint_t);
static int viona_ioc_ring_set_msi(viona_link_t *, void *, int);
static int viona_ioc_ring_intr_clear(viona_link_t *, uint_t);
static int viona_ioc_intr_poll(viona_link_t *, void *, int, int *);
@@ -530,6 +541,9 @@ viona_ioctl(dev_t dev, int cmd, intptr_t data, int md, cred_t *cr, int *rv)
return (viona_ioc_create(ss, dptr, md, cr));
case VNA_IOC_DELETE:
return (viona_ioc_delete(ss, B_FALSE));
+ case VNA_IOC_VERSION:
+ *rv = VIONA_CURRENT_INTERFACE_VERSION;
+ return (0);
default:
break;
}
@@ -578,6 +592,16 @@ viona_ioctl(dev_t dev, int cmd, intptr_t data, int md, cred_t *cr, int *rv)
case VNA_IOC_RING_INTR_CLR:
err = viona_ioc_ring_intr_clear(link, (uint_t)data);
break;
+ case VNA_IOC_RING_SET_STATE:
+ err = viona_ioc_ring_set_state(link, dptr, md);
+ break;
+ case VNA_IOC_RING_GET_STATE:
+ err = viona_ioc_ring_get_state(link, dptr, md);
+ break;
+ case VNA_IOC_RING_PAUSE:
+ err = viona_ioc_ring_pause(link, (uint_t)data);
+ break;
+
case VNA_IOC_INTR_POLL:
err = viona_ioc_intr_poll(link, dptr, md, rv);
break;
@@ -853,13 +877,65 @@ viona_ioc_ring_init(viona_link_t *link, void *udata, int md)
if (ddi_copyin(udata, &kri, sizeof (kri), md) != 0) {
return (EFAULT);
}
+ const struct viona_ring_params params = {
+ .vrp_pa = kri.ri_qaddr,
+ .vrp_size = kri.ri_qsize,
+ .vrp_avail_idx = 0,
+ .vrp_used_idx = 0,
+ };
+
+ err = viona_ring_init(link, kri.ri_index, &params);
+
+ return (err);
+}
+
+static int
+viona_ioc_ring_set_state(viona_link_t *link, void *udata, int md)
+{
+ vioc_ring_state_t krs;
+ int err;
+
+ if (ddi_copyin(udata, &krs, sizeof (krs), md) != 0) {
+ return (EFAULT);
+ }
+ const struct viona_ring_params params = {
+ .vrp_pa = krs.vrs_qaddr,
+ .vrp_size = krs.vrs_qsize,
+ .vrp_avail_idx = krs.vrs_avail_idx,
+ .vrp_used_idx = krs.vrs_used_idx,
+ };
- err = viona_ring_init(link, kri.ri_index, kri.ri_qsize, kri.ri_qaddr);
+ err = viona_ring_init(link, krs.vrs_index, &params);
return (err);
}
static int
+viona_ioc_ring_get_state(viona_link_t *link, void *udata, int md)
+{
+ vioc_ring_state_t krs;
+
+ if (ddi_copyin(udata, &krs, sizeof (krs), md) != 0) {
+ return (EFAULT);
+ }
+
+ struct viona_ring_params params;
+ int err = viona_ring_get_state(link, krs.vrs_index, &params);
+ if (err != 0) {
+ return (err);
+ }
+ krs.vrs_qsize = params.vrp_size;
+ krs.vrs_qaddr = params.vrp_pa;
+ krs.vrs_avail_idx = params.vrp_avail_idx;
+ krs.vrs_used_idx = params.vrp_used_idx;
+
+ if (ddi_copyout(&krs, udata, sizeof (krs), md) != 0) {
+ return (EFAULT);
+ }
+ return (0);
+}
+
+static int
viona_ioc_ring_reset(viona_link_t *link, uint_t idx)
{
viona_vring_t *ring;
@@ -909,6 +985,17 @@ viona_ioc_ring_kick(viona_link_t *link, uint_t idx)
}
static int
+viona_ioc_ring_pause(viona_link_t *link, uint_t idx)
+{
+ if (idx >= VIONA_VQ_MAX) {
+ return (EINVAL);
+ }
+
+ viona_vring_t *ring = &link->l_vrings[idx];
+ return (viona_ring_pause(ring));
+}
+
+static int
viona_ioc_ring_set_msi(viona_link_t *link, void *data, int md)
{
vioc_ring_msi_t vrm;
@@ -935,21 +1022,33 @@ viona_notify_iop(void *arg, bool in, uint16_t port, uint8_t bytes,
uint32_t *val)
{
viona_link_t *link = (viona_link_t *)arg;
- uint16_t vq = *val;
- if (in) {
- /*
- * Do not service read (in/ins) requests on this ioport.
- * Instead, indicate that the handler is not found, causing a
- * fallback to userspace processing.
- */
+ /*
+ * If the request is a read (in/ins), or direct at a port other than
+ * what we expect to be registered on, ignore it.
+ */
+ if (in || port != link->l_notify_ioport) {
return (ESRCH);
}
- if (port != link->l_notify_ioport) {
- return (EINVAL);
+ /* Let userspace handle notifications for rings other than RX/TX. */
+ const uint16_t vq = *val;
+ if (vq >= VIONA_VQ_MAX) {
+ return (ESRCH);
}
- return (viona_ioc_ring_kick(link, vq));
+
+ viona_vring_t *ring = &link->l_vrings[vq];
+ int res = 0;
+
+ mutex_enter(&ring->vr_lock);
+ if (ring->vr_state == VRS_RUN) {
+ cv_broadcast(&ring->vr_cv);
+ } else {
+ res = ESRCH;
+ }
+ mutex_exit(&ring->vr_lock);
+
+ return (res);
}
static int
diff --git a/usr/src/uts/intel/io/viona/viona_ring.c b/usr/src/uts/intel/io/viona/viona_ring.c
index 2d847dda09..9339f805d4 100644
--- a/usr/src/uts/intel/io/viona/viona_ring.c
+++ b/usr/src/uts/intel/io/viona/viona_ring.c
@@ -35,7 +35,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2022 Oxide Computer Company
*/
@@ -281,15 +281,19 @@ viona_ring_free(viona_vring_t *ring)
}
int
-viona_ring_init(viona_link_t *link, uint16_t idx, uint16_t qsz, uint64_t pa)
+viona_ring_init(viona_link_t *link, uint16_t idx,
+ const struct viona_ring_params *params)
{
viona_vring_t *ring;
kthread_t *t;
int err = 0;
+ const uint16_t qsz = params->vrp_size;
+ const uint64_t pa = params->vrp_pa;
if (idx >= VIONA_VQ_MAX) {
return (EINVAL);
}
+
if (qsz == 0 || qsz > VRING_MAX_LEN || (1 << (ffs(qsz) - 1)) != qsz) {
return (EINVAL);
}
@@ -320,8 +324,8 @@ viona_ring_init(viona_link_t *link, uint16_t idx, uint16_t qsz, uint64_t pa)
}
/* Initialize queue indexes */
- ring->vr_cur_aidx = 0;
- ring->vr_cur_uidx = 0;
+ ring->vr_cur_aidx = params->vrp_avail_idx;
+ ring->vr_cur_uidx = params->vrp_used_idx;
if (idx == VIONA_VQ_TX) {
viona_tx_ring_alloc(ring, qsz);
@@ -351,11 +355,48 @@ fail:
ring->vr_size = 0;
ring->vr_mask = 0;
ring->vr_pa = 0;
+ ring->vr_cur_aidx = 0;
+ ring->vr_cur_uidx = 0;
mutex_exit(&ring->vr_lock);
return (err);
}
int
+viona_ring_get_state(viona_link_t *link, uint16_t idx,
+ struct viona_ring_params *params)
+{
+ viona_vring_t *ring;
+
+ if (idx >= VIONA_VQ_MAX) {
+ return (EINVAL);
+ }
+
+ ring = &link->l_vrings[idx];
+ mutex_enter(&ring->vr_lock);
+
+ params->vrp_size = ring->vr_size;
+ params->vrp_pa = ring->vr_pa;
+
+ if (ring->vr_state == VRS_RUN) {
+ /* On a running ring, we must heed the avail/used locks */
+ mutex_enter(&ring->vr_a_mutex);
+ params->vrp_avail_idx = ring->vr_cur_aidx;
+ mutex_exit(&ring->vr_a_mutex);
+ mutex_enter(&ring->vr_u_mutex);
+ params->vrp_used_idx = ring->vr_cur_uidx;
+ mutex_exit(&ring->vr_u_mutex);
+ } else {
+ /* Otherwise vr_lock is adequate protection */
+ params->vrp_avail_idx = ring->vr_cur_aidx;
+ params->vrp_used_idx = ring->vr_cur_uidx;
+ }
+
+ mutex_exit(&ring->vr_lock);
+
+ return (0);
+}
+
+int
viona_ring_reset(viona_vring_t *ring, boolean_t heed_signals)
{
mutex_enter(&ring->vr_lock);
@@ -485,40 +526,152 @@ viona_intr_ring(viona_vring_t *ring, boolean_t skip_flags_check)
}
}
+static inline bool
+vring_stop_req(const viona_vring_t *ring)
+{
+ return ((ring->vr_state_flags & VRSF_REQ_STOP) != 0);
+}
+
+static inline bool
+vring_pause_req(const viona_vring_t *ring)
+{
+ return ((ring->vr_state_flags & VRSF_REQ_PAUSE) != 0);
+}
+
+static inline bool
+vring_start_req(const viona_vring_t *ring)
+{
+ return ((ring->vr_state_flags & VRSF_REQ_START) != 0);
+}
+
+/*
+ * Check if vring worker thread should bail out. This will heed indications
+ * that the containing process is exiting, as well as requests to stop or pause
+ * the ring. The `stop_only` parameter controls if pause requests are ignored
+ * (true) or checked (false).
+ *
+ * Caller should hold vr_lock.
+ */
+static bool
+vring_need_bail_ext(const viona_vring_t *ring, bool stop_only)
+{
+ ASSERT(MUTEX_HELD(&ring->vr_lock));
+
+ if (vring_stop_req(ring) ||
+ (!stop_only && vring_pause_req(ring))) {
+ return (true);
+ }
+
+ kthread_t *t = ring->vr_worker_thread;
+ if (t != NULL) {
+ proc_t *p = ttoproc(t);
+
+ ASSERT(p != NULL);
+ if ((p->p_flag & SEXITING) != 0) {
+ return (true);
+ }
+ }
+ return (false);
+}
+
+bool
+vring_need_bail(const viona_vring_t *ring)
+{
+ return (vring_need_bail_ext(ring, false));
+}
+
+int
+viona_ring_pause(viona_vring_t *ring)
+{
+ mutex_enter(&ring->vr_lock);
+ switch (ring->vr_state) {
+ case VRS_RESET:
+ case VRS_SETUP:
+ case VRS_INIT:
+ /*
+ * For rings which have not yet started (even those in the
+ * VRS_SETUP and VRS_INIT phases, where there a running worker
+ * thread (waiting to be released to do its intended task), it
+ * is adequate to simply clear any start request, to keep them
+ * from proceeding into the actual work processing function.
+ */
+ ring->vr_state_flags &= ~VRSF_REQ_START;
+ mutex_exit(&ring->vr_lock);
+ return (0);
+
+ case VRS_STOP:
+ if ((ring->vr_state_flags & VRSF_REQ_STOP) != 0) {
+ /* A ring on its way to RESET cannot be paused. */
+ mutex_exit(&ring->vr_lock);
+ return (EBUSY);
+ }
+ /* FALLTHROUGH */
+ case VRS_RUN:
+ ring->vr_state_flags |= VRSF_REQ_PAUSE;
+ cv_broadcast(&ring->vr_cv);
+ break;
+
+ default:
+ panic("invalid ring state %d", ring->vr_state);
+ break;
+ }
+
+ for (;;) {
+ int res = cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
+
+ if (ring->vr_state == VRS_INIT ||
+ (ring->vr_state_flags & VRSF_REQ_PAUSE) == 0) {
+ /* Ring made it to (or through) paused state */
+ mutex_exit(&ring->vr_lock);
+ return (0);
+ }
+ if (res == 0) {
+ /* interrupted by signal */
+ mutex_exit(&ring->vr_lock);
+ return (EINTR);
+ }
+ }
+ /* NOTREACHED */
+}
+
static void
viona_worker(void *arg)
{
viona_vring_t *ring = (viona_vring_t *)arg;
viona_link_t *link = ring->vr_link;
- proc_t *p = ttoproc(curthread);
mutex_enter(&ring->vr_lock);
VERIFY3U(ring->vr_state, ==, VRS_SETUP);
/* Bail immediately if ring shutdown or process exit was requested */
- if (VRING_NEED_BAIL(ring, p)) {
- goto cleanup;
+ if (vring_need_bail_ext(ring, true)) {
+ goto ring_reset;
}
/* Report worker thread as alive and notify creator */
+ring_init:
ring->vr_state = VRS_INIT;
cv_broadcast(&ring->vr_cv);
- while (ring->vr_state_flags == 0) {
+ while (!vring_start_req(ring)) {
/*
* Keeping lease renewals timely while waiting for the ring to
* be started is important for avoiding deadlocks.
*/
if (vmm_drv_lease_expired(ring->vr_lease)) {
if (!viona_ring_lease_renew(ring)) {
- goto cleanup;
+ goto ring_reset;
}
}
(void) cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
- if (VRING_NEED_BAIL(ring, p)) {
- goto cleanup;
+ if (vring_pause_req(ring)) {
+ /* We are already paused in the INIT state. */
+ ring->vr_state_flags &= ~VRSF_REQ_PAUSE;
+ }
+ if (vring_need_bail_ext(ring, true)) {
+ goto ring_reset;
}
}
@@ -529,7 +682,7 @@ viona_worker(void *arg)
/* Ensure ring lease is valid first */
if (vmm_drv_lease_expired(ring->vr_lease)) {
if (!viona_ring_lease_renew(ring)) {
- goto cleanup;
+ goto ring_reset;
}
}
@@ -543,15 +696,18 @@ viona_worker(void *arg)
}
VERIFY3U(ring->vr_state, ==, VRS_STOP);
+ VERIFY3U(ring->vr_xfer_outstanding, ==, 0);
-cleanup:
- if (ring->vr_txdesb != NULL) {
- /*
- * Transmit activity must be entirely concluded before the
- * associated descriptors can be cleaned up.
- */
- VERIFY(ring->vr_xfer_outstanding == 0);
+ /* Respond to a pause request if the ring is not required to stop */
+ if (vring_pause_req(ring)) {
+ ring->vr_state_flags &= ~VRSF_REQ_PAUSE;
+
+ if (!vring_need_bail_ext(ring, true)) {
+ goto ring_init;
+ }
}
+
+ring_reset:
viona_ring_misc_free(ring);
viona_ring_lease_drop(ring);
diff --git a/usr/src/uts/intel/io/viona/viona_rx.c b/usr/src/uts/intel/io/viona/viona_rx.c
index 2fbf6be972..e6f6f421d5 100644
--- a/usr/src/uts/intel/io/viona/viona_rx.c
+++ b/usr/src/uts/intel/io/viona/viona_rx.c
@@ -35,7 +35,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2022 Oxide Computer Company
*/
#include <sys/types.h>
@@ -86,8 +86,6 @@ viona_rx_fini(void)
void
viona_worker_rx(viona_vring_t *ring, viona_link_t *link)
{
- proc_t *p = ttoproc(curthread);
-
(void) thread_vsetname(curthread, "viona_rx_%p", ring);
ASSERT(MUTEX_HELD(&ring->vr_lock));
@@ -122,7 +120,7 @@ viona_worker_rx(viona_vring_t *ring, viona_link_t *link)
* place to inject frames into the guest.
*/
(void) cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
- } while (!VRING_NEED_BAIL(ring, p));
+ } while (!vring_need_bail(ring));
ring->vr_state = VRS_STOP;
diff --git a/usr/src/uts/intel/io/viona/viona_tx.c b/usr/src/uts/intel/io/viona/viona_tx.c
index 277ee521a1..306c6f308e 100644
--- a/usr/src/uts/intel/io/viona/viona_tx.c
+++ b/usr/src/uts/intel/io/viona/viona_tx.c
@@ -35,7 +35,7 @@
*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
- * Copyright 2021 Oxide Computer Company
+ * Copyright 2022 Oxide Computer Company
*/
@@ -179,11 +179,11 @@ viona_tx_done(viona_vring_t *ring, uint32_t len, uint16_t cookie)
viona_intr_ring(ring, B_FALSE);
}
+#define TX_BURST_THRESH 32
+
void
viona_worker_tx(viona_vring_t *ring, viona_link_t *link)
{
- proc_t *p = ttoproc(curthread);
-
(void) thread_vsetname(curthread, "viona_tx_%p", ring);
ASSERT(MUTEX_HELD(&ring->vr_lock));
@@ -192,23 +192,30 @@ viona_worker_tx(viona_vring_t *ring, viona_link_t *link)
mutex_exit(&ring->vr_lock);
for (;;) {
- boolean_t bail = B_FALSE;
- boolean_t renew = B_FALSE;
- uint_t ntx = 0;
+ uint_t ntx = 0, burst = 0;
viona_ring_disable_notify(ring);
- while (viona_ring_num_avail(ring)) {
+ while (viona_ring_num_avail(ring) != 0) {
viona_tx(link, ring);
+ ntx++;
+ burst++;
/*
* It is advantageous for throughput to keep this
* transmission loop tight, but periodic breaks to
* check for other events are of value too.
*/
- if (ntx++ >= ring->vr_size)
- break;
+ if (burst >= TX_BURST_THRESH) {
+ mutex_enter(&ring->vr_lock);
+ const bool need_bail = vring_need_bail(ring);
+ mutex_exit(&ring->vr_lock);
+
+ if (need_bail) {
+ break;
+ }
+ burst = 0;
+ }
}
- viona_ring_enable_notify(ring);
VIONA_PROBE2(tx, viona_link_t *, link, uint_t, ntx);
@@ -219,14 +226,11 @@ viona_worker_tx(viona_vring_t *ring, viona_link_t *link)
* The barrier ensures that visibility of the no-notify
* store does not cross the viona_ring_num_avail() check below.
*/
+ viona_ring_enable_notify(ring);
membar_enter();
- bail = VRING_NEED_BAIL(ring, p);
- renew = vmm_drv_lease_expired(ring->vr_lease);
- if (!bail && !renew && viona_ring_num_avail(ring)) {
- continue;
- }
- if ((link->l_features & VIRTIO_F_RING_NOTIFY_ON_EMPTY) != 0) {
+ if (viona_ring_num_avail(ring) == 0 &&
+ (link->l_features & VIRTIO_F_RING_NOTIFY_ON_EMPTY) != 0) {
/*
* The NOTIFY_ON_EMPTY interrupt should not pay heed to
* the presence of AVAIL_NO_INTERRUPT.
@@ -235,36 +239,43 @@ viona_worker_tx(viona_vring_t *ring, viona_link_t *link)
}
mutex_enter(&ring->vr_lock);
+ for (;;) {
+ if (vring_need_bail(ring)) {
+ ring->vr_state = VRS_STOP;
+ viona_tx_wait_outstanding(ring);
+ return;
+ }
- while (!bail && !renew && !viona_ring_num_avail(ring)) {
- (void) cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
- bail = VRING_NEED_BAIL(ring, p);
- renew = vmm_drv_lease_expired(ring->vr_lease);
- }
-
- if (bail) {
- break;
- } else if (renew) {
- ring->vr_state_flags |= VRSF_RENEW;
- /*
- * When renewing the lease for the ring, no TX
- * frames may be outstanding, as they contain
- * references to guest memory.
- */
- viona_tx_wait_outstanding(ring);
+ if (vmm_drv_lease_expired(ring->vr_lease)) {
+ ring->vr_state_flags |= VRSF_RENEW;
+ /*
+ * When renewing the lease for the ring, no TX
+ * frames may be outstanding, as they contain
+ * references to guest memory.
+ */
+ viona_tx_wait_outstanding(ring);
+
+ const boolean_t renewed =
+ viona_ring_lease_renew(ring);
+ ring->vr_state_flags &= ~VRSF_RENEW;
+
+ if (!renewed) {
+ /* stop ring on failed renewal */
+ ring->vr_state = VRS_STOP;
+ return;
+ }
+ }
- if (!viona_ring_lease_renew(ring)) {
+ if (viona_ring_num_avail(ring) != 0) {
break;
}
- ring->vr_state_flags &= ~VRSF_RENEW;
+
+ /* Wait for further activity on the ring */
+ (void) cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
}
mutex_exit(&ring->vr_lock);
}
-
- ASSERT(MUTEX_HELD(&ring->vr_lock));
-
- ring->vr_state = VRS_STOP;
- viona_tx_wait_outstanding(ring);
+ /* UNREACHABLE */
}
static void
diff --git a/usr/src/uts/intel/io/vmm/vmm_sol_dev.c b/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
index ee07779b21..da83735e43 100644
--- a/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
+++ b/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
@@ -2239,6 +2239,24 @@ vmm_drv_purge(vmm_softc_t *sc)
hold = list_next(&sc->vmm_holds, hold)) {
hold->vmh_release_req = B_TRUE;
}
+
+ /*
+ * Require that all leases on the instance be broken, now that
+ * all associated holds have been marked as needing release.
+ *
+ * Dropping vmm_mtx is not strictly necessary, but if any of the
+ * lessees are slow to respond, it would be nice to leave it
+ * available for other parties.
+ */
+ mutex_exit(&vmm_mtx);
+ vmm_lease_block(sc);
+ vmm_lease_unblock(sc);
+ mutex_enter(&vmm_mtx);
+
+ /*
+ * With all of the leases broken, we can proceed in an orderly
+ * fashion to waiting for any lingering holds to be dropped.
+ */
while ((sc->vmm_flags & VMM_HELD) != 0) {
if (cv_wait_sig(&sc->vmm_cv, &vmm_mtx) <= 0) {
return (EINTR);
diff --git a/usr/src/uts/intel/sys/viona_io.h b/usr/src/uts/intel/sys/viona_io.h
index 46cc72eb06..761445986c 100644
--- a/usr/src/uts/intel/sys/viona_io.h
+++ b/usr/src/uts/intel/sys/viona_io.h
@@ -12,6 +12,7 @@
/*
* Copyright 2013 Pluribus Networks Inc.
* Copyright 2018 Joyent, Inc.
+ * Copyright 2022 Oxide Computer Company
*/
#ifndef _VIONA_IO_H_
@@ -20,18 +21,39 @@
#define VNA_IOC (('V' << 16)|('C' << 8))
#define VNA_IOC_CREATE (VNA_IOC | 0x01)
#define VNA_IOC_DELETE (VNA_IOC | 0x02)
+#define VNA_IOC_VERSION (VNA_IOC | 0x03)
#define VNA_IOC_RING_INIT (VNA_IOC | 0x10)
#define VNA_IOC_RING_RESET (VNA_IOC | 0x11)
#define VNA_IOC_RING_KICK (VNA_IOC | 0x12)
#define VNA_IOC_RING_SET_MSI (VNA_IOC | 0x13)
#define VNA_IOC_RING_INTR_CLR (VNA_IOC | 0x14)
+#define VNA_IOC_RING_SET_STATE (VNA_IOC | 0x15)
+#define VNA_IOC_RING_GET_STATE (VNA_IOC | 0x16)
+#define VNA_IOC_RING_PAUSE (VNA_IOC | 0x17)
#define VNA_IOC_INTR_POLL (VNA_IOC | 0x20)
#define VNA_IOC_SET_FEATURES (VNA_IOC | 0x21)
#define VNA_IOC_GET_FEATURES (VNA_IOC | 0x22)
#define VNA_IOC_SET_NOTIFY_IOP (VNA_IOC | 0x23)
+
+/*
+ * Viona Interface Version
+ *
+ * Like bhyve, viona exposes Private interfaces which are nonetheless consumed
+ * by out-of-gate consumers. While those consumers assume all risk of breakage
+ * incurred by subsequent changes, it would be nice to equip them to potentially
+ * detect (and handle) those modifications.
+ *
+ * There are no established criteria for the magnitude of change which requires
+ * this version to be incremented, and maintenance of it is considered a
+ * best-effort activity. Nothing is to be inferred about the magnitude of a
+ * change when the version is modified. It follows no rules like semver.
+ *
+ */
+#define VIONA_CURRENT_INTERFACE_VERSION 1
+
typedef struct vioc_create {
datalink_id_t c_linkid;
int c_vmfd;
@@ -43,6 +65,14 @@ typedef struct vioc_ring_init {
uint64_t ri_qaddr;
} vioc_ring_init_t;
+typedef struct vioc_ring_state {
+ uint16_t vrs_index;
+ uint16_t vrs_avail_idx;
+ uint16_t vrs_used_idx;
+ uint16_t vrs_qsize;
+ uint64_t vrs_qaddr;
+} vioc_ring_state_t;
+
typedef struct vioc_ring_msi {
uint16_t rm_index;
uint64_t rm_addr;