
Hypervisor kodlarını paylaştım, tester arıyorum
Sadece amd işlemci gerekiyor denemek için ama Intel biri de denese olur çünkü virt öncesi amd değilse geri dönmesi lazım.

Sadece amd işlemci gerekiyor denemek için ama Intel biri de denese olur çünkü virt öncesi amd değilse geri dönmesi lazım.
Ellerim titriyor Birkaç haftadır bu projeyi yapıyorum. Sonunda çalıştı ve ne kadar zor olduğunu anlatmak istiyorum çünkü bu tür projelerde genellikle yaptım, işte repo kısmını görürsünüz, ortadaki acıyı görmezsiniz.
Proje ne?
Kısaca: çalışan bir Linux sistemine insmod yapıyorsunuz o andan itibaren kernel farkında olmadan AMD SVM guest VM'i olarak çalışıyor. Modül Ring -1'de hypervisor oluyor. rmmod yapınca 12 CPU temiz devirtualize oluyor, sistem bare metal'e dönüyor. Reboot yok, özel kernel yok, patch yok.
Buna Type-1.5 hypervisor deniyor, sistem açılmış, kernel çalışıyor, sonradan altına hypervisor enjekte ediliyor. Windows dünyasında buna "bluepill" deniyor. Linux'ta açık kaynak olarak bunu yapan bir LKM yok, en azından ben bulamadım. Asıl zorluk şu o anın fotoğrafını çekip kernele bıraktığı gibi yeri vermek herseyi registerdan cr4'e kadar artik 90larda degiliz islemcilerde bir ton şey var. 12 core bi de hayvan gibi deadlock veya race riski var.
Gerçekten zor olan kısımlar
Teoride basit görünüyor: VMCB hazırla, VMRUN çalıştır, VMEXIT'leri handle et. AMD dokumantasyon'u oku, SimpleSVM koduna bak, porta başla. İlk birkaç gün içinde bu birkaç günde biter diye düşündüm.
Yanılmışımmm
Triple fault ve hiç log yok iz yok neden yok boşluk siyah ekran hiç ışık yok.
İlk büyük engel şuydu: sistem anında triple fault yapıyor, dmesg'de hiçbir şey yok. Triple fault olduğunda CPU reset atıyor, kernel buffer'a yazamıyor. Hata nerede? Hiçbir fikrim yok.
Çözüm olarak framebuffer'a doğrudan yazmaya başladım initte /proc/iomem'den GOP adresi alıp her CPU'nun VMRUN öncesi ve sonrası durumunu renkli piksel blokları olarak ekrana çiziyordum. Debugger yok, serial port yok, sadece ekranda beliren renkler. Her renk bir CPU'nun ne kadar ilerlediğini gösteriyordu. Sonunda sorunun NPT'de olduğunu bu şekilde buldum. Burda bi ara nosmp ile tek çekirdeğe düşmek zorunda kaldım. Bu arada framebuffer yöntemi devirt esnasında sorun çıkardığı için son aşamalarda kaldırdım.
TLB shootdown deadlock
En sinsi bug buydu. Sistem görünürde çalışıyor, CPUID intercept çalışıyor, ama birkaç saniye sonra soft lockup.
Ne oluyordu? Bir CPU TLB flush gönderiyor, diğer CPU'ların acknowledge etmesini bekliyor. Ama diğer CPU'lar VMRUN içinde, IPI'ı handle etmiyor. Gönderen CPU sonsuza spin ediyor.
Çözüm basit görünüyor: INTR intercept ekle, IPI'ları handle et. Ama INTR intercept ekleyince bu sefer hard lockup NMI bile gelmiyor. Sonra anladım: interrupt re-inject yapmam lazım, yoksa IPI kayboluyordu.
Günlerce bu üzerinde çalıştım.
Sonunda farklı bir yaklaşım buldum INTR intercept olmadan, CPUID intercept'te flag kontrolü yaparak devirtualize. Her CPUID VMEXIT'te sv_should_exit flag'ini kontrol et, set edilmişse o CPU kendini devirtualize etsin. rmmod anında flag'i set et, CPU'ların çıkmasını bekle, sonra NPT'yi free et. Ama burda da bellek bariyerleri ve atomik olmaz zorundaydı ve log yoktu çünkü atomik bağlamda dmesg logu basamazsınız.
GS_BASE race
atomic_inc per-CPU pointer kullanıyor, bu %gs:offset ile erişiliyor. Ama vmload sonrası guest GS_BASE aktif yani kernel kodu guest GS_BASE ile per-CPU verisine erişmeye çalışıyor, yanlış adres, crash.
Fix tek satır: atomic_inc'i vmload'dan önceye taşı. Ama bunu bulmak saatler aldı.
NPT coverage GPU MMIO
AMD Radeon 760M entegre GPU'nun MMIO bölgesi ~288GB'ta. NPT identity map'im başlangıçta sadece RAM'i kapsıyordu (~18GB). Guest kernel GPU'ya erişmeye çalışınca NPF (Nested Page Fault), devirtualize crash.
Çözüm: identity map'i 1TB'a çıkarmak. Ama bu da başka soruna yol açtı vzalloc ile allocate edilen page table'lar GPU MMIO range'iyle çakışıyordu, rastgele pikseller beliriyordu ekranda. kzalloc'a geçince düzeldi.
Devirtualize sıralaması
rmmod anında 12 CPU'nun hepsinin devirtualize olmasını, sonra NPT'yi free etmem lazım. Ama nasıl emin olacaksın? Atomic counter her CPU devirtualize olunca increment ediyor, ana thread counter'ı poll ediyor. Basit ama implementasyonu doğru yapmak önemli. Counter'ı yanlış yerde increment edersen ya crash ya deadlock.
Şu anki durum:
insmod: 12/12 CPU virtualized
btop açık, sistem normal çalışıyor
rmmod: 12/12 CPU devirtualized (561ms içinde)
Repo şimdilik yok biraz kod temizliği ve debug log ve 2-3 optimizasyon vb yaptıktan sonra düşünüyorum. Saygılar.
Ülkemizin gündemi malum hypervizor projemin yanına keyfine Go tabanlı Webrtc kilifli Vless üstünden akan bir p2p trafik düşünüyorum ilk web uzantısı olabilir emin değilim şimdilik ama en büyük sorun ilķ buluşma ve hangi peer guvenli onu anlamak. Feyz aldığım proje V2ray ve Tor snowflake.
Hypervisor Nedir?
Hypervisor, işletim sistemlerini çalıştıran bir yazılım katmanıdır. Normalde işletim sisteminiz doğrudan işlemciyle konuşur. Hypervisor araya girerek bu konuşmayı dinler, yönetir, hatta değiştirir.
En bilinen örnek VirtualBox veya VMware bilgisayarınızda Windows çalıştırırken içinde Linux açabiliyorsunuz. İşte o Linux bir guest, VirtualBox ise hypervisor.
Tip 1, Tip 2 Tip 1.5 meselesi
Klasik sınıflandırma şöyle:
Tip 1 Bare Metal: Doğrudan donanım üzerinde çalışır, altında işletim sistemi yoktur. Örnek: VMware ESXi, Microsoft Hyper-V, Xen. Veri merkezlerinde sunucuları sanallaştırmak için kullanılır. Çok hızlı, çok güvenli.
Tip 2 Hösted: Mevcut bir işletim sisteminin üzerinde çalışır. Örnek: virtualbox hünlük kullanım için pratik ama Tip 1'den yavaş.
Tip 1.5: İkisi arası: İşte burada işler ilginçleşiyor. Çalışan bir işletim sisteminin altına gizlice yerleşen hypervsor'lar var. Sistem açıkken, yeniden başlatmaya gerek kalmadan, kernelin haberi olmadan araya girebiliyorsunuz. Teknik adı bluepill Matrix filmindeki mavi hapı yutan Neo gibi, sistem gerçekliğinin farkında bile değil.
Bu konsepti 2006'da güvenlik araştırmacısı Joanna Rutkowska ortaya attı. Windows Vistayı canlı olarak sanallaştirmus.
Peki Bu Nasıl Mümkün?
Modern işlemciler bu tür sanallaştırma için özel donanım desteği sunuyor. Intel'de buna VT-x, AMD'de SVM deniyor. İşlemci iki mod arasında geçiş yapabiliyor: guest ve höst
Hypervısor çalışmaya başladığında işlemciye şunu söylüyor: artık sen guest moddasın, her önemli şey yapmak istediğinde benden izin al. Islemci buna uyuyor cünkü bu özellik silokna işlenmiş.
Her onemli şey derken: CPUID komutu bellek yontemi, bazı MSR erişimleri hatta sanal makine içinde sanal makine açmaya çalışmak(L2-L1 meselesi inanılmaz karisik kvm respect) bile hypervisoru tetikleyebiliyor.
Linux Kernel Modülü Olarak Hypervisor
Linux'ta çekirdek her şeyi yönetiyor. Ama kernele sonradan ek modüller yükleyebiliyorsunuz sürücüler, dosya sistemleri gibi. Ben de bu mekanizmayı kullandım.
modülü yükledim. O andan itibaren:
Modül her CPU çekirdeği için hazırlık yaptı
İşlemciye artık hypervisor kontrolündesin dedi
Linux kernel, kendi donanımı üzerinde guest olarak çalışmaya devam etti
Kullanıcı hiçbir şey fark etmedi
Bu tür hypervisor'lara kernel modülü olarak implement edildiği için LKM hypervisor da deniyor(belki de denmiyorama ben uydurdum iste nis alan zaten bilgi yo). Avantajı: kurulumu ve kaldırılması teorik olarak çok kolay devantaji: sistem zaten çalışıyor, her şey hassas bir denge üzerinde duruyor en küçük yanlış 10 saat debug maratonu.
Işlemci mimarisini, bellek yönetimini, inerrupt sistemini bu kadar derinden başka türlü öğrenemezsinz bu arada.
Projeyi geliştirirken öğrendiklerim:
Modern Linux (7.x sürümü) üzerinde bunu yapmak inanılmaz zordu. Windows için yazılmış referans implementasyonlar var ama Linux çok daha katı güvenlik önlemleri uyguluyor. IBT (Bi ekliyor bi eklemiyor ömur torpusu), stack protector(asiri zirluyor), PREEMPT_FULL scheduler(zamanliyici civik her an bi risk), GS_BASE register yönetimi(kaydetmesi vb ayri dert) bunların hepsi hypervisor yazarken teker teker karşınıza çıkıyor ve her biri saatler süren debug gerektiriyor.
Kernel panic loglarını yakalamak için bile harici donanım kurmak zorunda kaldım ESP32 ile UART üzerinden log toplamak. Çünkü sistem Triple fault berince ekrana bakamazsınız, log dosyasına yazamazsınız(ölüm hız 1ns disk en az 20 ms) tek çare seri port üzerinden başka bir cihaza yollamak orda da baud düzgün değilse son 2-3 satır gider.
Bu arada son olarak işlemcilerin bile hatasız olmadığını hatırlayın bunlara errata deniyor.
Amd Vol 2 part 15
KVM
Respect