Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_passthru.c
Show All 26 Lines | |||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#ifndef WITHOUT_CAPSICUM | |||||
#include <sys/capsicum.h> | |||||
#endif | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/pciio.h> | #include <sys/pciio.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <dev/io/iodev.h> | #include <dev/io/iodev.h> | ||||
#include <dev/pci/pcireg.h> | #include <dev/pci/pcireg.h> | ||||
#include <machine/iodev.h> | #include <machine/iodev.h> | ||||
#ifndef WITHOUT_CAPSICUM | |||||
#include <capsicum_helpers.h> | #include <capsicum_helpers.h> | ||||
#endif | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#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> | ||||
▲ Show 20 Lines • Show All 588 Lines • ▼ Show 20 Lines | done: | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | ||||
{ | { | ||||
int bus, slot, func, error, memflags; | int bus, slot, func, error, memflags; | ||||
struct passthru_softc *sc; | struct passthru_softc *sc; | ||||
#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 | |||||
sc = NULL; | sc = NULL; | ||||
error = 1; | error = 1; | ||||
#ifndef WITHOUT_CAPSICUM | |||||
cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE); | cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE); | ||||
#endif | |||||
memflags = vm_get_memflags(ctx); | memflags = vm_get_memflags(ctx); | ||||
if (!(memflags & VM_MEM_F_WIRED)) { | if (!(memflags & VM_MEM_F_WIRED)) { | ||||
warnx("passthru requires guest memory to be wired"); | warnx("passthru requires guest memory to be wired"); | ||||
return (error); | return (error); | ||||
} | } | ||||
if (pcifd < 0) { | if (pcifd < 0) { | ||||
pcifd = open(_PATH_DEVPCI, O_RDWR, 0); | pcifd = open(_PATH_DEVPCI, O_RDWR, 0); | ||||
if (pcifd < 0) { | if (pcifd < 0) { | ||||
warn("failed to open %s", _PATH_DEVPCI); | warn("failed to open %s", _PATH_DEVPCI); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
#ifndef WITHOUT_CAPSICUM | |||||
if (caph_rights_limit(pcifd, &rights) == -1) | if (caph_rights_limit(pcifd, &rights) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
if (caph_ioctls_limit(pcifd, pci_ioctls, nitems(pci_ioctls)) == -1) | if (caph_ioctls_limit(pcifd, pci_ioctls, nitems(pci_ioctls)) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
#endif | |||||
if (iofd < 0) { | if (iofd < 0) { | ||||
iofd = open(_PATH_DEVIO, O_RDWR, 0); | iofd = open(_PATH_DEVIO, O_RDWR, 0); | ||||
if (iofd < 0) { | if (iofd < 0) { | ||||
warn("failed to open %s", _PATH_DEVIO); | warn("failed to open %s", _PATH_DEVIO); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
#ifndef WITHOUT_CAPSICUM | |||||
if (caph_rights_limit(iofd, &rights) == -1) | if (caph_rights_limit(iofd, &rights) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
if (caph_ioctls_limit(iofd, io_ioctls, nitems(io_ioctls)) == -1) | if (caph_ioctls_limit(iofd, io_ioctls, nitems(io_ioctls)) == -1) | ||||
errx(EX_OSERR, "Unable to apply rights for sandbox"); | errx(EX_OSERR, "Unable to apply rights for sandbox"); | ||||
#endif | |||||
if (memfd < 0) { | if (memfd < 0) { | ||||
memfd = open(_PATH_MEM, O_RDWR, 0); | memfd = open(_PATH_MEM, O_RDWR, 0); | ||||
if (memfd < 0) { | if (memfd < 0) { | ||||
warn("failed to open %s", _PATH_MEM); | warn("failed to open %s", _PATH_MEM); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
#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 | |||||
if (opts == NULL || | if (opts == NULL || | ||||
sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) { | sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) { | ||||
warnx("invalid passthru options"); | warnx("invalid passthru options"); | ||||
return (error); | return (error); | ||||
} | } | ||||
if (vm_assign_pptdev(ctx, bus, slot, func) != 0) { | if (vm_assign_pptdev(ctx, bus, slot, func) != 0) { | ||||
▲ Show 20 Lines • Show All 221 Lines • Show Last 20 Lines |