Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_9p.c
| Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
| #include <unistd.h> | #include <unistd.h> | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <pthread.h> | #include <pthread.h> | ||||
| #include <lib9p.h> | #include <lib9p.h> | ||||
| #include <backend/fs.h> | #include <backend/fs.h> | ||||
| #include "bhyverun.h" | #include "bhyverun.h" | ||||
| #include "config.h" | |||||
| #include "debug.h" | |||||
| #include "pci_emul.h" | #include "pci_emul.h" | ||||
| #include "virtio.h" | #include "virtio.h" | ||||
| #define VT9P_MAX_IOV 128 | #define VT9P_MAX_IOV 128 | ||||
| #define VT9P_RINGSZ 256 | #define VT9P_RINGSZ 256 | ||||
| #define VT9P_MAXTAGSZ 256 | #define VT9P_MAXTAGSZ 256 | ||||
| #define VT9P_CONFIGSPACESZ (VT9P_MAXTAGSZ + sizeof(uint16_t)) | #define VT9P_CONFIGSPACESZ (VT9P_MAXTAGSZ + sizeof(uint16_t)) | ||||
| ▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | for (int i = 0; i < n; i++) { | ||||
| "len=%zu, flags=0x%04x\r\n", i, iov[i].iov_base, | "len=%zu, flags=0x%04x\r\n", i, iov[i].iov_base, | ||||
| iov[i].iov_len, flags[i])); | iov[i].iov_len, flags[i])); | ||||
| } | } | ||||
| l9p_connection_recv(sc->vsc_conn, iov, preq->vsr_respidx, preq); | l9p_connection_recv(sc->vsc_conn, iov, preq->vsr_respidx, preq); | ||||
| } | } | ||||
| } | } | ||||
| static int | |||||
| pci_vt9p_legacy_config(nvlist_t *nvl, const char *opts) | |||||
| { | |||||
| char *sharename, *tofree, *token, *tokens; | |||||
| if (opts == NULL) | |||||
| return (0); | |||||
| tokens = tofree = strdup(opts); | |||||
| while ((token = strsep(&tokens, ",")) != NULL) { | |||||
| if (strchr(token, '=') != NULL) { | |||||
| if (sharename != NULL) { | |||||
| EPRINTLN( | |||||
| "virtio-9p: more than one share name given"); | |||||
| return (-1); | |||||
| } | |||||
| sharename = strsep(&token, "="); | |||||
| set_config_value_node(nvl, "sharename", sharename); | |||||
| set_config_value_node(nvl, "path", token); | |||||
| } else | |||||
| set_config_bool_node(nvl, token, true); | |||||
| } | |||||
| free(tofree); | |||||
| return (0); | |||||
| } | |||||
| static int | static int | ||||
| pci_vt9p_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | pci_vt9p_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
| { | { | ||||
| struct pci_vt9p_softc *sc; | struct pci_vt9p_softc *sc; | ||||
| char *opt; | const char *value; | ||||
| char *sharename = NULL; | const char *sharename; | ||||
| char *rootpath = NULL; | |||||
| int rootfd; | int rootfd; | ||||
| bool ro = false; | bool ro; | ||||
| cap_rights_t rootcap; | cap_rights_t rootcap; | ||||
| if (opts == NULL) { | ro = get_config_bool_node_default(nvl, "ro", false); | ||||
| printf("virtio-9p: share name and path required\n"); | |||||
| return (1); | |||||
| } | |||||
| while ((opt = strsep(&opts, ",")) != NULL) { | value = get_config_value_node(nvl, "path"); | ||||
| if (strchr(opt, '=') != NULL) { | if (value == NULL) { | ||||
| if (sharename != NULL) { | EPRINTLN("virtio-9p: path required"); | ||||
| printf("virtio-9p: more than one share name given\n"); | |||||
| return (1); | return (1); | ||||
| } | } | ||||
| rootfd = open(value, O_DIRECTORY); | |||||
| sharename = strsep(&opt, "="); | if (rootfd < 0) { | ||||
| rootpath = opt; | EPRINTLN("virtio-9p: failed to open '%s': %s", value, | ||||
| continue; | strerror(errno)); | ||||
| return (-1); | |||||
| } | } | ||||
| if (strcmp(opt, "ro") == 0) { | sharename = get_config_value_node(nvl, "sharename"); | ||||
| DPRINTF(("read-only mount requested\r\n")); | if (sharename == NULL) { | ||||
| ro = true; | EPRINTLN("virtio-9p: share name required"); | ||||
| continue; | |||||
| } | |||||
| printf("virtio-9p: invalid option '%s'\n", opt); | |||||
| return (1); | return (1); | ||||
| } | } | ||||
| if (strlen(sharename) > VT9P_MAXTAGSZ) { | if (strlen(sharename) > VT9P_MAXTAGSZ) { | ||||
| printf("virtio-9p: share name too long\n"); | EPRINTLN("virtio-9p: share name too long"); | ||||
| return (1); | return (1); | ||||
| } | } | ||||
| rootfd = open(rootpath, O_DIRECTORY); | |||||
| if (rootfd < 0) | |||||
| return (-1); | |||||
| sc = calloc(1, sizeof(struct pci_vt9p_softc)); | sc = calloc(1, sizeof(struct pci_vt9p_softc)); | ||||
| sc->vsc_config = calloc(1, sizeof(struct pci_vt9p_config) + | sc->vsc_config = calloc(1, sizeof(struct pci_vt9p_config) + | ||||
| VT9P_MAXTAGSZ); | VT9P_MAXTAGSZ); | ||||
| pthread_mutex_init(&sc->vsc_mtx, NULL); | pthread_mutex_init(&sc->vsc_mtx, NULL); | ||||
| cap_rights_init(&rootcap, | cap_rights_init(&rootcap, | ||||
| CAP_LOOKUP, CAP_ACL_CHECK, CAP_ACL_DELETE, CAP_ACL_GET, | CAP_LOOKUP, CAP_ACL_CHECK, CAP_ACL_DELETE, CAP_ACL_GET, | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) | ||||
| return (1); | return (1); | ||||
| vi_set_io_bar(&sc->vsc_vs, 0); | vi_set_io_bar(&sc->vsc_vs, 0); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| struct pci_devemu pci_de_v9p = { | struct pci_devemu pci_de_v9p = { | ||||
| .pe_emu = "virtio-9p", | .pe_emu = "virtio-9p", | ||||
| .pe_legacy_config = pci_vt9p_legacy_config, | |||||
| .pe_init = pci_vt9p_init, | .pe_init = pci_vt9p_init, | ||||
| .pe_barwrite = vi_pci_write, | .pe_barwrite = vi_pci_write, | ||||
| .pe_barread = vi_pci_read | .pe_barread = vi_pci_read | ||||
| }; | }; | ||||
| PCI_EMUL_SET(pci_de_v9p); | PCI_EMUL_SET(pci_de_v9p); | ||||