A glance at Virtual Machine Monitor

This article was released on www.codeproject.com.

Overview

1. Introduction

A virtual-machine monitor (VMM) manages the resources of the underlying hardware and provides an abstraction of one or more virtual machines [1]. Each virtual machine can run a complete operating system and its applications. Software running within a virtual machine is called guest software. All guest software runs in user mode; only the VMM runs in the most privileged level (kernel mode). The host OS is used to provide portable access to a wide variety of I/O devices [2]. virtual machine monitors export hardware-level abstractions to guest software using emulated hardware. The guest OS interacts with the virtual hardware in the same manner as it would with real hardware, for example IN / OUT instructions, and these interactions are trapped by the VMM and emulated in software. This emulation allows the guest OS to run without modification while maintaining control over the system at the VMM layer [2].

Virtualization has become an important tool in computer system design, and virtual machines are used in a number of sub-disciplines ranging from operating systems to programming languages to processor architectures. By freeing developers and users from traditional interface and resource constraints, virtual machines enhance software interoperability, system impregnability, and platform versatility [4]. The primary motivation for using a virtual machine is that it decouples the design of computer software from the evolution and diversity of computer hardware and operating systems. This is because the same application code can be used on any system that supports the appropriate virtual machine. Advocates of virtual machines say that it is far more convenient to implement a single virtual machine for each computer than it would be to re-implement or even just recompile each application for every different system. Furthermore, a virtual machine that allows one program to be used on different computers also aids mobility: allowing programs to move seamlessly between computers, perhaps to follow the user to a different physical location, or to relocate from a busy computer to an idle one [3]. By virtual machine, a software-implemented abstraction of a physical machine that is at a low-enough level to run an operating system, running the Operating System inside a virtual machine enables the programmer to stand outside the Operating System being debugged. From this vantage point, the programmer can use a debugger to examine and control the execution of the Operating System without perturbing its state [5].

The continued success of VMMs suggests that the technology possesses inherently useful traits. In this view, several factors contribute to the current popularity of Virtual Machine Monitors [7]:

2. Classification

The VMM must be able to export a hardware interface to the software in a virtual machine that is roughly equivalent to raw hardware and simultaneously maintain control of the machine and retain the ability to interpose on hardware access. Various techniques can help achieve this, each offering different design tradeoffs. When evaluating these tradeoffs, the central design goals for VMMs are compatibility, performance, and simplicity. Compatibility is clearly important, since the VMM’s chief benefit is its ability to run legacy software. The goal of performance, a measure of virtualization overhead, is to run the virtual machine at the same speed as the software would run on the real machine. Simplicity is particularly important because a VMM failure is likely to cause all the virtual machines running on the computer to fail. In particular, providing secure isolation requires that the VMM be free of bugs that attackers could use to subvert the system [8].

Virtualization software can be applied in several ways to connect and adapt the three major system components Emulation adds considerable flexibility by permitting mix-and-match cross-platform software portability. Virtualization software can enhance emulation with optimization, by taking implementation-specific information into consideration as it performs emulation, or it can perform optimization alone, without emulation. Virtualization software can also provide resource replication, for example by giving a single hardware platform the appearance of multiple platforms, each capable of running a complete operating system and/or a set of applications [9]. Finally, the various types of virtual machines can be composed to form wide variety of architectures, freed of many of the traditional compatibility constraints, FIG. 1 .

FIG. 1. VMM Classification [6].

In many levels of abstraction, the meaning of machine is a matter of perspective. From the perspective of a process, the machine consists of a memory address space that has been assigned to the process, along with user level registers and instructions that allow the execution of code belonging to the process. The I/O system, as perceived by the process, is rather abstract. Disks and other secondary storage appear as a collection of files to which the process has access permissions. In the desktop environment, the process can interact with a user through a window that it creates within a larger graphical user interface. The only way the process can interact with the I/O system of its machine is via operating system calls, either directly, or through libraries that are supplied to the process [9].

From a higher level perspective, an entire system is supported by an underling machine. A system is a full execution environment that can simultaneously support a number of processes potentially belonging to different users. All the processes share a file system and other I/O resources. The system environment persists over time, with occasional reboot, as processes come and go. The system allocates physical memory and I/O resources to the processes, and allows the processes to interact with their resources via an OS that is part of the system [9].

Virtualization provides a way of getting around such constraints. Virtualizing a system or component, such as a processor, memory, or an I/O device, at a given abstraction level maps its interface and visible resources onto the interface and resources of an underlying, possibly different, real system. Consequently, the real system appears as a different virtual system or even as multiple virtual systems. The concept of virtualization can be applied not only to subsystems such as disks but to an entire machine. To implement a virtual machine, developers add a software layer to a real machine to support the desired architecture. By doing so, a virtual machine can circumvent real machine compatibility and hardware resource constraints [4].

Process or System

