Skip to content

KVM & QEMU

KVM biến Linux kernel thành hypervisor, QEMU là chương trình userspace tạo VM và giả lập thiết bị. Hai thành phần này thường đi cùng nhau.

Phân vai

Thành phần Chạy ở Vai trò
KVM (kvm.ko, kèm kvm-intel/kvm-amd trên x86) Kernel Dùng ảo hóa phần cứng (CPU, memory), chạy vCPU, xử lý các VM exit đơn giản
QEMU Userspace Cấp phát RAM cho guest, giả lập hoặc cung cấp thiết bị (virtio), xử lý các exit cần thiết bị (MMIO, PIO)
libvirt (tùy chọn) Userspace Lớp quản lý (XML, virsh, virt-manager) bên trên QEMU

KVM không tự tạo được VM hoàn chỉnh vì thiếu thiết bị, nên cần một VMM (Virtual Machine Monitor) ở userspace. QEMU là VMM phổ biến nhất, ngoài ra có Firecracker, Cloud Hypervisor, crosvm (xem Sandbox & micro-VM).

Cách KVM hoạt động

Userspace nói chuyện với KVM qua các ioctl trên /dev/kvm:

  1. KVM_CREATE_VM: tạo VM, nhận về một file descriptor.
  2. KVM_SET_USER_MEMORY_REGION: gán một vùng nhớ của tiến trình QEMU làm RAM của guest (GPA sang vùng nhớ đó).
  3. KVM_CREATE_VCPU: tạo vCPU, mỗi vCPU tương ứng một thread của QEMU.
  4. KVM_RUN: thread vào guest. Khi guest gây exit mà kernel không tự xử lý được (ví dụ truy cập MMIO của thiết bị giả lập), KVM_RUN trả về userspace với lý do exit, QEMU xử lý rồi gọi KVM_RUN lại.

Vì vCPU là thread thường nên Linux scheduler, cgroups, taskset đều áp dụng được cho VM.

Ảo hóa và giả lập trong QEMU

QEMU có hai chế độ chạy mã guest:

  • KVM accelerator (-enable-kvm hoặc -accel kvm): kiến trúc guest phải trùng host, tốc độ gần native.
  • TCG (Tiny Code Generator): dịch lệnh động, cho phép guest khác kiến trúc (ARM trên x86), chậm hơn nhiều. Đây là giả lập, không phải ảo hóa.

QEMU còn có chế độ user-mode, chỉ chạy một chương trình khác kiến trúc, không phải cả hệ thống, xem QEMU cross-arch.

Kiểm tra máy có KVM

ls -l /dev/kvm                                    # có node này là KVM đã sẵn sàng
grep -Ec '(vmx|svm)' /proc/cpuinfo                # x86: >0 nghĩa là CPU hỗ trợ VT-x/AMD-V
lsmod | grep kvm

Quyền truy cập /dev/kvm thường cần thuộc nhóm kvm. Trong VM cloud hoặc Codespaces thường không có /dev/kvm nếu nhà cung cấp không bật nested virtualization.

Ví dụ

Tạo đĩa và chạy VM x86 với KVM, thiết bị virtio:

qemu-img create -f qcow2 disk.qcow2 20G

qemu-system-x86_64 -accel kvm -cpu host -m 2G -smp 2 \
    -drive file=disk.qcow2,if=virtio \
    -cdrom ubuntu.iso \
    -netdev user,id=n0 -device virtio-net-pci,netdev=n0 \
    -nographic

Chạy kernel ARM64 trên máy ảo virt (không cần board thật), rootfs nằm trên đĩa virtio:

qemu-system-aarch64 -machine virt -cpu cortex-a57 -m 1G -smp 2 \
    -kernel Image -append "console=ttyAMA0 root=/dev/vda rw" \
    -drive file=rootfs.ext4,if=none,format=raw,id=hd0 \
    -device virtio-blk-device,drive=hd0 \
    -netdev user,id=n0 -device virtio-net-device,netdev=n0 \
    -nographic

Khi host cũng là ARM64 có KVM, thay -cpu cortex-a57 bằng -cpu host và thêm -accel kvm. Thoát QEMU ở chế độ -nographic: Ctrl + A rồi X.

Dùng trong phát triển embedded

  • Thử kernel và driver trên máy virt (ARM, ARM64, RISC-V) trước khi có board, debug bằng -s -S (gdbserver ở cổng 1234, dừng chờ debugger).
  • Phát triển driver virtio, kiểm thử device tree, boot flow với QEMU, kết hợp với Device Tree.
  • Một số SoC (ví dụ nhiều dòng ARM64) chạy được KVM thật, dùng làm hypervisor cho Linux guest cạnh RTOS, nhưng nếu cần cô lập cứng và real-time hơn thì xem Partitioning hypervisor.

Đọc thêm