---> NVIDIA GPU passthrough should work with stock 15.0, no patches
required.

Hello my friend. Unfortunately it does not. Not even with 15.0-p9. With my
system it didn't work. If you go on the FreeBSD forums you see people
saying that they are still using the passthru on FreeBSD 14. One user
offered a patch that I have applied,but it didn't work. So I worked with
Claude to fix the bug and after some days of work,we developed the correct
patches. Now it is working fine. I attach them here,if you want to give a
look.

On Fri, Jun 5, 2026 at 8:34 AM Corvin Köhne <[email protected]> wrote:

> On Thu, 2026-06-04 at 13:23 +0200, Mario Marietto wrote:
> >         Hi everyone,
> >  I'm trying to get NVIDIA GPU passthrough working with bhyve on FreeBSD
> 15.0-
> > RELEASE-p5, using Corvin Köhne's nvidia-wip branch:
> >
> https://github.com/Beckhoff/freebsd-src/tree/phab/corvink/15.0/nvidia-wip
> >  The VM fails to start with the following error before the guest even
> boots:
> >  bhyve: bootrom_alloc: vm_mmap_mapseg: Invalid argument
>
> NVIDIA GPU passthrough should work with stock 15.0, no patches required.
>
>
> --
> Best regards,
> Corvin
>


-- 
Mario.
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -755,10 +755,10 @@
 	sx_assert(&vm->mem.mem_segs_lock, SX_LOCKED);

 	for (i = 0; i < VM_MAX_MEMMAPS; i++) {
-		if (!vm_memseg_sysmem(vm, i))
+		mm = &vm->mem.mem_maps[i];
+		if (!vm_memseg_sysmem(vm, mm->segid))
 			continue;

-		mm = &vm->mem.mem_maps[i];
 		KASSERT((mm->flags & VM_MEMMAP_F_IOMMU) == 0,
 		    ("iommu map found invalid memmap %#lx/%#lx/%#x",
 		    mm->gpa, mm->len, mm->flags));
@@ -803,10 +803,10 @@
 	sx_assert(&vm->mem.mem_segs_lock, SX_LOCKED);

 	for (i = 0; i < VM_MAX_MEMMAPS; i++) {
-		if (!vm_memseg_sysmem(vm, i))
+		mm = &vm->mem.mem_maps[i];
+		if (!vm_memseg_sysmem(vm, mm->segid))
 			continue;

-		mm = &vm->mem.mem_maps[i];
 		if ((mm->flags & VM_MEMMAP_F_IOMMU) == 0)
 			continue;
 		mm->flags &= ~VM_MEMMAP_F_IOMMU;
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -14,6 +14,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/mman.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/queue.h>
 #include <sys/sx.h>
@@ -74,14 +75,11 @@
 static void devmem_destroy(void *arg);
 static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem);

+/* VMM_PRIV_CHECK_FIX_APPLIED */
 static int
-vmm_priv_check(struct ucred *ucred)
+vmm_priv_check(struct thread *td)
 {
-	if (jailed(ucred) &&
-	    !(ucred->cr_prison->pr_allow & pr_allow_flag))
-		return (EPERM);
-
-	return (0);
+	return (priv_check(td, PRIV_DRIVER));
 }

 static int
@@ -334,7 +332,7 @@
 	 * A jail without vmm access shouldn't be able to access vmm device
 	 * files at all, but check here just to be thorough.
 	 */
-	error = vmm_priv_check(td->td_ucred);
+	error = vmm_priv_check(td);
 	if (error != 0)
 		return (error);

@@ -813,7 +811,7 @@
 	char *buf;
 	int error, buflen;

-	error = vmm_priv_check(req->td->td_ucred);
+	error = vmm_priv_check(req->td);
 	if (error)
 		return (error);

@@ -902,7 +900,7 @@
 	char *buf;
 	int error, buflen;

-	error = vmm_priv_check(req->td->td_ucred);
+	error = vmm_priv_check(req->td);
 	if (error != 0)
 		return (error);

@@ -925,7 +923,7 @@
 {
 	int error;

-	error = vmm_priv_check(td->td_ucred);
+	error = vmm_priv_check(td);
 	if (error != 0)
 		return (error);
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -390,6 +390,8 @@
 	 * This is the usual case for the SYSMEM segment created by userspace
 	 * loaders like bhyveload(8).
 	 */
+	if (segid != VM_SYSMEM) /* VM_ALLOC_MEMSEG_FIX_APPLIED */
+		goto alloc_devmem;
 	error = vm_get_memseg(ctx, segid, &memseg.len, memseg.name,
 	    sizeof(memseg.name));
 	if (error)
@@ -404,6 +406,7 @@
 		}
 	}

+alloc_devmem:
 	bzero(&memseg, sizeof(struct vm_memseg));
 	memseg.segid = segid;
 	memseg.len = len;

Reply via email to