diff options
author | Corvin Köhne <CorvinK@beckhoff.com> | 2021-11-18 15:25:09 +0000 |
---|---|---|
committer | Emmanuel Vadot <manu@FreeBSD.org> | 2021-11-18 15:25:09 +0000 |
commit | e87a6f3ef284593c01e0fd3f8b5bfc1f645e5b18 (patch) | |
tree | 6be8182881a7718f0a9cb05f30a20d424a81e7b0 /usr.sbin | |
parent | f7c526ab3f23e5663cb8477c3dfb41a89de2d4cd (diff) | |
download | src-e87a6f3ef284593c01e0fd3f8b5bfc1f645e5b18.tar.gz src-e87a6f3ef284593c01e0fd3f8b5bfc1f645e5b18.zip |
bhyve: use physical lobits for BARs of passthru devices
Tell the guest whether a BAR uses prefetched memory or not for
passthru devices by using the same lobits as the physical device.
Reviewed by: grehan
Sponsored by: Beckhoff Autmation GmbH & Co. KG
Differential Revision: https://reviews.freebsd.org/D32685
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 16 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_passthru.c | 11 |
3 files changed, 24 insertions, 4 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 86a2f995126e..bd94859c4ea1 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -707,6 +707,15 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, pdi->pi_bar[idx].type = type; pdi->pi_bar[idx].addr = addr; pdi->pi_bar[idx].size = size; + /* + * passthru devices are using same lobits as physical device they set + * this property + */ + if (pdi->pi_bar[idx].lobits != 0) { + lobits = pdi->pi_bar[idx].lobits; + } else { + pdi->pi_bar[idx].lobits = lobits; + } /* Initialize the BAR register in config space */ bar = (addr & mask) | lobits; @@ -1946,7 +1955,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, case PCIBAR_IO: addr = *eax & mask; addr &= 0xffff; - bar = addr | PCIM_BAR_IO_SPACE; + bar = addr | pi->pi_bar[idx].lobits; /* * Register the new BAR value for interception */ @@ -1957,7 +1966,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, break; case PCIBAR_MEM32: addr = bar = *eax & mask; - bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + bar |= pi->pi_bar[idx].lobits; if (addr != pi->pi_bar[idx].addr) { update_bar_address(pi, addr, idx, PCIBAR_MEM32); @@ -1965,8 +1974,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, break; case PCIBAR_MEM64: addr = bar = *eax & mask; - bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | - PCIM_BAR_MEM_PREFETCH; + bar |= pi->pi_bar[idx].lobits; if (addr != (uint32_t)pi->pi_bar[idx].addr) { update_bar_address(pi, addr, idx, PCIBAR_MEM64); diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 5b6a17119960..6eac0720f09f 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -99,6 +99,7 @@ struct pcibar { enum pcibar_type type; /* io or memory */ uint64_t size; uint64_t addr; + uint8_t lobits; }; #define PI_NAMESZ 40 diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c index bf99c646c480..29142749abb4 100644 --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -531,12 +531,23 @@ cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) sc->psc_bar[i].type = bartype; sc->psc_bar[i].size = size; sc->psc_bar[i].addr = base; + sc->psc_bar[i].lobits = 0; /* Allocate the BAR in the guest I/O or MMIO space */ error = pci_emul_alloc_bar(pi, i, bartype, size); if (error) return (-1); + /* Use same lobits as physical bar */ + uint8_t lobits = read_config(&sc->psc_sel, PCIR_BAR(i), 0x01); + if (bartype == PCIBAR_MEM32 || bartype == PCIBAR_MEM64) { + lobits &= ~PCIM_BAR_MEM_BASE; + } else { + lobits &= ~PCIM_BAR_IO_BASE; + } + sc->psc_bar[i].lobits = lobits; + pi->pi_bar[i].lobits = lobits; + /* The MSI-X table needs special handling */ if (i == pci_msix_table_bar(pi)) { error = init_msix_table(ctx, sc, base); |