Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Description of vmm/src/lib.rs (VMM Struct and Implementation) #24

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions VMM_Implementaion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# [VMM Impl](../src/vmm/src/lib.rs)
codenet marked this conversation as resolved.
Show resolved Hide resolved
codenet marked this conversation as resolved.
Show resolved Hide resolved

codenet marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention the path to the code file here

The `Vmm` is the main structure that holds all the VMM resources. It is responsible for the high level management of the VMM. It is also responsible for the communication with the API and the VMM action handlers.

codenet marked this conversation as resolved.
Show resolved Hide resolved
```rs
pub struct Vmm {
codenet marked this conversation as resolved.
Show resolved Hide resolved
vm: KvmVm<WrappedExitHandler>,
kernel_cfg: KernelConfig,
guest_memory: GuestMemoryMmap,
device_mgr: Arc<Mutex<IoManager>>,
event_mgr: EventManager<Arc<Mutex<dyn MutEventSubscriber + Send>>>,
exit_handler: WrappedExitHandler,
#[cfg(target_arch = "aarch64")]
num_vcpus: u64,
}

```
- `vm` - The KVM VM object. It is created when the VMM starts. It is wrapped in a `KvmVm` object that provides a safe interface to the KVM API. The `KvmVm` object also holds a reference to the `exit_handler` object. The `exit_handler` is responsible for handling the VM exits. The `KvmVm` object is responsible for running the VM.
- `kernel_cfg` - The kernel configuration. It holds the kernel image, the kernel command line and the kernel start address.
- `guest_memory` - The guest memory object. It is created when the VMM starts. It is wrapped in a `GuestMemoryMmap` object that provides a safe interface to the guest memory.
- `device_mgr` - The device manager object. It is created when the VMM starts. It is responsible for managing the devices attached to the VMM.
- `event_mgr` - The event manager object. It is created when the VMM starts. It is responsible for managing the events that are generated by the devices attached to the VMM.
- `exit_handler` - The exit handler object. It is created when the VMM starts. It is responsible for handling the VM exits.
Comment on lines +20 to +23
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lot of redundancy in these statements. You can just say
exit_handler: responsible for handling VM exits.

- `device_mgr` , `event_mgr` and `exit_handler` are wrapped in an `Arc` and a `Mutex` to allow for multiple threads to access them.
- `num_vcpus` - The number of vCPUs. It is used only on AArch64.

```rs
impl Vmm {
}
```
__ Overview of the `Vmm` functions __

The `Vmm` structure exposes the following public functions:
```rs
pub fn run(&mut self) -> Result<()> {
}
```
This function will start the event manager loop and will block until the VMM is stopped. The VMM is stopped when the VM exits or when an error occurs. In the latter case, the error is logged and the VMM is stopped.

```rs
let kernel_load_addr = self.compute_kernel_load_addr(&load_result)?;
```
- Loads the kernel in the guest memory. This function returns a `Result` that contains the `GuestAddress` where the kernel was loaded. This address is used to configure the boot source. If the kernel was loaded successfully, the `Vmm` state is updated to `KernelConfigured`. If the kernel was not loaded successfully, the `Vmm` state is updated to `KernelLoadFailed`.

```rs
self.vm.run(Some(kernel_load_addr)).map_err(Error::Vm)?;
```
- Starts the VM. This function returns a `Result` that contains the `ExitReason` of the VM. This `ExitReason` is used to update the `Vmm` state. If the VM exits successfully, the `Vmm` state is updated to `VmRunning`. If the VM exits with an error, the `Vmm` state is updated to `VmError`.

```rs
fn create_guest_memory(memory_config: &MemoryConfig) -> Result<GuestMemoryMmap> {
let mem_size = ((memory_config.size_mib as u64) << 20) as usize;
let mem_regions = Vmm::create_memory_regions(mem_size);

// Create guest memory from regions.


GuestMemoryMmap::from_ranges(&mem_regions)
.map_err(|e| Error::Memory(MemoryError::VmMemory(e)))
}
```
- Creates the guest memory. This function returns a `Result` that contains the `GuestMemoryMmap` object. Represents the entire physical memory of the guest by tracking all its memory regions. Each region is an instance of GuestRegionMmap, being backed by a mapping in the virtual address space of the calling process. The guest memory is created from a list of memory regions. The memory regions are created from the `MemoryConfig` object. The `MemoryConfig` object contains the size of the guest memory in MiB. The `MemoryConfig` object is created when the VMM starts.
- `mem_size` is the size of the guest memory in bytes.
- `mem_regions` is a vector of memory regions. Each memory region is defined by a base address and a size.


```rs
fn load_kernel(&mut self) {
let mut kernel_image
let zero_page_addr
...
let kernel_load = match Elf::load{
};
...
let mut bootparams
...
let mut cmdline
...
load_cmdline(
)
...


// Write the boot parameters in the zeropage.
//
LinuxBootConfigurator::write_bootparams::<GuestMemoryMmap>(
&BootParams::new::<boot_params>(&bootparams, zero_page_addr),
&self.guest_memory,
)
.map_err(Error::BootConfigure)?;

Ok(kernel_load)
}

```
- Loads the kernel in the guest memory. This function returns a `Result` that contains the `KernelLoaderResult` object. The `KernelLoaderResult` object contains the entry point of the kernel and the kernel image size. The `KernelLoaderResult` object is used to configure the boot source.
- `kernel_image` is the kernel image file. It is opened in read-only mode. If the kernel image file is not opened successfully, the `Vmm` state is updated to `KernelLoadFailed`.
- `zero_page_addr` is the address of the zero page. The zero page is a 4 KiB page that is mapped at the start of the guest physical address space. It is used to pass information to the kernel at boot time. The zero page is defined by the `ZEROPG_START` constant.
- `kernel_load` is the result of loading the kernel in the guest memory. The kernel is loaded using the `Elf` or `BzImage` loader.
- `cmdline` is the kernel command line. It is created from the `cmdline` field of the `KernelConfig` object. The `KernelConfig` object is created when the VMM starts.
- `load_cmdline` is the result of loading the kernel command line in the guest memory. The kernel command line is loaded at the end of the zero page. The kernel command line is defined by the `CMDLINE_OFFSET` constant.
- `LinuxBootConfigurator::write_bootparams` is the result of writing the boot parameters in the zero page. The boot parameters are written at the beginning of the zero page. The boot parameters are defined by the `BOOTPARAMS_OFFSET` constant.