Next week, (10/29) I’ll be starting to publish a series that is written to aid new and interested readers with building, testing, and understanding type-2 hypervisor development. This hypervisor will be written for use on Intel processors with virtualization support. If you’re operating on an AMD chip, you may find some parts helpful, but overall it may not be what you need to understand the nuances. All concepts for each article, their importance, the references to more detailed information, and otherwise will be linked through just like any other of my blog posts followed by a recommended reading section at the end should your thirst for details and knowledge not be satisfied. I will also put recommended reading for those of you with interest in developing an AMD SVM.
Note: This hypervisor will be written for Intel x86-64 (64-bit) using C.
Below is a list of sections and brief descriptions that will be posted, in order over the next week:
- Day 0: Setting up test environment, scripts, shared folders, and WinDbg shortcuts.
- This article will detail what testing environment will be used throughout the series, how to setup both serial and network debugging, writing scripts to aid in efficient and fast stand-up for testing, and creating WinDbg shortcuts to quicken debugging init.
- Day 1: Driver skeleton, introduction to virtualization, type definitions and the reasoning behind detailing them, compiling, and running unit tests.
- This will provide a walk-through on constructing a basic driver skeleton for usage, explain the different pieces and their purpose, introduce virtualization and the various components in great detail, and then provide type definitions, their purpose, and where more information can be found. We’ll close with compiling and running unit tests to verify that everything is written properly and running as expected. (You may find this boring, but it is an incredibly important part of any project.)
- Day 2: Writing communication channel for client and VMM, defining important context structures, detailed explanation of important VMM regions, allocating, building, and testing initialization of basic constructs on a single processor.
- This will likely be lengthy, more lengthy than the previous two, and be the most important one to read all the way through. It will provide details on communicating with your driver, the importance of designing the structure of your hypervisor before implementation, and will explain the various VMM regions required for basic initialization and entrance into VMX operation. All of this will be done for a single processor to lower complexity, Day 3 will begin multi-processor initialization.
- Day 3: Multi-processor initialization, setting up VMM regions on MP systems, error checking, VMX instructions, and the importance of unwinding actions.
- In this article we’ll discuss multi-processor initialization, and the various ways to initialize all cores. As well as implementing solid error checking mechanisms and procedures, introducing VMX instructions and their nuances, and the article will conclude with the importance of unwinding actions (the ability to gracefully recover from errors, free what has been allocated, and return to a stable system state.)
- Day 4: VMCS initialization, the differences in guest state versus host state, operation visualization, and the use of intrinsic functions.
- This article will be detailed, fast paced, with lots of reference material. There is an entire chapter in the Intel SDM Volume 3C dedicated to VMCS encoding, init, and guest/host state operation. We will only be covering the very basics for understanding. I will also help the reader visualize how operation is entered, exited, and resumed to make it easier to understand the abstractness. We will also cover the implementation of important intrinsic functions required for setting up various guest and host VMCS components.
- Day 5: Implementing unconditional vmexit handlers, and testing start-up and shutdown.
- This day will cover the introduction and details on segmentation on Intel x86-64, demystifying initialization of guest and host segment data. Also, including implementation of the vmexit handler to handle unconditional exits that will occur, explaining the assembly stubs, and will conclude with a test of the hypervisor to verify that it starts and runs stably, and shuts down gracefully returning the system to a stable pre-operation state.
- Day 6: CPUID emulation example, recommended reading for EPT initialization and usage, and author anecdotes.
- This is the end, by now the hypervisor will be in an operational state, and able to be built upon by the author. We’ll conclude this series with an example using the cpuid instruction and emulating responses and providing spoofed information. The final source for the basic hypervisor will be included in this post, as well as recommended articles for further development.
I hope to later have a 7 day series on EPT (Extended Page Table) implementation, and the mythical APIC virtualization. For now, those are still works in progress, but keep an eye on the blog because I’m sure by the new year there will be another series ready for reader consumption.
As an aside, prior to any post for this series it is strongly recommended that if you intend to be proficient and knowledgeable on the subject of virtualization and the microarchitecture in general that you read the recommended reading, all of it – and take notes and put the knowledge into practice. This will be repeated every post, and pushed in your face because details matter.
I hope you enjoy the series! Leave me feedback, questions, comments, or recommendations in the comment section or contact me on twitter.
This series was inspired by the writing and enthusiasm of Sinaei and his articles that cover similar and extended parts of hypervisor development. Those can be found here and throughout the recommended reading sections in each article.
Other supplemental reading in each article will be based on content of that day, you may find some tweets, blogs, or gists from other hypervisor authors. All will be credited when used!
I’d also like to thank dude719, and drew for their helpful insights at various times while working with virtualization. Both are very meticulous and have a different way of doing things, and these two have an impressive knowledge-base that I’ve been lucky to have around. A lot information they’ve passed to me will be passed down to readers.
Thank you again for your interest and I hope you learn something new and valuable in this series.