KVM ve QEMU ile Donanım Destekli Sanallaştırma

2021-04-27 | Tags: #kvm #qemu #sanallastirma

Donanım destekli sanallaştırmada CPU'lar sanallaştırma işlemlerini yapmaktadırlar. Donanım destekli sanallaştırma, yazılım sanallaştırmaya göre çok daha hızlı çalışmaktadır. Intel VT-X veya AMD-V buna örnek olarak verilebilir. Bir çok hypervisor da donanım desteklerinden faydalanmaktadır. * Yeni bir CPU modu sunulmuş oluyor ==> VMX .

Bu yazıda Qemu/KVM kullanılarak basit bir örnek de yapacağız.

Qemu Mimarisi

QEMU (Quick Emulator) ihtiyaç duyulan donanımları hızlı bir şekilde taklit edebilecek bir emülatördür. QEMU farklı CPU çeşitlerini (x86, PowerPC, ARM vb.) farklı mimarilerde (x86, PowerPC, ARM, Sparc, MIPS vb.) kullanmaya izin vermektedir. Aynı zamanda donanım ile sanallaştırmayı da desteklemektedir.

  • Qemu bir userspace process'idir. Yani aslında bilgisayar üzerinde çalışan bir programdan çok da bir farkı yoktur.
  • Qemu ve KVM birlikte kullanılabilmektedirler.
  • Qemu ve KVM işlemleri şu şekilde sıralanabilir.
  • KVM ile haberleşmenin sağlanması
  • Oluşturulacak sanal makine için fiziksel bellek ayrılması
  • Oluşturulacak her sanal CPU için bir thread'in oluşturulması
  • KVM ile haberleşmenin sağlanabilmesi

Örnek kod parçaları

kvmq->kvm_fd = open("/dev/kvm", O_RDWR | O_CLOEXEC); // KVM'in açılması

uint8_t ver = ioctl(kvmq->kvm_fd, KVM_GET_API_VERSION, 0); // Basit bir KVM ioctl'in oluşturulması 

if (ver != 12){
    fprintf(stderr, "KVM_GET_API_VERSION %d, expected 12",ver);
    return NULL;
}

Qemu ve KVM arasındaki genel şemayı da bu şekilde çizebiliriz. (KVM kernel seviyesinde (ring 0) QEMU ise userspace'de (ring 3) de çalışmaktadır. )

Qemu ve KVM arasındaki en önemli işlemlerden birisi ise KVM_RUN ioctl'inin çalıştırılması. Bu işlemi de basit bir döngü üzerinde açıklamak gerekirse:

while (!kvm_exit)
{
    ret = ioctl(kvm->vcpu->vcpu_fd, KVM_RUN, NULL);
    switch (kvm->vcpu->kvm_run->exit_reason)
    {
        case KVM_EXIT_IO:
        {
        }
        case KVM_EXIT_HLT:
        {
        }
        default:
        {

        }
    }
}

KVM_RUN ioctl'i çalıştıktan sonra QEMU bloklanıyor ve kontrol KVM'e geçiyor. Burada KVM işlemlerini bitirdikten sonra file descriptor üzerinden çıkış nedenini belirtiyor. Bu şekilde KVM'in işlemlerimizi yerine getirip getiremediğini anlayabilmekteyiz. Sanallaştırma işlemlerine devam ederken iki önemli konu karşımıza çıkmaktadır. Bunlar: 1. Bellek Sanallaştırması 2. I/O Sanallaştırması

VT-x ve VMX

VT-x sayesinde x86 sistemlerde sanallaştırma yapabilmek mümkündür. Bunu kontrol etmek için cat /proc/cpuinfo | grep "vmx" yazabiliriz.

VMX Mode - Bunlar bazı özel CPU komutlarıdır. - VMLAUNCH, VMRESUME, VMEXIT

Bu komutlar kullanıldıkları zaman base OS ile sananallaştırılan OS arasında veri alışverişi olmaktadır. Burada sanallaştırılan cihazının page-tableları, registerları base OS'e aktarılmaktadır. Ancak bu verilerin OS'de tutulamaz bunun için VMCS (VM control structure) bulunmaktadır. Burada VMCS KVM ve CPU arasındaki iletişimi sağlamaktadır.

Ayrıca vmcs hakkında daha detaylı bilgi edinebilmek için https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/intel-vmcs-shadowing-paper.pdf kaynağına göz atmakta fayda var.


This was the end of the blog post. You can reach me via email umusasadik at gmail com