From the perspective of a process executing a user program, the machine consists of a logical memory address space assigned to the process along with user-level instructions and registers that allow the execution of code belonging to the process. From the perspective of the operating system and the applications it supports, the entire system runs on an underlying machine. A system is a full execution environment that can support numerous processes simultaneously. From the system perspective, therefore, the underlying hardware's characteristics alone define the machine; it is the ISA that provides the interface between the system and machine [4].

A process virtual machine is a virtual platform that executes an individual process. This type of virtual machine exists solely to support the process; it is created when the process is created and terminates when the process terminates. In contrast, a system virtual machine provides a complete, persistent system environment that supports an operating system along with its many user processes. It provides the guest operating system with access to virtual hardware resources, including networking, I/O, and perhaps a graphical user interface along with a processor and memory. The process or system that runs on a virtual machine  is the guest, while the underlying platform that supports the virtual machine  is the host. The virtualizing software that implements a process virtual machine is often termed the runtime software. The virtualizing software in a system virtual machines typically referred to as the virtual machine monitor [4].

Paravirtualization or Hardware interposition

Denali VMM research group (denali.cs.washington.edu), after working from the premise to a virtual machine abstraction, categorized the virtualization in two major group: paravirtualization and hardware interposition [7]:

Denali’s use of paravirtualization has parallels with earlier work in operating system design. Researchers in the 1970s proposed impure virtual machine architectures to improve performance or reduce implementation complexity. In a similar vein, microkernel systems such as Mach expose low-level abstractions, which are similar to but differ from a hardware interface [7].

3. Implementation

When the virtual machine performs the same task, different physical states of the computer can realize the same virtual states. For instance, if I enter some text in one window, then delete the text, do something else in another window, and then come back and enter the same text into the first window again, the second text entry may be recorded at different memory addresses than the first. Those used initially may have been reassigned other tasks by what I did in the second window. Although the physical realizations of a virtual state can be in different places (different memory addresses) in the computer at different times, the virtual state nevertheless plays a fixed functional role in computation. For example, a compiler creates a word processor by creating virtual states that work the same way every time they occur, but the virtual states may be realized in different memory locations each time they occur, with the result that different physical states of the computer realize the same virtual state on different occasions [12].

Although the specifics of a virtual machine monitor's implementation are architecture-dependent, virtual machine monitors tend to rely on similar implementation techniques. Among these techniques is configuring the real machine so that virtual machines can safely and directly execute using the machine’s CPU and memory. By doing this, virtual machine monitors can efficiently run software in the virtual machines at speeds close to that achieved by running them on the bare hardware [10]. Virtual machine monitors can also fully isolate the software running in a virtual machine from other virtual machines, and from the virtual machine monitor.

A common way to virtualize the CPU is to run the virtual machine monitor in the most privileged mode of the processor, while running virtual machines in less privileged modes. All traps and interrupts that occur while a virtual machine is running transfer control to the virtual machine monitor. Attempts by the virtual machines to access privileged operations trap into the virtual machine monitor; the virtual machine monitor emulates privileged operations for the virtual machine. In this architecture, the virtual machine monitor can always control the virtual machine regardless of what the software in the virtual machine does. Memory is commonly virtualized by keeping a virtual Memory management unit for each virtual machine that reflects the virtual machine’s view of its address space. The virtual machine monitor retains control of the real memory management unit, and maps each virtual machine’s physical memory in such a way that virtual machines do not share physical memory with each other, or with the virtual machine monitor. Through this technique the virtual machine monitor is able to create the illusion that each virtual machine has its own address space that it fully controls. This also allows the virtual machine monitor to isolate the virtual machines from one another and prevents them from accessing the memory of the virtual machine monitor. In addition to virtualizing the CPU and memory, the virtual machine monitor intercepts all input/output requests from virtual machines to virtual devices and maps them to the correct physical I/O device. For memory-mapped I/O, the virtual machine monitor only allows a virtual machine to see and access the particular I/O devices it is permitted to use [11].

In a traditional virtual machine monitor the virtual hardware exposed is functionally identical to the underlying machine [14]. Although full virtualization has the obvious benefit of allowing unmodified operating systems to be hosted, it also has a number of drawbacks. This is particularly true for the prevalent IA-32, or x86, architecture. Support for full virtualization was never part of the x86 architectural design. Certain supervisor instructions must be handled by the virtual machine monitor for correct virtualization, but executing these with insufficient privilege fails silently rather than causing a convenient trap [15]. Efficiently virtualizing the x86 memory management units also difficult. These problems can be solved, but only at the cost of increased complexity and reduced performance. Notwithstanding the intricacies of the x86, there are other arguments against full virtualization. In particular, there are situations in which it is desirable for the hosted operating systems to see real as well as virtual resources: providing both real and virtual time allows a guest Operating System to better support time-sensitive tasks while exposing real machine addresses allows a guest OS to improve performance. An approach which has been dubbed is paravirtualization [16]. This promises improved performance, although it does require modifications to the guest operating system. It is important to note, however, that it does not require changes to the application binary interface, and hence no modifications are required to guest applications. The paravirtualized x86 interface is factored into three broad aspects of the system: memory management, the CPU, and device I/O [13]:

