Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_passthru.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <sysexits.h> | #include <sysexits.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <machine/vmm.h> | #include <machine/vmm.h> | ||||
#include <vmmapi.h> | #include <vmmapi.h> | ||||
#include "config.h" | |||||
#include "debug.h" | |||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "mem.h" | #include "mem.h" | ||||
#ifndef _PATH_DEVPCI | #ifndef _PATH_DEVPCI | ||||
#define _PATH_DEVPCI "/dev/pci" | #define _PATH_DEVPCI "/dev/pci" | ||||
#endif | #endif | ||||
#ifndef _PATH_DEVIO | #ifndef _PATH_DEVIO | ||||
▲ Show 20 Lines • Show All 573 Lines • ▼ Show 20 Lines | pci_set_cfgdata16(pi, PCIR_COMMAND, read_config(&sc->psc_sel, | ||||
PCIR_COMMAND, 2)); | PCIR_COMMAND, 2)); | ||||
error = 0; /* success */ | error = 0; /* success */ | ||||
done: | done: | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | passthru_legacy_config(nvlist_t *nvl, const char *opts) | ||||
{ | { | ||||
char value[16]; | |||||
int bus, slot, func; | |||||
if (opts == NULL) | |||||
return (0); | |||||
if (sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) { | |||||
EPRINTLN("passthru: invalid options \"%s\"", opts); | |||||
return (-1); | |||||
} | |||||
snprintf(value, sizeof(value), "%d", bus); | |||||
set_config_value_node(nvl, "bus", value); | |||||
snprintf(value, sizeof(value), "%d", slot); | |||||
set_config_value_node(nvl, "slot", value); | |||||
snprintf(value, sizeof(value), "%d", func); | |||||
set_config_value_node(nvl, "func", value); | |||||
return (0); | |||||
} | |||||
static int | |||||
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | |||||
{ | |||||
int bus, slot, func, error, memflags; | int bus, slot, func, error, memflags; | ||||
struct passthru_softc *sc; | struct passthru_softc *sc; | ||||
const char *value; | |||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
cap_ioctl_t pci_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR }; | cap_ioctl_t pci_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR }; | ||||
cap_ioctl_t io_ioctls[] = { IODEV_PIO }; | cap_ioctl_t io_ioctls[] = { IODEV_PIO }; | ||||
#endif | #endif | ||||
sc = NULL; | sc = NULL; | ||||
error = 1; | error = 1; | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_clear(&rights, CAP_IOCTL); | cap_rights_clear(&rights, CAP_IOCTL); | ||||
cap_rights_set(&rights, CAP_MMAP_RW); | cap_rights_set(&rights, CAP_MMAP_RW); | ||||
if (caph_rights_limit(memfd, &rights) == -1) | if (caph_rights_limit(memfd, &rights) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
#endif | #endif | ||||
if (opts == NULL || | #define GET_INT_CONFIG(var, name) do { \ | ||||
sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) { | value = get_config_value_node(nvl, name); \ | ||||
warnx("invalid passthru options"); | if (value == NULL) { \ | ||||
return (error); | EPRINTLN("passthru: missing required %s setting", name); \ | ||||
} | return (error); \ | ||||
} \ | |||||
var = atoi(value); \ | |||||
} while (0) | |||||
GET_INT_CONFIG(bus, "bus"); | |||||
GET_INT_CONFIG(slot, "slot"); | |||||
GET_INT_CONFIG(func, "func"); | |||||
if (vm_assign_pptdev(ctx, bus, slot, func) != 0) { | if (vm_assign_pptdev(ctx, bus, slot, func) != 0) { | ||||
warnx("PCI device at %d/%d/%d is not using the ppt(4) driver", | warnx("PCI device at %d/%d/%d is not using the ppt(4) driver", | ||||
bus, slot, func); | bus, slot, func); | ||||
goto done; | goto done; | ||||
} | } | ||||
sc = calloc(1, sizeof(struct passthru_softc)); | sc = calloc(1, sizeof(struct passthru_softc)); | ||||
▲ Show 20 Lines • Show All 219 Lines • ▼ Show 20 Lines | passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, | ||||
} | } | ||||
return (val); | return (val); | ||||
} | } | ||||
struct pci_devemu passthru = { | struct pci_devemu passthru = { | ||||
.pe_emu = "passthru", | .pe_emu = "passthru", | ||||
.pe_init = passthru_init, | .pe_init = passthru_init, | ||||
.pe_legacy_config = passthru_legacy_config, | |||||
.pe_cfgwrite = passthru_cfgwrite, | .pe_cfgwrite = passthru_cfgwrite, | ||||
.pe_cfgread = passthru_cfgread, | .pe_cfgread = passthru_cfgread, | ||||
.pe_barwrite = passthru_write, | .pe_barwrite = passthru_write, | ||||
.pe_barread = passthru_read, | .pe_barread = passthru_read, | ||||
}; | }; | ||||
PCI_EMUL_SET(passthru); | PCI_EMUL_SET(passthru); |