Esta pagina se ve mejor con JavaScript habilitado

PCIe passthru Bhyve

 ·  🎃 kr0m

Como ya vimos en un artículo anterior Bhyve es un sistema de virtualización ligero con multitud de funcionalidades, entre ellas el passthru de dispositivos PCIe, los requisitos para disponer de dicha funcionalidad son:

  • CPU supports Intel IOMMU (a.k.a. VT-d) feature:
    Mi microprocesador es un Intel Core i7-6700K que soporta tanto VT-x como VT-d:

    dmesg

    CPU: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (4007.99-MHz K8-class CPU)
      Origin="GenuineIntel"  Id=0x506e3  Family=0x6  Model=0x5e  Stepping=3
      Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
      Features2=0x7ffafbbf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,SDBG,FMA,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND>
      AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM>
      AMD Features2=0x121<LAHF,ABM,Prefetch>
      Structured Extended Features=0x29c6fbf<FSGSBASE,TSCADJ,SGX,BMI1,HLE,AVX2,SMEP,BMI2,ERMS,INVPCID,RTM,NFPUSG,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PROCTRACE>
      Structured Extended Features3=0xbc002e00<MCUOPT,MD_CLEAR,TSXFA,IBPB,STIBP,L1DFL,ARCH_CAP,SSBD>
      XSAVE Features=0xf<XSAVEOPT,XSAVEC,XINUSE,XSAVES>
      IA32_ARCH_CAPS=0xc04<RSBA>
      VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
      TSC: P-state invariant, performance statistics
    

    En mi caso no fué suficiente habilitando el VT-x en la BIOS, además tuve que ir a Advanced -> System Agent Configuration -> VT-d: Enabled

    Comprobamos que ACPI tenga la información de mapeo de dispositivos necesaria:

    acpidump -t | grep DMAR

      DMAR: Length=176, Revision=1, Checksum=45,
    
  • PCI device (and driver) supports MSI/MSI-x interrupts:

    pciconf -lc | grep MSI

        cap 05[90] = MSI supports 1 message
        cap 05[ac] = MSI supports 1 message
        cap 05[80] = MSI supports 8 messages, 64 bit enabled with 1 message
        cap 05[8c] = MSI supports 1 message, 64 bit
        cap 05[80] = MSI supports 1 message enabled with 1 message
        cap 05[80] = MSI supports 1 message
        cap 05[80] = MSI supports 1 message
        cap 05[80] = MSI supports 1 message
        cap 05[80] = MSI supports 1 message
        cap 05[80] = MSI supports 1 message
        cap 05[60] = MSI supports 1 message, 64 bit enabled with 1 message
        cap 05[d0] = MSI supports 1 message, 64 bit enabled with 1 message
        cap 05[68] = MSI supports 1 message, 64 bit enabled with 1 message
        cap 05[68] = MSI supports 1 message, 64 bit enabled with 1 message
        cap 05[50] = MSI supports 8 messages, 64 bit
        cap 11[68] = MSI-X supports 8 messages, enabled
        cap 05[50] = MSI supports 8 messages, 64 bit
        cap 11[68] = MSI-X supports 8 messages
        cap 05[50] = MSI supports 1 message, 64 bit
        cap 11[b0] = MSI-X supports 33 messages, enabled
    

Debemos tener en cuenta que el passthru tiene algunas limitaciones importantes como son:

  • El dispositivo debe ser deshabilitado del host padre para poder ser utilizado en las máquinas virtuales.
  • Si se trata de una controladora USB, no se pueden asignar puertos aislados, se asigna la controladora entera.

Para evitar estas limitaciones he optado por comprar una controladora PCIe que utilizaré exclusivamente en las máquinas virtuales, de este modo mi equipo queda intacto sin perder ningún puerto USB, se trata de una tarjeta YEELIYA :


Parent host:

La mejor manera de identificar la tarjeta es empleando los comandos instalados por vm-bhyve:

vm passthru

DEVICE     BHYVE ID     READY        DESCRIPTION
hostb0     0/0/0        No           Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers
pcib1      0/1/0        No           6th-10th Gen Core Processor PCIe Controller (x16)
vgapci1    0/2/0        No           HD Graphics 530
xhci0      0/20/0       No           100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller
none0      0/22/0       No           100 Series/C230 Series Chipset Family MEI Controller
ahci0      0/23/0       No           Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode]
pcib2      0/27/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib3      0/27/3       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib4      0/28/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib5      0/28/7       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib6      0/29/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
isab0      0/31/0       No           Z170 Chipset LPC/eSPI Controller
none1      0/31/2       No           100 Series/C230 Series Chipset Family Power Management Controller
hdac1      0/31/3       No           100 Series/C230 Series Chipset Family HD Audio Controller
ichsmb0    0/31/4       No           100 Series/C230 Series Chipset Family SMBus
em0        0/31/6       No           Ethernet Connection (2) I219-V
vgapci0    1/0/0        No           GP106 [GeForce GTX 1060 6GB]
hdac0      1/0/1        No           GP106 High Definition Audio Controller
ahci1      3/0/0        No           ASM1062 Serial ATA Controller
xhci1      4/0/0        No           ASM1142 USB 3.1 Host Controller
xhci2      5/0/0        No           ASM2142/ASM3142 USB 3.1 Host Controller
nvme0      6/0/0        No           NVMe SSD Controller SM981/PM981/PM983

