Page MenuHomeFreeBSD

D31534.id93662.diff
No OneTemporary

D31534.id93662.diff

Index: usr.sbin/bhyve/pci_passthru.c
===================================================================
--- usr.sbin/bhyve/pci_passthru.c
+++ usr.sbin/bhyve/pci_passthru.c
@@ -43,7 +43,10 @@
#include <dev/io/iodev.h>
#include <dev/pci/pcireg.h>
+#include <vm/vm.h>
+
#include <machine/iodev.h>
+#include <machine/vm.h>
#ifndef WITHOUT_CAPSICUM
#include <capsicum_helpers.h>
@@ -79,7 +82,6 @@
#define MSIX_CAPLEN 12
static int pcifd = -1;
-static int memfd = -1;
struct passthru_softc {
struct pci_devinst *psc_pi;
@@ -435,13 +437,12 @@
static int
init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base)
{
- int b, s, f;
- int idx;
- size_t remaining;
- uint32_t table_size, table_offset;
- uint32_t pba_size, pba_offset;
- vm_paddr_t start;
struct pci_devinst *pi = sc->psc_pi;
+ struct pci_bar_mmap pbm;
+ void *addr;
+ size_t remaining;
+ int b, s, f, idx;
+ uint32_t map_offset, pba_size, pba_offset, table_size, table_offset;
assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0);
@@ -462,7 +463,6 @@
table_size = roundup2(table_size, 4096);
idx = pi->pi_msix.table_bar;
- start = pi->pi_bar[idx].addr;
remaining = pi->pi_bar[idx].size;
if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar) {
@@ -477,25 +477,39 @@
pi->pi_msix.pba_page = NULL;
pi->pi_msix.pba_page_offset = 0;
} else {
- /*
- * The PBA overlaps with either the first or last
- * page of the MSI-X table region. Map the
- * appropriate page.
- */
- if (pba_offset <= table_offset)
- pi->pi_msix.pba_page_offset = table_offset;
- else
- pi->pi_msix.pba_page_offset = table_offset +
- table_size - 4096;
- pi->pi_msix.pba_page = mmap(NULL, 4096, PROT_READ |
- PROT_WRITE, MAP_SHARED, memfd, start +
- pi->pi_msix.pba_page_offset);
- if (pi->pi_msix.pba_page == MAP_FAILED) {
+ memset(&pbm, 0, sizeof(pbm));
+ pbm.pbm_sel = sc->psc_sel;
+ pbm.pbm_flags = PCIIO_BAR_MMAP_RW;
+ pbm.pbm_reg = PCIR_BAR(pi->pi_msix.pba_bar);
+ pbm.pbm_memattr = VM_MEMATTR_UNCACHEABLE;
+
+ if (ioctl(pcifd, PCIOCBARMMAP, &pbm) != 0) {
warn(
"Failed to map PBA page for MSI-X on %d/%d/%d",
b, s, f);
return (-1);
}
+
+ /*
+ * The PBA overlaps with either the first or last
+ * page of the MSI-X table region.
+ */
+ assert(pbm.pbm_bar_off == 0);
+ addr = (void *)(uintptr_t)pbm.pbm_map_base;
+ if (pba_offset <= table_offset)
+ map_offset = table_offset;
+ else
+ map_offset = table_offset + table_size - 4096;
+ pi->pi_msix.pba_page = (uint8_t *)addr + map_offset;
+ pi->pi_msix.pba_page_offset = map_offset;
+
+ /*
+ * PCIOCBARMMAP maps the entire BAR, remove what we
+ * don't need.
+ */
+ (void)munmap(addr, map_offset);
+ (void)munmap((uint8_t *)addr + map_offset + 4096,
+ pbm.pbm_map_length - (map_offset + 4096));
}
}
@@ -645,7 +659,7 @@
#ifndef WITHOUT_CAPSICUM
cap_rights_t rights;
cap_ioctl_t pci_ioctls[] =
- { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR, PCIOCBARIO };
+ { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR, PCIOCBARIO, PCIOCBARMMAP };
#endif
sc = NULL;
@@ -676,21 +690,6 @@
errx(EX_OSERR, "Unable to apply rights for sandbox");
#endif
- if (memfd < 0) {
- memfd = open(_PATH_MEM, O_RDWR, 0);
- if (memfd < 0) {
- warn("failed to open %s", _PATH_MEM);
- return (error);
- }
- }
-
-#ifndef WITHOUT_CAPSICUM
- cap_rights_clear(&rights, CAP_IOCTL);
- cap_rights_set(&rights, CAP_MMAP_RW);
- if (caph_rights_limit(memfd, &rights) == -1)
- errx(EX_OSERR, "Unable to apply rights for sandbox");
-#endif
-
#define GET_INT_CONFIG(var, name) do { \
value = get_config_value_node(nvl, name); \
if (value == NULL) { \

File Metadata

Mime Type
text/plain
Expires
Tue, Jun 16, 12:28 PM (4 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33987403
Default Alt Text
D31534.id93662.diff (3 KB)

Event Timeline