Faire du Pci Passtrough sous Proxmox

Logo-ProxmoxVE

 

Encore un article sur Proxmox ??
Ben oui, y a matière à faire dessus !

Cette fois je vais parler du Pci Passtrough, "kécécé" ??

Il s'agit de pouvoir utiliser des périphériques physiques (comme des cartes réseaux, graphiques …) dans une machine virtuelle, afin qu'elle bénéficie d'un usage unique aux ressources matériels du composant.
Vous allez avec ça pouvoir créer un routeur/firewall virtuel avec Pfsense ou IpCop, faire une vm dédiée aux calcul GPGPU, faire un NAS avec une carte raid …

Sur le papier ça semble simple, beau, pratique… bref tout ce qu'il faut pour plaire !

Et ben nan, pas chez Proxmox !

Dans la pratique, les options n'existent même pas dans l'interface, vous aurez beau chercher, y a rien… donc perdez pas de temps, et mettons les mains dans le cambouis.

Dans un premier temps il est important de vérifier que votre hardware soit compatible (c'est souvent là que ça bloque !).
(mon serveur hôte étant sous Intel, je vais garder ce constructeur dans mes exemples, mais AMD propose également du matériel compatible ;) )

  • Le CPU: il doit supporter les instructions VT-X, c'est souvent le cas pour les familles de Core2Duo, Core2Quad, Core i5 / i7, les Xeon (à partir des série Exxxx
    attention aux CPU "grand publique" (sauf exceptions) comme les Pentium, Atom, Core i3…  ils ne supportent pas toujours pas ces instructions.
    Pour savoir si votre CPU est compatible, faites une recherche sur le site Intel Ark (http://ark.intel.com/fr).
    Voici la liste des CPU Intel ayant le VT-X : http://ark.intel.com/fr/search/advanced/?s=t&VTX=true

     

     

     

  • La carte mère: oui car pour faire fonctionner notre super carte TV, dans notre super VM, il faut que le chipset de la CM soit compatible lui aussi avec des instructions de virtualisations, chez Intel c'est le VT-d (chez AMD on parlera de gestion d'IOMMU).
    C'est malheureusement beaucoup plus rare que sur les processeurs, il va falloir chercher du coté des cartes mère pour serveurs ou workstations.
    Généralement chez Intel les chipsets compatibles sont de la gamme Q ou X (mais là encore avec des exceptions).

    Voici une liste non exaustive : Q45 / Q65 / Q57 / Q67 / Z77 / X79 / X58 / 5520 / 5500 …
    Pensez à bien vérifier si vous achetez du nouveau matériel !

     

Maintenant que vous être sûr d'avoir le bon matériel (et de l'avoir bien activé dans le bios ;) ), il faut modifier notre Proxmox 2.3 :
(comme je l'avais dit sur HFR, j'ai fais pas mal de modifs avant d'arriver à tout faire fonctionner, j'ai fais une synthèse, de ce qui est nécessaire).

 

On commence par modifier le fichier "default" de Grub :

# nano /etc/default/grub

Puis on modifie la ligne :

 GRUB_CMDLINE_LINUX_DEFAULT="quiet"

en

GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"

 

Il faut créer un fichier à l'endroit suivant : 

# nano /etc/modprobe.d/kvm_iommu_map_guest.conf

pour y ajouter :

options kvm allow_unsafe_assigned_interrupts=1

 

# update-grub

REBOOT !!  turbocat 

On vérifie que l'IOMMU est bien géré :

dmesg | grep -e DMAR -e IOMMU

Chez moi ça donne :

root@Willbure:~# dmesg | grep -e DMAR -e IOMMU
ACPI: DMAR 00000000bdaa00f0 00178 (v01    AMI  OEMDMAR 00000001 MSFT 00000097)
Intel-IOMMU: enabled
DMAR: Host address width 36
DMAR: DRHD base: 0x000000fed90000 flags: 0x0
IOMMU fed90000: ver 1:0 cap c9008020e30272 ecap 1000
DMAR: DRHD base: 0x000000fed91000 flags: 0x0
IOMMU fed91000: ver 1:0 cap c0000020630272 ecap 1000
DMAR: DRHD base: 0x000000fed92000 flags: 0x0
IOMMU fed92000: ver 1:0 cap c0000020630272 ecap 1000
DMAR: DRHD base: 0x000000fed93000 flags: 0x1
IOMMU fed93000: ver 1:0 cap c9008020630272 ecap 1000
DMAR: RMRR base: 0x000000000ed000 end: 0x000000000effff
DMAR: RMRR base: 0x000000bdc00000 end: 0x000000bfffffff
DMAR: RMRR base: 0x000000bdaf0000 end: 0x000000bdafffff
DMAR: No ATSR found
IOMMU 0xfed92000: using Register based invalidation
IOMMU 0xfed91000: using Register based invalidation
IOMMU 0xfed90000: using Register based invalidation
IOMMU 0xfed93000: using Register based invalidation
IOMMU: Setting RMRR:
IOMMU: Setting identity map for device 0000:00:1d.0 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1d.1 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1d.2 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1d.7 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1a.0 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1a.1 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1a.2 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:1a.7 [0xbdaf0000 - 0xbdb00000]
IOMMU: Setting identity map for device 0000:00:02.0 [0xbdc00000 - 0xc0000000]
IOMMU: Setting identity map for device 0000:00:02.1 [0xbdc00000 - 0xc0000000]
IOMMU: Setting identity map for device 0000:00:1d.0 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1d.1 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1d.2 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1d.7 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1a.0 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1a.1 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1a.2 [0xed000 - 0xf0000]
IOMMU: Setting identity map for device 0000:00:1a.7 [0xed000 - 0xf0000]
IOMMU: Prepare 0-16MiB unity mapping for LPC
IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0x1000000]
DMAR:[DMA Write] Request device [00:02.0] fault addr fffff000 
DMAR:[fault reason 05] PTE Write access is not set

 

