Sanallaştırmanın büyük vaadi donanımı soyutlamaktır: sanal makine gerçek diski değil sanal diski, gerçek ağ kartını değil sanal ağ kartını görür. Ama bazı iş yüklerinde tam tersi gerekir — kartın kendisi, taklit edilmiş hâli değil. İşte PCI passthrough tam olarak bunu yapar: anakarttaki fiziksel bir PCI/PCIe cihazını hipervizörden koparıp doğrudan bir sanal makineye bağlar. Konuk sistem o cihazı kendi donanımıymış gibi görür, kendi sürücüsünü yükler ve taklit katmanının ek yükünü hiç ödemez.
Bu yazıda passthrough'un altında yatan mekanizmayı — IOMMU, VFIO ve IOMMU grupları — anlaşılır biçimde açıklayacağım, sonra bir cihazı adım adım sanal makineye nasıl vereceğinizi göstereceğim. GPU'ya özgü ayrıntılar için Proxmox'ta GPU passthrough yazısı ayrı bir rehber; burada NVMe disk, ağ kartı, RAID denetleyicisi ve USB denetleyicisi gibi tüm cihaz tiplerini kapsayan genel mantığı kuruyoruz.
Passthrough Aslında Ne Yapıyor#
Normal sanallaştırmada bir sanal makine diske yazmak istediğinde şu zincir işler: konuk sürücü → sanal disk denetleyicisi → hipervizör → ana makinenin dosya sistemi → gerçek disk. Her katman biraz gecikme, biraz CPU ve biraz karmaşıklık ekler. Passthrough bu zinciri kısaltır: konuk sürücü doğrudan cihazın kayıtlarına (register) yazar, hipervizör aradan çekilir.
Bunu güvenli hâle getiren şey IOMMU'dur (Input-Output Memory Management Unit). CPU'daki MMU'nun süreçler için yaptığını, IOMMU cihazlar için yapar: bir PCI cihazının DMA (doğrudan bellek erişimi) isteklerini çevirir ve sınırlar. IOMMU olmasaydı, sanal makineye verilen bir kart ana makinenin belleğinin herhangi bir yerine yazabilirdi — yani passthrough tam bir güvenlik felaketi olurdu. IOMMU sayesinde cihaz yalnızca kendisine ayrılan sanal makinenin belleğini görür.
İkinci parça VFIO'dur (Virtual Function I/O). VFIO, Linux çekirdeğinde bir cihazı kullanıcı alanındaki bir sürece (burada QEMU) güvenli biçimde devretmeyi sağlayan çerçevedir. Bir cihazı passthrough'a hazırlamak, pratikte onu normal sürücüsünden koparıp vfio-pci sürücüsüne bağlamak demektir. Zinciri şöyle özetleyebiliriz:
| Katman | Görevi |
|---|---|
| BIOS/UEFI (VT-d, AMD-Vi) | Donanım yalıtımını etkinleştirir |
Çekirdek (intel_iommu=on) | IOMMU'yu kullanmaya başlar, grupları oluşturur |
vfio-pci sürücüsü | Cihazı ana makineden alır, devredilebilir kılar |
| QEMU/KVM | Cihazı konuk sisteme PCI aygıtı olarak sunar |
| Konuk sürücü | Cihazı gerçek donanım gibi kullanır |
Bu zincirin herhangi bir halkası eksikse passthrough çalışmaz — ve hata mesajları çoğu zaman hangi halkanın koptuğunu doğrudan söylemez. Bu yüzden aşağıdaki adımlarda her aşamada bir doğrulama komutu vereceğim.
IOMMU Grupları: En Kritik Kavram#
Passthrough öğrenirken insanların en çok takıldığı yer burasıdır. IOMMU, cihazları tek tek değil gruplar hâlinde yalıtabilir. Bir IOMMU grubu, donanımın birbirinden bağımsız olarak izole edemediği cihazların kümesidir; kural basittir: bir gruptaki cihazların tamamı ya aynı sanal makineye gider ya da hiçbiri gitmez.
Grupların nasıl oluştuğunu anakart tasarımı belirler. PCIe yuvaları CPU'ya doğrudan bağlıysa genellikle temiz ve tekil gruplar oluşur; yonga seti (chipset) üzerinden köprülenmiş yuvalar ise sık sık aynı gruba düşer. Sunucu anakartları bu konuda tüketici anakartlarından belirgin biçimde daha iyidir.
Sisteminizdeki grupları listelemek için şu döngüyü kullanın:
#!/bin/bash
# Tüm IOMMU gruplarını ve içindeki cihazları listeler
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/}; n=${n%%/*}
printf 'Grup %3s: ' "$n"
lspci -nns "${d##*/}"
done | sort -V
Örnek bir çıktı parçası şöyle görünür:
Grup 14: 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation ... [10de:1c03]
Grup 14: 01:00.1 Audio device [0403]: NVIDIA Corporation ... [10de:10f1]
Grup 15: 02:00.0 Non-Volatile memory controller [0108]: Samsung ... [144d:a808]
Grup 16: 03:00.0 Ethernet controller [0200]: Intel Corporation I210 [8086:1533]
Bu çıktı ideal bir tablodur: ekran kartı ve onun ses fonksiyonu 14'te birlikte (zaten aynı fiziksel kart oldukları için sorun değil), NVMe disk 15'te tek başına, ağ kartı 16'da tek başına. Eğer ağ kartınız ana makinenin önyükleme diski denetleyicisiyle aynı grupta çıkarsa o kartı veremezsiniz — verirseniz ana makine kendi diskini kaybeder.
Grup çakışması yaşarsanız üç seçeneğiniz vardır: cihazı başka bir PCIe yuvasına takmak (en temiz çözüm), gruptaki tüm cihazları birlikte vermek (ana makine onlara ihtiyaç duymuyorsa) ya da grupları yazılımla bölen yamalara başvurmak. Üçüncüsü yalıtım garantisini zayıflattığı için üretim ortamında önerilmez.
Adım Adım Yapılandırma#
Genel akış her cihaz tipi için aynıdır; yalnızca kimlikler değişir. Aşağıdaki adımları sırayla uygulayın ve her birinin sonundaki doğrulamayı atlamayın.
- BIOS'ta sanallaştırma ve IOMMU'yu açın. Intel'de VT-d, AMD'de IOMMU/SVM. Büyük bellek pencereli cihazlar için "Above 4G Decoding" da açık olmalıdır.
- Çekirdek parametresini ekleyin. GRUB kullanıyorsanız
/etc/default/grub,systemd-bootkullanıyorsanız/etc/kernel/cmdline. - Cihazın PCI kimliğini bulun.
- Cihazı
vfio-pci'ye bağlayın ve normal sürücüsünü kara listeye alın. - Sanal makineye ekleyin ve konuk içinde doğrulayın.
İlk iki adımın uygulanışı şöyledir:
# Intel için (GRUB)
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="quiet"/GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"/' /etc/default/grub
update-grub && reboot
# Yeniden başladıktan sonra doğrula
dmesg | grep -i -e DMAR -e IOMMU | head -3
# "DMAR: IOMMU enabled" satırını görmelisiniz
Üçüncü ve dördüncü adımda cihaz kimliğini alıp vfio-pci'ye bağlarsınız. Örnek olarak bir NVMe diski verelim:
# NVMe denetleyicisinin adresini ve kimliğini bul
lspci -nn | grep -i "Non-Volatile"
# 02:00.0 Non-Volatile memory controller [0108]: Samsung ... [144d:a808]
# Mevcut sürücüsünü gör
lspci -nnk -s 02:00.0 | grep "driver in use"
# Kernel driver in use: nvme
# vfio-pci'ye bağla
echo "options vfio-pci ids=144d:a808" > /etc/modprobe.d/vfio.conf
echo -e "vfio\nvfio_iommu_type1\nvfio_pci" >> /etc/modules
update-initramfs -u -k all
reboot
# Doğrulama - artık vfio-pci yazmalı
lspci -nnk -s 02:00.0 | grep "driver in use"
# Kernel driver in use: vfio-pci
Kimliğe göre bağlamanın önemli bir yan etkisi vardır: aynı modelden birden fazla cihaz varsa hepsi birden ayrılır. İki özdeş NVMe diskiniz varsa ve biri ana makinenin sistem diskiyse, bu yöntem sunucunuzu açılamaz hâle getirir. Böyle durumlarda kimlik yerine PCI adresine göre bağlama yapan bir udev kuralı ya da driverctl aracı kullanın.
Son adımda cihazı makineye eklersiniz. Proxmox'ta:
# 210 numaralı makineye NVMe diskini PCIe olarak ver
qm set 210 -hostpci0 02:00.0,pcie=1
# Yapılandırmayı kontrol et
qm config 210 | grep -E "hostpci|machine|bios"
Konuk sistem açıldığında cihazı doğrudan görmelidir. Linux konukta lspci ve ilgili cihaz dosyaları (/dev/nvme0n1 gibi) kontrol edilir; disk tarafında bağlama ve kalıcı yapılandırma için disk bağlama, mount ve fstab yazısındaki adımlar aynen geçerlidir.
Hangi Cihazları Passthrough ile Vermek Mantıklı#
Her cihaz passthrough'a aday değildir; bazılarında kazanç önemsiz, bazılarında ise dezavantajlar avantajı bastırır.
| Cihaz | Passthrough mantıklı mı | Not |
|---|---|---|
| GPU (hesaplama/grafik) | Çok mantıklı | Taklit edilemez, tek gerçek yol budur |
| NVMe disk | Mantıklı | Düşük gecikme isteyen veritabanları için |
| RAID / HBA denetleyicisi | Mantıklı | Depolama VM'i (TrueNAS gibi) için diskleri doğrudan görmek şart |
| Ağ kartı | Duruma göre | 10G+ ve düşük gecikme gerekiyorsa; aksi hâlde VirtIO yeterli |
| USB denetleyicisi | Mantıklı | Lisans dongle'ı, yazıcı, seri cihaz için |
| Ses kartı | Nadiren | Genellikle GPU'nun ses fonksiyonu yeterli |
| SATA denetleyicisi | Dikkatli | Ana makinenin sistem diski aynı denetleyicideyse verilemez |
Ağ kartı satırındaki "duruma göre" ifadesini biraz açayım: modern VirtIO ağ sürücüsü 10 Gbit/s seviyesine kadar çok verimli çalışır ve canlı taşımaya izin verir. Passthrough ise gecikmeyi birkaç mikrosaniye düşürür ama taşımayı imkânsız kılar. Bu takas, ancak gerçekten gecikmeye duyarlı iş yüklerinde passthrough lehine döner. Sanal disk katmanında hangi denetleyicinin ne kadar fark yarattığını görmek için VirtIO sürücüleri ve disk performansı yazısına göz atın.
Passthrough'un Bedeli: Neleri Kaybedersiniz#
Bu bölümü atlayan çok kişi gördüm ve hepsi aynı yere çarptı. Passthrough performans kazandırırken sanallaştırmanın en değerli özelliklerinden bazılarını elinizden alır:
- Canlı taşıma (live migration) biter. Cihaz fiziksel olarak bir düğüme bağlıdır; makineyi başka düğüme kesintisiz taşıyamazsınız.
- RAM dahil anlık görüntü alınamaz.
--vmstateiçeren snapshot passthrough'lu makinelerde desteklenmez. Yalnızca kapalıyken yedek alabilirsiniz. - Aşırı tahsis (overcommit) kaybolur. Passthrough genellikle belleğin sabitlenmesini gerektirir; o RAM artık başka makinelerle paylaşılamaz.
- Cihaz paylaşılamaz. Bir kart aynı anda tek bir makinededir. Paylaşım için SR-IOV gerekir ve her cihaz bunu desteklemez.
- Kurtarma senaryosu zorlaşır. Sunucu arızalanırsa makineyi başka düğümde açmak için orada da aynı donanımın bulunması gerekir.
Bu maddeler passthrough'u kötü yapmaz; sadece bilinçli bir takas olduğunu gösterir. Yedekleme ve felaket kurtarma planınızı bu kısıtları bilerek kurun — düğüm dışına dosya seviyesinde yedek almak, imaj yedeğine güvenmekten daha sağlam bir yaklaşımdır.
Sık Yapılan Hatalar#
En yaygın hata, doğrulama adımlarını atlayıp doğrudan sanal makineye cihaz eklemektir. IOMMU açılmamışken qm set komutu hata vermez; sorun ancak makineyi başlatınca "vfio: error, group is not viable" mesajıyla ortaya çıkar ve insanlar mesajı yanlış yorumlayıp saatlerce grup ayarlarıyla uğraşır. Oysa sorun bir adım öncededir.
İkinci hata, kimliğe göre bağlamanın yan etkisini hesaba katmamaktır. ids= ile bağlama modele göre çalışır; aynı modelden ikinci bir cihaz ana makinenin işine yarıyorsa sunucu açılışta o cihazı kaybeder. Sistem diskiyle aynı modelden bir NVMe'yi passthrough'a vermeye çalışan biri, sunucusunu önyüklenemez hâle getirebilir.
Üçüncü hata, initramfs'i yeniden üretmeyi unutmaktır. /etc/modprobe.d/ altındaki dosyalar açılışın erken aşamasında initramfs'ten okunur; update-initramfs -u -k all çalıştırmazsanız yaptığınız değişiklik yeniden başlatmada hiçbir işe yaramaz ve cihaz eski sürücüsüne bağlanmaya devam eder.
Dördüncü hata, makine tipi ve BIOS seçimini önemsememektir. PCIe cihazlarını düzgün sunmak için q35 makine tipi gerekir; eski i440fx yalnızca klasik PCI topolojisi sağlar ve bazı cihazlar burada hiç başlamaz. Modern kurulumlarda OVMF (UEFI) tercih edin.
Sıkça Sorulan Sorular#
PCI passthrough için hangi CPU gerekir#
Intel tarafında VT-d, AMD tarafında AMD-Vi desteği olan bir işlemci gerekir. Bu özellik günümüzdeki sunucu işlemcilerinin tamamında, masaüstü işlemcilerinin ise çoğunda bulunur. Ancak CPU'nun desteklemesi yetmez: anakart üreticisinin de BIOS'ta bu özelliği sunması ve sizin açmanız gerekir. dmesg | grep IOMMU komutu size çalışıp çalışmadığını kesin olarak söyler.
IOMMU açık mı nasıl kontrol ederim#
En hızlı yol dmesg | grep -e DMAR -e IOMMU komutudur; "IOMMU enabled" benzeri bir satır görmelisiniz. İkinci ve daha kesin doğrulama, ls /sys/kernel/iommu_groups/ çıktısının boş olmamasıdır. Bu dizin boşsa IOMMU çalışmıyordur ve passthrough denemeye devam etmenin anlamı yoktur; önce BIOS ayarına ve çekirdek parametresine dönün.
Passthrough yapılmış makineyi canlı taşıyabilir miyim#
Hayır. Fiziksel cihaz belirli bir sunucuya bağlı olduğu için canlı taşıma desteklenmez; makineyi kapatmadan başka düğüme geçiremezsiniz. Kapalıyken taşımak mümkündür ama hedef düğümde de aynı donanımın bulunması ve PCI adreslerinin yapılandırmada güncellenmesi gerekir. Canlı taşıma sizin için kritikse passthrough yerine VirtIO tabanlı sanal cihazları tercih edin.
USB cihazı için passthrough şart mı#
Genellikle değil. Proxmox tek bir USB cihazını doğrudan makineye yönlendirebilir (qm set 200 -usb0 host=1234:5678) ve bu çoğu senaryo için yeterlidir. Tüm USB denetleyicisini passthrough ile vermek, çok sayıda cihaz bağlayacaksanız ya da cihazın sıcak takma davranışı sorun çıkarıyorsa anlamlıdır. Basit bir lisans dongle'ı için denetleyiciyi ayırmaya gerek yoktur.
Aynı cihazı birden fazla makineye verebilir miyim#
Standart passthrough ile hayır; cihaz bir anda tek bir makineye bağlanır. Paylaşım için cihazın SR-IOV desteklemesi gerekir. SR-IOV, tek bir fiziksel kartı birden çok "sanal fonksiyona" böler ve her birini ayrı makineye verebilirsiniz. Bu özellik kurumsal ağ kartlarında ve bazı hesaplama kartlarında bulunur; sıradan tüketici donanımında yoktur.
Passthrough güvenli mi#
IOMMU açıkken evet, makul ölçüde güvenlidir: cihazın DMA erişimi yalnızca kendi sanal makinesinin belleğiyle sınırlanır. IOMMU olmadan yapılan passthrough ise ciddi bir risktir; kart teorik olarak ana makinenin belleğinin herhangi bir yerine yazabilir. Ayrıca konuk sisteme donanım seviyesinde erişim verdiğiniz için, cihazın kendi ürün yazılımını güncelleyebilecek bir konuk teorik olarak kalıcı bir iz bırakabilir. Güvenilmeyen konuklara passthrough vermemek en sağlıklı politikadır.
Kapanış#
PCI passthrough, sanallaştırmanın soyutlama katmanını bilinçli olarak devre dışı bıraktığınız bir araçtır: performans ve doğrudan donanım erişimi kazanır, taşınabilirlik ve esneklikten ödün verirsiniz. Aklınızda kalması gereken dört şey şunlar: her adımdan sonra doğrulama komutunu çalıştırın, IOMMU gruplarını cihazı almadan önce kontrol edin, kimliğe göre bağlamanın aynı modeldeki tüm cihazları etkilediğini unutmayın ve yedekleme planınızı canlı taşımanın olmadığını bilerek kurun.
Kendi hipervizörünüzü kurup bu tür yapılandırmaları denemek istiyorsanız iç içe sanallaştırmaya açık nested sunucu ya da tam donanım kontrolü veren dedicated sunucu seçeneklerimiz uygun bir başlangıç noktası olur. Hesaplama için ekran kartı gerekiyorsa passthrough kurulumuyla uğraşmadan hazır gelen GPU VDS paketlerimize bakabilir, kurulum ve bakım yükünü devretmek isterseniz sunucu yönetimi hizmetimizden yararlanabilirsiniz.