aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorvin Köhne <CorvinK@beckhoff.com>2021-11-18 15:25:09 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2021-11-18 15:25:09 +0000
commite87a6f3ef284593c01e0fd3f8b5bfc1f645e5b18 (patch)
tree6be8182881a7718f0a9cb05f30a20d424a81e7b0
parentf7c526ab3f23e5663cb8477c3dfb41a89de2d4cd (diff)
downloadsrc-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
-rw-r--r--usr.sbin/bhyve/pci_emul.c16
-rw-r--r--usr.sbin/bhyve/pci_emul.h1
-rw-r--r--usr.sbin/bhyve/pci_passthru.c11
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);