CPU virtualization

A CPU architecture is virtualizable if it supports the basic virtual machine monitor technique of direct execution, executing the virtual machine on the real machine, while letting the virtual machine monitor retain ultimate control of the CPU. Implementing basic direct execution requires running the virtual machine's privileged and unprivileged code in the CPU's unprivileged mode, while the virtual machine monitor runs in privileged mode. Thus, when the virtual machine attempts to perform a privileged operation, the CPU traps into the virtual machine monitor, which emulates the privileged operation on the virtual machine state that the virtual machine monitor manages. The VMM handling of an instruction that disables interrupts provides a good example. Letting a guest operating system disable interrupts would not be safe since the VMM could not regain control of the CPU. Instead, the VMM would trap the operation to disable interrupts and then record that interrupts were disabled for that virtual machine. The VMM would then postpone delivering subsesubsequent interrupts to the virtual machine until it reenables interrupts. Consequently, the key to providing virtualizable architecture is to provide trap semantics that let a VMM safely, transparently, and directly use the CPU to execute the virtual machine. With these semantics, the VMM can use direct execution to create the illusion of a normal physical machine for the software running inside the virtual machine. [8].

A strategy for virtualizing the Intel architecture would be as follows [17]:

Execution of Privileged Instructions

When executing in a virtual machine, some processor instructions can not be executed directly on the processor. These instructions would interfere with the state of the underlying virtual machine monitor or host Operating System and are called sensitive instructions. The key to implementing a virtual machine monitor is to prevent the direct execution of sensitive instructions[17].

Sensitive Register Instructions. Several Intel instructions break hardware virtualization require that read or change sensitive registers and/or memory locations such as a clock register and interrupt registers. The rule states that instructions are sensitive if they read or change sensitive registers and/or memory locations such as a clock register and interrupt registers [17].

Protection System References. Many Intel instructions violate require that reference the storage protection system, memory system, or address relocation system: Instructions are sensitive if they reference the storage protection system, memory or address relocation system.

The ideas and techniques of virtualizing a machine can be carried over to many different architectures, provided they have a capable feature set. Virtualization can also use various schemes depending on the architecture, the operating systems to be run, and other considerations. Some CPU architectures provide virtualization naturally. Others like IA32 require additional software to completely virtualize the CPU [18].

IA32 Virtualization

Unfortunately, the IA32 architecture is not completely naturally virtualizable. There are a number of instructions for which write access to system registers is not allowed from user code, but read access is allowed. So we must coerce the processor into trapping out when potentially problematic instructions are executed; ones that the processor does not offer us a natural hardware protection against. In a nutshell, this problem boils down to how to breakpoint (BPX) on the execution of arbitrary instructions, since the IA32 CPU won't always do this for us. And do this, without the guest OS detecting any changes; otherwise it's execution path could be altered. [18].

A list of x86 instructions which need special consideration with respect to virtualization:

instructions protected in ring3 [18]:

instructions protected in ring3 by IOPL aid:

instructions protected in ring3 by special commentary:

instructions unprotected in ring3:

instructions which effect a control transfer or interrupt:

We can handle the instructions which have native protection in ring3 while running at user-level, by an exception handler which emulates the instruction in our virtualization context. This is exactly what a v8086 mode monitor does. One of the key tasks we have, is to protect against the execution of that small set of instructions which do not invoke native IA32 protection mechanisms that is done in virtual machine monitor software. The path of execution of code can be thought of simply as starting at a well defined address, and passing through many branches - jumps, calls, interrupts, etc - along the way. Since we know where execution begins, we can fetch and decode a sequence of instructions up to a branch instruction, and place a breakpoint there. We could then execute the code, which will generate a breakpoint exception at the branch instruction. Our virtualization monitor would receive the exception, effect the branch in the guest code, and given the new target address after the branch, repeat the same process for the next code sequence. Using this method, we are free to place breakpoints on arbitrary instructions, not just branch instructions. So we can force the guest code to generate exceptions on any instructions [18].

4. Conclusion

The VMM resurgence seems to be fundamentally altering the way software and hardware designers view, manage, and structure complex software environments. VMMs also provide a backward- capability path for deploying innovative operating system solutions that both meet current needs and safely pull along the existing software base. This capability will be key to meeting future computing challenges [8]. In the future, we expect that innovations will arise from applying virtual machine technology in new and innovative ways. One opportunity will be to leverage the strong isolation of virtual machines to avoid configuration conflicts between applications running on a single system. Another opportunity would be to use VMMs to simplify software testing and debugging[7].

References

By: Ashkbiz Danehkar