The branch main has been updated by corvink:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f841cb63687ba7d4285bcd35f3bdbb51253c41d8

commit f841cb63687ba7d4285bcd35f3bdbb51253c41d8
Author:     Corvin Köhne <corv...@freebsd.org>
AuthorDate: 2024-01-08 14:01:45 +0000
Commit:     Corvin Köhne <corv...@freebsd.org>
CommitDate: 2025-08-05 14:02:09 +0000

    bhyve: trap protected BAR regions of passthru devices
    
    At the moment, the list of protected BAR regions is unused by the passthru
    emulation. Make use of it when mapping the BAR regions. This causes bhyve to
    trap those regions.
    
    Reviewed by:            jhb
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D45340
---
 usr.sbin/bhyve/pci_passthru.c | 57 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 47 insertions(+), 10 deletions(-)

diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c
index 0cc5b777b842..2b84c561927a 100644
--- a/usr.sbin/bhyve/pci_passthru.c
+++ b/usr.sbin/bhyve/pci_passthru.c
@@ -1323,27 +1323,64 @@ passthru_msix_addr(struct pci_devinst *pi, int baridx, 
int enabled,
        }
 }
 
-static void
-passthru_mmio_addr(struct pci_devinst *pi, int baridx, int enabled,
-    uint64_t address)
+static int
+passthru_mmio_map(struct pci_devinst *pi, int baridx, int enabled,
+    uint64_t address, uint64_t off, uint64_t size)
 {
        struct passthru_softc *sc;
 
        sc = pi->pi_arg;
        if (!enabled) {
                if (vm_unmap_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus,
-                                        sc->psc_sel.pc_dev,
-                                        sc->psc_sel.pc_func, address,
-                                        sc->psc_bar[baridx].size) != 0)
+                   sc->psc_sel.pc_dev, sc->psc_sel.pc_func, address + off,
+                   size) != 0) {
                        warnx("pci_passthru: unmap_pptdev_mmio failed");
+                       return (-1);
+               }
        } else {
                if (vm_map_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus,
-                                      sc->psc_sel.pc_dev,
-                                      sc->psc_sel.pc_func, address,
-                                      sc->psc_bar[baridx].size,
-                                      sc->psc_bar[baridx].addr) != 0)
+                   sc->psc_sel.pc_dev, sc->psc_sel.pc_func, address + off,
+                   size, sc->psc_bar[baridx].addr + off) != 0) {
                        warnx("pci_passthru: map_pptdev_mmio failed");
+                       return (-1);
+               }
+       }
+
+       return (0);
+}
+
+static void
+passthru_mmio_addr(struct pci_devinst *pi, int baridx, int enabled,
+    uint64_t address)
+{
+       struct passthru_softc *sc;
+       struct passthru_bar_handler *handler;
+       uint64_t off;
+
+       sc = pi->pi_arg;
+
+       off = 0;
+
+       /* The queue is sorted by offset in ascending order. */
+       TAILQ_FOREACH(handler, &sc->psc_bar_handler[baridx], chain) {
+               uint64_t handler_off = trunc_page(handler->off);
+               uint64_t handler_end = round_page(handler->off + handler->size);
+
+               /*
+                * When two handlers point to the same page, handler_off can be
+                * lower than off. That's fine because we have nothing to do in
+                * that case.
+                */
+               if (handler_off > off) {
+                       passthru_mmio_map(pi, baridx, enabled, address, off,
+                           handler_off - off);
+               }
+
+               off = handler_end;
        }
+
+       passthru_mmio_map(pi, baridx, enabled, address, off,
+           sc->psc_bar[baridx].size - off);
 }
 
 static void

Reply via email to