Getz Mikalsen
Table of Contents
_________________
1. GPU passthrough for bhyve on FreeBSD 14
.. 1. Why even bother
.. 2. Lets get started!
..... 1. buildkernel
..... 2. make bhyve
..... 3. Bhyve passthrough
2. Update for newer releases
3. References
1 GPU passthrough for bhyve on FreeBSD 14
=========================================
21-05-2024
*Table of Contents*
- [GPU passthrough for bhyve on FreeBSD 14]
- [Why even bother]
- [Lets get started!]
- [buildkernel]
- [make bhyve]
- [Bhyve passthrough]
- [Update for newer releases]
- [References]
We recently purchased a GPU for our University computer club [[1]] for
Machine Learning tasks. Being most comfortable on a FreeBSD system I
decided that running a VM through bhyve would be most
suitable. Especially as I expect that several students will connect to
this machine concurrently using harmful software such as Visual Studio
Codes remote development over SSH extension.
[GPU passthrough for bhyve on FreeBSD 14] See section 1
[Why even bother] See section 1.1
[Lets get started!] See section 1.2
[buildkernel] See section 1.2.1
[make bhyve] See section 1.2.2
[Bhyve passthrough] See section 1.2.3
[Update for newer releases] See section 2
[References] See section 3
[1]
1.1 Why even bother
~~~~~~~~~~~~~~~~~~~
From experience I know that VSCode launches a gazillion processes and
wont kindly terminate them. It also downloads binaries from microsoft
servers and runs a little node session remote on the server for each
user and doesnt reuse old ones. A bonus is that it doesnt run naively
on FreeBSD (You can get this working using linuxulator [[2]] but dont
bother).
But the problem is that meanwhile Bhyve does support PCI-e passthrough
its GPU support is lacking according to people online. [[3]] > bhyve
supports passing of host PCI devices to a virtual machine for its
exclusive use of them.
> Note: VGA / GPU pass-through devices are not currently supported.
That last part is not really true, the problem lies within some
drivers (NVIDIA) only supporting hypervisors with the KVM signature,
so we need to patch Bhyve.
Luckily patches are already available [[4]], and the instructions are
as simple as following the FreeBSD developers handbook [[5]].
[2]
[3]
[4]
[5]
1.2 Lets get started!
~~~~~~~~~~~~~~~~~~~~~
First get the sources for FreeBSD, you probably only care about the
branch with the patches applied. They reside on github from the
Beckhoff github account under the tag phab/corvink/14.0/nvidia-wip.
,----
| cd /where/you/want/to/build
| git clone --depth 1 --branch phab/corvink/14.0/nvidia-wip https://github.com/Beckhoff/freebsd-src
`----
1.2.1 buildkernel
-----------------
Now we can either use the script provided by corvink@ [[6]] or just
follow the handbook.
,----
| cd freebsd-src
| make -j64 buildkernel
| make installkernel
`----
Now the new kernel is installed, the previous kernel is located at
`/boot/kernel.old/kernel'
[6]
1.2.2 make bhyve
----------------
Now its time to build bhyve with our patches, this will go quick. The
provided script automates this for you. (really, use the script [[6]])
,----
| cd include
| make -j64
| make install
| cd lib/libvmmapi
| make -j64
| make install
| cd sys/modules/vmm
| make -j64
| make install
| cd usr.sbin/bhyve
| make -j64
| make install
| cd usr.sbin/bhyvectl
| make -j64
| make install
| cd usr.sbin/bhyveload
| make -j64
| make install
`----
Really, just use the script. But now you should be ready to reboot
into your freshly patches system!
For future FreeBSD releases you can simply go in and apply the patch
manually if necessary.
[6]
1.2.3 Bhyve passthrough
-----------------------
Now to have our pci device to passthrough to bhyve we first figure out
what id its assigned. This is basically following the wiki page at
[[3]].
,----
| $ pciconf -v -l | grep -B 1 -A 3 NVIDIA
| ppt0@pci0:193:0:0: class=0x030000 rev=0xa1 hdr=0x00 vendor=0x10de device=0x2204 subvendor=0x1028 subdevice=0x3880
| vendor = 'NVIDIA Corporation'
| device = 'GA102 [GeForce RTX 3090]'
| class = display
| subclass = VGA
| ppt1@pci0:193:0:1: class=0x040300 rev=0xa1 hdr=0x00 vendor=0x10de device=0x1aef subvendor=0x1028 subdevice=0x3880
| vendor = 'NVIDIA Corporation'
| device = 'GA102 High Definition Audio Controller'
| class = multimedia
| subclass = HDA
`----
Now note down those numbers and insert them into /boot/loader.conf as
following
,----
| # echo pptdevs="193/0/0 193/0/1" >> /boot/loader.conf
`----
Now the host wont steal them when the system is started, now to map
them into Bhyve. If you want to passthrough another device, such as an
USB hub to the VM you can specify more devices by appending `N' to
pptdevs such as `pptdevs2'"194/0/0"=.
We use the excellent bhyve-vm [[7]] utility to simplify vm management.
Simply add the following to the end of your $VM.conf file, they will
now show up in pci slots 9:0 and 9:1 on the VM. You might want to make
sure that you dont make them to a spot thats already occupied, if so
just go higher.
,----
| passthru0="193/0/0=9:0"
| passthru1="193/0/1=9:1"
`----
And presto!
Now you can reboot your FreeBSD host and your VM will have access to
the GPU.
On a linux VM you can verify that the patches were applied correctly
by checking your hypervisor signator by running `dmesg'
,----
| # dmesg | grep KVM
`----
[3]
[7]
2 Update for newer releases
===========================
The patch still works on 14.1 it just needed some tiny refactoring as
`read_config' was renamed to `pci_host_read_config'. A patch file is
provided [nvidia.patch]. Apply it by running `git apply -v
nvidia.patch' after cloning 14.1 by running `git clone --depth 1
--branch releng/14.1 https://github.com/freebsd/freebsd-src'
[nvidia.patch] <./nvidia.patch>
3 References
============
[[1]]
[[2]]
[[3]]
[[4]]
[[5]]
[[6]]
[[7]]
[1]
[2]
[3]
[4]
[5]
[6]
[7]