Summary

Completed
  • To virtualize an I/O device, we ought to follow two main steps: (1) construct a virtual version of the device and (2) virtualize the I/O activity routed to the device.
  • Constructing a virtual version of an I/O device entails sharing the device across multiple guest OSs.
  • Virtualizing the I/O activity to an I/O device passes through the device's controller. (Each I/O device has a device controller.)
  • A device controller can be signaled via either a privileged I/O instruction (defined in ISA) or memory-mapped I/O.
  • I/O instructions and memory-mapped addresses are handled in system mode to protect the called I/O devices.
  • I/O instructions and memory-mapped addresses are not critical, and thus can be easily handled by the hypervisor after naturally trapping to it. (Because they are privileged and not critical, they will naturally trap to the hypervisor when run in user mode.)
  • General-purpose OSs abstract most of the details of I/O devices and make them accessible only through well-defined interfaces, such as the system call interface, the device driver interface, and the operation-level interface.
  • In the presence of a hypervisor, two different device drivers must be supported per I/O device, versus only one in traditional nonvirtualized systems.
  • The redundancy of device drivers in the presence of a hypervisor is usually circumvented by collocating the hypervisor with a major OS on the same machine. Subsequently, the hypervisor leverages the device drivers of the major OS without requiring special device drivers. (Xen Project applies this approach.)
  • Because all I/O instructions are privileged, they need to be intercepted by the hypervisor.
  • In principle, the hypervisor can intercept I/O requests at any of the three interfaces: the system call interface, the device driver interface, and the operation-level interface.
  • Intercepting I/O requests at the operation-level interface might lead to the loss of some essential information about I/O actions.
  • Intercepting I/O requests at the system call interface (i.e., the ABI) entails emulating the ABI routines of every guest OS. (Different OSs have different ABI routines.)
  • In practice, intercepting I/O requests at the device driver interface is typically the most efficient approach because it avoids emulating the ABI routines of every guest OS and losing some necessary information about I/O actions.