Page MenuHomeFreeBSD

D45339.id159776.diff
No OneTemporary

D45339.id159776.diff

diff --git a/usr.sbin/bhyve/pci_passthru.h b/usr.sbin/bhyve/pci_passthru.h
--- a/usr.sbin/bhyve/pci_passthru.h
+++ b/usr.sbin/bhyve/pci_passthru.h
@@ -35,6 +35,10 @@
struct pci_devinst *pi, int coff, int bytes, uint32_t *rv);
typedef int (*cfgwrite_handler)(struct passthru_softc *sc,
struct pci_devinst *pi, int coff, int bytes, uint32_t val);
+typedef uint64_t (*passthru_read_handler)(struct pci_devinst *pi, int baridx,
+ uint64_t offset, int size);
+typedef void (*passthru_write_handler)(struct pci_devinst *pi, int baridx, uint64_t offset,
+ int size, uint64_t val);
uint32_t pci_host_read_config(const struct pcisel *sel, long reg, int width);
void pci_host_write_config(const struct pcisel *sel, long reg, int width,
diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c
--- a/usr.sbin/bhyve/pci_passthru.c
+++ b/usr.sbin/bhyve/pci_passthru.c
@@ -79,6 +79,14 @@
SET_DECLARE(passthru_dev_set, struct passthru_dev);
+struct passthru_bar_handler {
+ TAILQ_ENTRY(passthru_bar_handler) chain;
+ uint64_t off;
+ uint64_t size;
+ passthru_read_handler read;
+ passthru_write_handler write;
+};
+
struct passthru_softc {
struct pci_devinst *psc_pi;
/* ROM is handled like a BAR */
@@ -96,6 +104,9 @@
struct passthru_mmio_mapping psc_mmio_map[PASSTHRU_MMIO_MAX];
cfgread_handler psc_pcir_rhandler[PCI_REGMAX + 1];
cfgwrite_handler psc_pcir_whandler[PCI_REGMAX + 1];
+
+ TAILQ_HEAD(,
+ passthru_bar_handler) psc_bar_handler[PCI_BARMAX_WITH_ROM + 1];
};
static int
@@ -947,6 +958,9 @@
pi->pi_arg = sc;
sc->psc_pi = pi;
+ for (uint8_t i = 0; i < PCI_BARMAX_WITH_ROM + 1; ++i)
+ TAILQ_INIT(&sc->psc_bar_handler[i]);
+
/* initialize config space */
if ((error = cfginit(pi, bus, slot, func)) != 0)
goto done;
@@ -1166,6 +1180,7 @@
uint64_t value)
{
struct passthru_softc *sc;
+ struct passthru_bar_handler *handler;
struct pci_bar_ioreq pio;
sc = pi->pi_arg;
@@ -1173,9 +1188,27 @@
if (baridx == pci_msix_table_bar(pi)) {
msix_table_write(sc, offset, size, value);
} else {
- assert(pi->pi_bar[baridx].type == PCIBAR_IO);
assert(size == 1 || size == 2 || size == 4);
- assert(offset <= UINT32_MAX && offset + size <= UINT32_MAX);
+
+ TAILQ_FOREACH(handler, &sc->psc_bar_handler[baridx], chain) {
+ if (offset >= handler->off + handler->size) {
+ continue;
+ } else if (offset < handler->off) {
+ assert(offset + size < handler->off);
+ /*
+ * The list is sorted in ascending order, so all
+ * remaining handlers will have an even larger
+ * offset.
+ */
+ break;
+ }
+
+ assert(offset + size <= handler->off + handler->size);
+
+ handler->write(pi, baridx,
+ offset - handler->off, size, value);
+ return;
+ }
bzero(&pio, sizeof(pio));
pio.pbi_sel = sc->psc_sel;
@@ -1193,6 +1226,7 @@
passthru_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size)
{
struct passthru_softc *sc;
+ struct passthru_bar_handler *handler;
struct pci_bar_ioreq pio;
uint64_t val;
@@ -1201,9 +1235,26 @@
if (baridx == pci_msix_table_bar(pi)) {
val = msix_table_read(sc, offset, size);
} else {
- assert(pi->pi_bar[baridx].type == PCIBAR_IO);
assert(size == 1 || size == 2 || size == 4);
- assert(offset <= UINT32_MAX && offset + size <= UINT32_MAX);
+
+ TAILQ_FOREACH(handler, &sc->psc_bar_handler[baridx], chain) {
+ if (offset >= handler->off + handler->size) {
+ continue;
+ } else if (offset < handler->off) {
+ assert(offset + size < handler->off);
+ /*
+ * The list is sorted in ascending order, so all
+ * remaining handlers will have an even larger
+ * offset.
+ */
+ break;
+ }
+
+ assert(offset + size <= handler->off + handler->size);
+
+ return (handler->read(pi, baridx,
+ offset - handler->off, size));
+ }
bzero(&pio, sizeof(pio));
pio.pbi_sel = sc->psc_sel;

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 26, 6:14 PM (34 m, 34 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26221825
Default Alt Text
D45339.id159776.diff (3 KB)

Event Timeline