In the previous blog https://medium.com/@jain.sm/virtualization-part-2-memory-virtualization-79b1c804e160 we talked of memory virtualization. In this blog we touch upon CPU virtualization
Before we take a peek at CPU virtualization it would be interesting to understand how the protection rings are built into x86 architecture. These rings allow the cpu to protect memory and control privileges as to what code executes at what privilege level.
The x86 architecture has a concept of protection rings. The Kernel runs in the most privileged mode AKA Ring 0 and the userspace used for running processes run in Ring 3.
The hardware enforces that all privileged instructions get executed in Ring 0. If any attempt is made to run a privileged instruction in Ring 0 the CPU generates a fault.
At a high level this is controlled by code segment register via CPL bit. All calls from Ring 3 are gated to Ring 0. So as an example a system call can be made by an instruction like syscall which in turn sets the right CPL level and executes the kernel code with a higher privilege level. Any attempt to directly call high privilege code from upper rings lead to a hardware fault.
The same concept applies for virtualized OS. In this case the guest is de-privileged and is run in Ring 1 and Process of Guest in Ring 3. The VMM itself runs in Ring 0. In case of fully virtualized guest this means that any privileged instruction has to be trapped and emulated. VMM emulates the trapped instruction. Over and above the privileged instructions the sensitive instructions also need to be trapped and emulated by VMM.
History of x86 is that it was not virtualizable. What this means is that not all sensitive instructions are privileged. Instructions like SGDT,SIDT and more can be executed in Ring 1 without being trapped. This can be harmful for running a guest OS as this gives a peek to host kernel data structures to the guest.
The above problem can be addressed by
1. Binary Translation in case of Full Virtualization
2. Paravirtualization as in case of XEN with hypercalls
X86 in 2005 finally became virtualizable. They introduced one more ring called Ring -1 which is also called VMX root mode. The VMM runs in VMX root mode and the guests run in non-root mode.
This means that the guests continue to run in Ring 0 and for majority of the instructions there is no trap. For some privileged/Sensitive instructions the VMM is executed in root mode via the trap. We call this switches as VM Entries and VM Exits.
Over this the hardware manages a data structure called VMCS (VM control structure). This has the state of the VM and registers. The hardware uses this during the VM Entries and exits. The VMCS structure is similar to the task_struct data structure used to represent a process. One VMCS ptr points to the currently active VMCS.
When a trap to VMM happens, VMCS provides the state of all guest registers, reason of exit etc.
Advantages of hardware assisted virtualization
1. No binary translation
2. No OS modification
Problem is the VM Entry and Exits are still heavy calls involving lot of CPU cycles as the complete VM state has to be saved and restored. Considerable work has gone in to reduce the cycles of these exits.
In next blog I intend to touch upon a bit on IO Virtualization (https://medium.com/@jain.sm/io-virtualization-731f6b1744ac)and different techniques involved.
Disclaimer : The views expressed above are personal and not of the company I work for.
