Writing a KVM client

Writing a KVM client

linux
linux, kernel, kvm

Major steps required in the workflow #

  1. Open /dev/kvm
  2. Obtain KVM API version
  3. Check extension if Needed
  4. Create a virtual machines
  5. Allocate memory for the virtual machines
  6. Create virtual CPUs
  7. Initialize registers
  8. Run guest code

The documentation for KVM API is available at Link. The KVM provides an API via a special node /device/kvm. We use this node and ioctl interface to communicate and setup the VM. The ioctl’s can be differentiated into KVM System API, Virtual machine API, vCPU API and device API The /dev/kvm node is used to control the KVM system and to create new VM’s. The Virtual machine API is used to control individual virtual machine. The vCPU API is used to control the operations of a single virtual CPU.

To build a virtual machine we’ll first need to open the kvm device
int kvm_fd = open("/dev/kvm", O_RDWR | OCLOEXEC);
So we are opening the /dev/kvm with read write and exec permissions.

The next step is to check the KVM API version. this can be done with an ioctl call with KVM_GET_API_VERSION agrument.
int version = ioctl(kvm_fd, KVM_GET_API_VERSION, NULL);
This is to make sure that you are working with a stable version, which in our case would be 12 as previous APIs were unstable and indeed we get the version as 12 for our application.

We then create a virtual machine, which represents the emulated system, its memory and its CPUs. int vmfd = ioctl(kvm_fd, KVM_CREATE_VM, (unsigned long)0);

VMs memory is provided in pages. This corresponds to the physical space as seen by the VM. So the virtual address that is provided by the host is seen as a physical address by the VM.

We allocate memory for the VM using mmap, we zero initialize the memory as well.



https://lwn.net/Articles/658511/
https://zserge.com/posts/kvm/
https://zserge.com/posts/containers/
https://docs.kernel.org/virt/kvm/api.html
https://medium.com/@michael2012zhao_67085/learning-virtualization-with-kvmtool-f99298ea44dc
https://github.com/kata-containers/kata-containers



Hypervisors that use these API's:<br>
[novm](https://github.com/google/novm): A lightweight hypervisor written in Go that uses KVM api
[kvmtool](https://github.com/kvmtool/kvmtool): A lightweight tool for hosting KVM guests
[Kata Containers](https://github.com/kata-containers/kata-containers): creates a KVM virtual machine for each container or periodic

ret = ioctl(kvm, KVM_GET_API_VERSION, NULL);

if (ret != 12){
  errx(1, "KVM_GET_API_VERSION %d, expected 12", ret);
}

vmfd = ioctl(kvm, KVM_CREATE_VM, (unsigned long)0);