aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/bhyve/pci_fbuf.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-06-26 20:30:41 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2021-03-18 23:30:26 +0000
commit621b5090487de9fed1b503769702a9a2a27cc7bb (patch)
treecab0b3b36533c630c011473b0ffbf8806121034a /usr.sbin/bhyve/pci_fbuf.c
parent929acdb19acb67cc0e6ee5439df98e28a84d4772 (diff)
downloadsrc-621b5090487de9fed1b503769702a9a2a27cc7bb.tar.gz
src-621b5090487de9fed1b503769702a9a2a27cc7bb.zip
Diffstat (limited to 'usr.sbin/bhyve/pci_fbuf.c')
-rw-r--r--usr.sbin/bhyve/pci_fbuf.c194
1 files changed, 96 insertions, 98 deletions
diff --git a/usr.sbin/bhyve/pci_fbuf.c b/usr.sbin/bhyve/pci_fbuf.c
index 0bd740a0908c..215ce742edfb 100644
--- a/usr.sbin/bhyve/pci_fbuf.c
+++ b/usr.sbin/bhyve/pci_fbuf.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "bhyvegc.h"
#include "bhyverun.h"
+#include "config.h"
#include "debug.h"
#include "console.h"
#include "inout.h"
@@ -116,15 +117,6 @@ static struct pci_fbuf_softc *fbuf_sc;
#define PCI_FBUF_MSI_MSGS 4
static void
-pci_fbuf_usage(char *opt)
-{
-
- EPRINTLN("Invalid fbuf emulation option \"%s\"", opt);
- EPRINTLN("fbuf: {wait,}{vga=on|io|off,}rfb=<ip>:port"
- "{,w=width}{,h=height}");
-}
-
-static void
pci_fbuf_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
int baridx, uint64_t offset, int size, uint64_t value)
{
@@ -225,102 +217,108 @@ pci_fbuf_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
}
static int
-pci_fbuf_parse_opts(struct pci_fbuf_softc *sc, char *opts)
+pci_fbuf_parse_config(struct pci_fbuf_softc *sc, nvlist_t *nvl)
{
- char *uopts, *uoptsbak, *xopts, *config;
- char *tmpstr;
- int ret;
-
- ret = 0;
- uoptsbak = uopts = strdup(opts);
- while ((xopts = strsep(&uopts, ",")) != NULL) {
- if (strcmp(xopts, "wait") == 0) {
- sc->rfb_wait = 1;
- continue;
- }
-
- if ((config = strchr(xopts, '=')) == NULL) {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
- }
-
- *config++ = '\0';
-
- DPRINTF(DEBUG_VERBOSE, ("pci_fbuf option %s = %s",
- xopts, config));
-
- if (!strcmp(xopts, "tcp") || !strcmp(xopts, "rfb")) {
- /*
- * IPv4 -- host-ip:port
- * IPv6 -- [host-ip%zone]:port
- * XXX for now port is mandatory.
- */
- tmpstr = strsep(&config, "]");
- if (config) {
- if (tmpstr[0] == '[')
- tmpstr++;
- sc->rfb_host = strdup(tmpstr);
- if (config[0] == ':')
- config++;
- else {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
- }
- sc->rfb_port = atoi(config);
- } else {
- config = tmpstr;
- tmpstr = strsep(&config, ":");
- if (!config)
- sc->rfb_port = atoi(tmpstr);
- else {
- sc->rfb_port = atoi(config);
- sc->rfb_host = strdup(tmpstr);
+ const char *value;
+ char *cp;
+
+ sc->rfb_wait = get_config_bool_node_default(nvl, "wait", false);
+
+ /* Prefer "rfb" to "tcp". */
+ value = get_config_value_node(nvl, "rfb");
+ if (value == NULL)
+ value = get_config_value_node(nvl, "tcp");
+ if (value != NULL) {
+ /*
+ * IPv4 -- host-ip:port
+ * IPv6 -- [host-ip%zone]:port
+ * XXX for now port is mandatory for IPv4.
+ */
+ if (value[0] == '[') {
+ cp = strchr(value + 1, ']');
+ if (cp == NULL || cp == value + 1) {
+ EPRINTLN("fbuf: Invalid IPv6 address: \"%s\"",
+ value);
+ return (-1);
+ }
+ sc->rfb_host = strndup(value + 1, cp - (value + 1));
+ cp++;
+ if (*cp == ':') {
+ cp++;
+ if (*cp == '\0') {
+ EPRINTLN(
+ "fbuf: Missing port number: \"%s\"",
+ value);
+ return (-1);
}
+ sc->rfb_port = atoi(cp);
+ } else if (*cp != '\0') {
+ EPRINTLN("fbuf: Invalid IPv6 address: \"%s\"",
+ value);
+ return (-1);
}
- } else if (!strcmp(xopts, "vga")) {
- if (!strcmp(config, "off")) {
- sc->vga_enabled = 0;
- } else if (!strcmp(config, "io")) {
- sc->vga_enabled = 1;
- sc->vga_full = 0;
- } else if (!strcmp(config, "on")) {
- sc->vga_enabled = 1;
- sc->vga_full = 1;
+ } else {
+ cp = strchr(value, ':');
+ if (cp == NULL) {
+ sc->rfb_port = atoi(value);
} else {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
+ sc->rfb_host = strndup(value, cp - value);
+ cp++;
+ if (*cp == '\0') {
+ EPRINTLN(
+ "fbuf: Missing port number: \"%s\"",
+ value);
+ return (-1);
+ }
+ sc->rfb_port = atoi(cp);
}
- } else if (!strcmp(xopts, "w")) {
- sc->memregs.width = atoi(config);
- if (sc->memregs.width > COLS_MAX) {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
- } else if (sc->memregs.width == 0)
- sc->memregs.width = 1920;
- } else if (!strcmp(xopts, "h")) {
- sc->memregs.height = atoi(config);
- if (sc->memregs.height > ROWS_MAX) {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
- } else if (sc->memregs.height == 0)
- sc->memregs.height = 1080;
- } else if (!strcmp(xopts, "password")) {
- sc->rfb_password = strdup(config);
+ }
+ }
+
+ value = get_config_value_node(nvl, "vga");
+ if (value != NULL) {
+ if (strcmp(value, "off") == 0) {
+ sc->vga_enabled = 0;
+ } else if (strcmp(value, "io") == 0) {
+ sc->vga_enabled = 1;
+ sc->vga_full = 0;
+ } else if (strcmp(value, "on") == 0) {
+ sc->vga_enabled = 1;
+ sc->vga_full = 1;
} else {
- pci_fbuf_usage(xopts);
- ret = -1;
- goto done;
+ EPRINTLN("fbuf: Invalid vga setting: \"%s\"", value);
+ return (-1);
}
}
-done:
- free(uoptsbak);
- return (ret);
+ value = get_config_value_node(nvl, "w");
+ if (value != NULL) {
+ sc->memregs.width = atoi(value);
+ if (sc->memregs.width > COLS_MAX) {
+ EPRINTLN("fbuf: width %d too large", sc->memregs.width);
+ return (-1);
+ }
+ if (sc->memregs.width == 0)
+ sc->memregs.width = 1920;
+ }
+
+ value = get_config_value_node(nvl, "h");
+ if (value != NULL) {
+ sc->memregs.height = atoi(value);
+ if (sc->memregs.height > ROWS_MAX) {
+ EPRINTLN("fbuf: height %d too large",
+ sc->memregs.height);
+ return (-1);
+ }
+ if (sc->memregs.height == 0)
+ sc->memregs.height = 1080;
+ }
+
+ value = get_config_value_node(nvl, "password");
+ if (value != NULL)
+ sc->rfb_password = strdup(value);
+
+ return (0);
}
@@ -351,7 +349,7 @@ pci_fbuf_render(struct bhyvegc *gc, void *arg)
}
static int
-pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
+pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
{
int error, prot;
struct pci_fbuf_softc *sc;
@@ -391,7 +389,7 @@ pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
sc->fsc_pi = pi;
- error = pci_fbuf_parse_opts(sc, opts);
+ error = pci_fbuf_parse_config(sc, nvl);
if (error != 0)
goto done;