El identificativo de bus/slot/function que nos interesa es:

xhci2      5/0/0        No           ASM2142/ASM3142 USB 3.1 Host Controller

Deshabilitamos la tarjeta en el sistema padre, es importante cargar vmm desde el loader en el arranque del SO y no a posteriori para poder reservar los dispositivos antes de que el propio sistema operativo empiece a utilizarlos, si dejamos que se cargue desde RC como dependencia de vm-bhyve(o cualquier otro software de virtualización) o mediante kld_list, los dispositivos no estarán disponibles para el passthru:

vi /boot/loader.conf

# PCIe passthru, USB-Card: 5/0/0
vmm_load="YES"
pptdevs="5/0/0"

Reiniciamos para que cargue la configuración:

shutdown -r now

Consultamos de nuevo la lista de dispositivos y veremos que ahora el que nos interesa está READY:

vm passthru

DEVICE     BHYVE ID     READY        DESCRIPTION
hostb0     0/0/0        No           Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers
pcib1      0/1/0        No           6th-10th Gen Core Processor PCIe Controller (x16)
vgapci1    0/2/0        No           HD Graphics 530
xhci0      0/20/0       No           100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller
none0      0/22/0       No           100 Series/C230 Series Chipset Family MEI Controller
ahci0      0/23/0       No           Q170/Q150/B150/H170/H110/Z170/CM236 Chipset SATA Controller [AHCI Mode]
pcib2      0/27/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib3      0/27/3       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib4      0/28/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib5      0/28/7       No           100 Series/C230 Series Chipset Family PCI Express Root Port
pcib6      0/29/0       No           100 Series/C230 Series Chipset Family PCI Express Root Port
isab0      0/31/0       No           Z170 Chipset LPC/eSPI Controller
none1      0/31/2       No           100 Series/C230 Series Chipset Family Power Management Controller
hdac1      0/31/3       No           100 Series/C230 Series Chipset Family HD Audio Controller
ichsmb0    0/31/4       No           100 Series/C230 Series Chipset Family SMBus
em0        0/31/6       No           Ethernet Connection (2) I219-V
vgapci0    1/0/0        No           GP106 [GeForce GTX 1060 6GB]
hdac0      1/0/1        No           GP106 High Definition Audio Controller
ahci1      3/0/0        No           ASM1062 Serial ATA Controller
xhci1      4/0/0        No           ASM1142 USB 3.1 Host Controller
ppt0       5/0/0        Yes          ASM2142/ASM3142 USB 3.1 Host Controller
nvme0      6/0/0        No           NVMe SSD Controller SM981/PM981/PM983

Virtual machine:

Indicamos los dispositivos a pasar :

cat << EOF >> /zroot/vm/ubuntu-cloud/ubuntu-cloud.conf
passthru0="5/0/0"
EOF

Podemos ver en la máquina virtual con un lspci los dispositivos disponibles.
Antes passthru:

00:00.0 Host bridge: Network Appliance Corporation Device 1275
00:04.0 SCSI storage controller: Red Hat, Inc. Virtio block device
00:04.1 SATA controller: Intel Corporation 82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]
00:05.0 Ethernet controller: Red Hat, Inc. Virtio network device
00:1f.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]

Después passthru:

00:00.0 Host bridge: Network Appliance Corporation Device 1275
00:04.0 SCSI storage controller: Red Hat, Inc. Virtio block device
00:04.1 SATA controller: Intel Corporation 82801HR/HO/HH (ICH8R/DO/DH) 6 port SATA Controller [AHCI mode]
00:05.0 Ethernet controller: Red Hat, Inc. Virtio network device
00:06.0 USB controller: ASMedia Technology Inc. ASM2142 USB 3.1 Host Controller
00:1f.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]

Troubleshooting:

Si algo saliese mal, siempre podemos consultar los logs de Bhyve:

tail -f /zroot/vm/ubuntu-cloud/vm-bhyve.log

Si vemos el siguiente error, es que no tenemos habilitado el VT-d en la BIOS o que nuestra CPU no lo soporta:

Oct 25 21:58:36: fatal; pci passthrough not supported on this system (no VT-d or amdvi)

En mi caso no fué suficiente habilitando el VT-x en la BIOS, además tuve que ir a Advanced -> System Agent Configuration -> VT-d: Enabled

Si te ha gustado el artículo puedes invitarme a un RedBull aquí