Puis pour être sur un petit : cat /proc/cpuinfo

root@Willbure:~# cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 23
model name	: Intel(R) Core(TM)2 Quad CPU    Q9400  @ 2.66GHz
stepping	: 10
cpu MHz		: 2003.000
cache size	: 3072 KB
physical id	: 0
siblings	: 4
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dts tpr_shadow vnmi flexpriority
bogomips	: 5332.92
clflush size	: 64
cache_alignment	: 64
address sizes	: 36 bits physical, 48 bits virtual
power management:

 

On retrouve bien dans les flags les instructions : vmx et smx
Mon cpu est donc bien compatible VT-x, et il est bien pris en charge par la distribution. (cool !)

Pour attribuer des ressources physiques à une VM, il faut connaitre son adressage, chose facile à faire grâce à la commande lspci :

root@Willbure:~# lspci
00:00.0 Host bridge: Intel Corporation 4 Series Chipset DRAM Controller (rev 03)
00:02.0 VGA compatible controller: Intel Corporation 4 Series Chipset Integrated Graphics Controller (rev 03)
00:02.1 Display controller: Intel Corporation 4 Series Chipset Integrated Graphics Controller (rev 03)
00:03.0 Communication controller: Intel Corporation 4 Series Chipset HECI Controller (rev 03)
00:03.2 IDE interface: Intel Corporation 4 Series Chipset PT IDER Controller (rev 03)
00:03.3 Serial controller: Intel Corporation 4 Series Chipset Serial KT Controller (rev 03)
00:19.0 Ethernet controller: Intel Corporation 82567LM-3 Gigabit Network Connection (rev 02)
00:1a.0 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #4 (rev 02)
00:1a.1 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #5 (rev 02)
00:1a.2 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #6 (rev 02)
00:1a.7 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB2 EHCI Controller #2 (rev 02)
00:1b.0 Audio device: Intel Corporation 82801JD/DO (ICH10 Family) HD Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation 82801JD/DO (ICH10 Family) PCI Express Port 1 (rev 02)
00:1d.0 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #1 (rev 02)
00:1d.1 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #2 (rev 02)
00:1d.2 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB UHCI Controller #3 (rev 02)
00:1d.7 USB Controller: Intel Corporation 82801JD/DO (ICH10 Family) USB2 EHCI Controller #1 (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a2)
00:1f.0 ISA bridge: Intel Corporation 82801JDO (ICH10DO) LPC Interface Controller (rev 02)
00:1f.2 SATA controller: Intel Corporation 82801JD/DO (ICH10 Family) SATA AHCI Controller (rev 02)
00:1f.3 SMBus: Intel Corporation 82801JD/DO (ICH10 Family) SMBus Controller (rev 02)
01:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
02:02.0 Ethernet controller: Intel Corporation 82546EB Gigabit Ethernet Controller (Copper) (rev 01)
02:02.1 Ethernet controller: Intel Corporation 82546EB Gigabit Ethernet Controller (Copper) (rev 01)

Moi je voulais rajouter les cartes Intel 82546EB, les IDs sont donc 02:02.0 et 02:02.1

Je modifie le fichier de conf de ma VM (qui est éteinte pour l'occasion !!) :

# nano /etc/pve/qemu-server/111.conf

ce qui donne chez moi :

boot: c
bootdisk: scsi0
cores: 1
keyboard: fr
memory: 512
name: Pfsense
net0: e1000=A2:93:78:F6:32:BC,bridge=vmbr1
ostype: l26
scsi0: local:111/vm-111-disk-1.qcow2,size=2G
sockets: 1
tablet: 0

Et sous la ligne "cores: 1", je rajoute les commandes "hostpci".

boot: c
bootdisk: scsi0
cores: 1
hostpci0: 02:02.0
hostpci1: 02:02.1
keyboard: fr
memory: 512
name: Pfsense
net0: e1000=A2:93:78:F6:32:BC,bridge=vmbr1
ostype: l26
scsi0: local:111/vm-111-disk-1.qcow2,size=2G
sockets: 1
tablet: 0

y a plus qu'à !

 

pour faire booter ma VM (ou depuis l'interface graphique, c'est au choix !) :

# qm start 111

Et voici un petit screenshot de ma VM, où on voit apparaitre mes deux cartes physiques (les Copper):

 

pci passtrough proxmox

Vus : 749
Publié par Sheldon.fr : 17