Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_console.c
Show First 20 Lines • Show All 267 Lines • ▼ Show 20 Lines | pci_vtcon_port_add(struct pci_vtcon_softc *sc, int port_id, const char *name, | ||||
} | } | ||||
port->vsp_enabled = true; | port->vsp_enabled = true; | ||||
return (port); | return (port); | ||||
} | } | ||||
static int | static int | ||||
pci_vtcon_sock_add(struct pci_vtcon_softc *sc, const char *port_name, | pci_vtcon_sock_add(struct pci_vtcon_softc *sc, const char *port_name, | ||||
const nvlist_t *nvl) | const config_node_t *node) | ||||
{ | { | ||||
struct pci_vtcon_sock *sock; | struct pci_vtcon_sock *sock; | ||||
struct sockaddr_un sun; | struct sockaddr_un sun; | ||||
const char *name, *path; | const char *name, *path; | ||||
char *cp, *pathcopy; | char *cp, *pathcopy; | ||||
long port; | long port; | ||||
int s = -1, fd = -1, error = 0; | int s = -1, fd = -1, error = 0; | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
#endif | #endif | ||||
port = strtol(port_name, &cp, 0); | port = strtol(port_name, &cp, 0); | ||||
if (*cp != '\0' || port < 0 || port >= VTCON_MAXPORTS) { | if (*cp != '\0' || port < 0 || port >= VTCON_MAXPORTS) { | ||||
EPRINTLN("vtcon: Invalid port %s", port_name); | EPRINTLN("vtcon: Invalid port %s", port_name); | ||||
error = -1; | error = -1; | ||||
goto out; | goto out; | ||||
} | } | ||||
path = get_config_value_node(nvl, "path"); | path = get_config_value_node(node, "path"); | ||||
if (path == NULL) { | if (path == NULL) { | ||||
EPRINTLN("vtcon: required path missing for port %ld", port); | EPRINTLN("vtcon: required path missing for port %ld", port); | ||||
error = -1; | error = -1; | ||||
goto out; | goto out; | ||||
} | } | ||||
sock = calloc(1, sizeof(struct pci_vtcon_sock)); | sock = calloc(1, sizeof(struct pci_vtcon_sock)); | ||||
if (sock == NULL) { | if (sock == NULL) { | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE); | cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE); | ||||
if (caph_rights_limit(s, &rights) == -1) | if (caph_rights_limit(s, &rights) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
#endif | #endif | ||||
name = get_config_value_node(nvl, "name"); | name = get_config_value_node(node, "name"); | ||||
if (name == NULL) { | if (name == NULL) { | ||||
EPRINTLN("vtcon: required name missing for port %ld", port); | EPRINTLN("vtcon: required name missing for port %ld", port); | ||||
error = -1; | error = -1; | ||||
goto out; | goto out; | ||||
} | } | ||||
sock->vss_port = pci_vtcon_port_add(sc, port, name, pci_vtcon_sock_tx, sock); | sock->vss_port = pci_vtcon_port_add(sc, port, name, pci_vtcon_sock_tx, sock); | ||||
if (sock->vss_port == NULL) { | if (sock->vss_port == NULL) { | ||||
error = -1; | error = -1; | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | pci_vtcon_notify_rx(void *vsc, struct vqueue_info *vq) | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Each console device has a "port" node which contains nodes for | * Each console device has a "port" node which contains nodes for | ||||
* each port. Ports are numbered starting at 0. | * each port. Ports are numbered starting at 0. | ||||
*/ | */ | ||||
static int | static int | ||||
pci_vtcon_legacy_config_port(nvlist_t *nvl, int port, char *opt) | pci_vtcon_legacy_config_port(config_node_t *node, int port, char *opt) | ||||
{ | { | ||||
char *name, *path; | char *name, *path; | ||||
char node_name[sizeof("XX")]; | char node_name[sizeof("XX")]; | ||||
nvlist_t *port_nvl; | config_node_t *port_node; | ||||
name = strsep(&opt, "="); | name = strsep(&opt, "="); | ||||
path = opt; | path = opt; | ||||
if (path == NULL) { | if (path == NULL) { | ||||
EPRINTLN("vtcon: port %s requires a path", name); | EPRINTLN("vtcon: port %s requires a path", name); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (port >= VTCON_MAXPORTS) { | if (port >= VTCON_MAXPORTS) { | ||||
EPRINTLN("vtcon: too many ports"); | EPRINTLN("vtcon: too many ports"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
snprintf(node_name, sizeof(node_name), "%d", port); | snprintf(node_name, sizeof(node_name), "%d", port); | ||||
port_nvl = create_relative_config_node(nvl, node_name); | port_node = create_relative_config_node(node, node_name); | ||||
set_config_value_node(port_nvl, "name", name); | set_config_value_node(port_node, "name", name); | ||||
set_config_value_node(port_nvl, "path", path); | set_config_value_node(port_node, "path", path); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
pci_vtcon_legacy_config(nvlist_t *nvl, const char *opts) | pci_vtcon_legacy_config(config_node_t *node, const char *opts) | ||||
{ | { | ||||
char *opt, *str, *tofree; | char *opt, *str, *tofree; | ||||
nvlist_t *ports_nvl; | config_node_t *ports_node; | ||||
int error, port; | int error, port; | ||||
ports_nvl = create_relative_config_node(nvl, "port"); | ports_node = create_relative_config_node(node, "port"); | ||||
tofree = str = strdup(opts); | tofree = str = strdup(opts); | ||||
error = 0; | error = 0; | ||||
port = 0; | port = 0; | ||||
while ((opt = strsep(&str, ",")) != NULL) { | while ((opt = strsep(&str, ",")) != NULL) { | ||||
error = pci_vtcon_legacy_config_port(ports_nvl, port, opt); | error = pci_vtcon_legacy_config_port(ports_node, port, opt); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
port++; | port++; | ||||
} | } | ||||
free(tofree); | free(tofree); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, config_node_t *node) | ||||
{ | { | ||||
struct pci_vtcon_softc *sc; | struct pci_vtcon_softc *sc; | ||||
nvlist_t *ports_nvl; | config_node_t *ports_node; | ||||
int i; | int i; | ||||
sc = calloc(1, sizeof(struct pci_vtcon_softc)); | sc = calloc(1, sizeof(struct pci_vtcon_softc)); | ||||
sc->vsc_config = calloc(1, sizeof(struct pci_vtcon_config)); | sc->vsc_config = calloc(1, sizeof(struct pci_vtcon_config)); | ||||
sc->vsc_config->max_nr_ports = VTCON_MAXPORTS; | sc->vsc_config->max_nr_ports = VTCON_MAXPORTS; | ||||
sc->vsc_config->cols = 80; | sc->vsc_config->cols = 80; | ||||
sc->vsc_config->rows = 25; | sc->vsc_config->rows = 25; | ||||
Show All 20 Lines | pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, config_node_t *node) | ||||
/* create control port */ | /* create control port */ | ||||
sc->vsc_control_port.vsp_sc = sc; | sc->vsc_control_port.vsp_sc = sc; | ||||
sc->vsc_control_port.vsp_txq = 2; | sc->vsc_control_port.vsp_txq = 2; | ||||
sc->vsc_control_port.vsp_rxq = 3; | sc->vsc_control_port.vsp_rxq = 3; | ||||
sc->vsc_control_port.vsp_cb = pci_vtcon_control_tx; | sc->vsc_control_port.vsp_cb = pci_vtcon_control_tx; | ||||
sc->vsc_control_port.vsp_enabled = true; | sc->vsc_control_port.vsp_enabled = true; | ||||
ports_nvl = find_relative_config_node(nvl, "port"); | ports_node = find_relative_config_node(node, "port"); | ||||
if (ports_nvl != NULL) { | if (ports_node != NULL) { | ||||
const char *name; | const char *name; | ||||
void *cookie; | void *cookie; | ||||
int type; | int type; | ||||
cookie = NULL; | cookie = NULL; | ||||
while ((name = nvlist_next(ports_nvl, &type, &cookie)) != | while ((name = config_node_next(ports_node, &type, &cookie)) != | ||||
NULL) { | NULL) { | ||||
if (type != NV_TYPE_NVLIST) | if (type != NODE_TYPE_NODE) | ||||
continue; | continue; | ||||
if (pci_vtcon_sock_add(sc, name, | if (pci_vtcon_sock_add(sc, name, | ||||
nvlist_get_nvlist(ports_nvl, name)) < 0) { | find_relative_config_node(ports_node, name)) < 0) { | ||||
EPRINTLN("cannot create port %s: %s", | EPRINTLN("cannot create port %s: %s", | ||||
name, strerror(errno)); | name, strerror(errno)); | ||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
Show All 9 Lines |