hcl_mapper/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Provides a mapper implementation for the page pool that uses the hcl ioctl
5//! crate to map guest memory.
6
7#![cfg(target_os = "linux")]
8#![forbid(unsafe_code)]
9
10use anyhow::Context;
11use hcl::ioctl::MshvVtlLow;
12use inspect::Inspect;
13use page_pool_alloc::PoolSource;
14use std::os::fd::AsFd;
15
16/// A mapper that uses [`MshvVtlLow`] to map pages.
17#[derive(Inspect)]
18pub struct HclMapper {
19    #[inspect(skip)]
20    fd: MshvVtlLow,
21    gpa_bias: u64,
22    is_shared: bool,
23}
24
25impl HclMapper {
26    /// Creates an instance for mapping shared memory, with shared memory
27    /// appearing to the guest starting at `vtom`.
28    pub fn new_shared(vtom: u64) -> anyhow::Result<Self> {
29        Self::new_inner(vtom, true)
30    }
31
32    /// Creates an instance for mapping private memory.
33    pub fn new_private() -> anyhow::Result<Self> {
34        Self::new_inner(0, false)
35    }
36
37    fn new_inner(gpa_bias: u64, is_shared: bool) -> anyhow::Result<Self> {
38        let fd = MshvVtlLow::new().context("failed to open gpa fd")?;
39        Ok(Self {
40            fd,
41            gpa_bias,
42            is_shared,
43        })
44    }
45}
46
47impl PoolSource for HclMapper {
48    fn address_bias(&self) -> u64 {
49        self.gpa_bias
50    }
51
52    fn file_offset(&self, address: u64) -> u64 {
53        address.wrapping_add(if self.is_shared {
54            MshvVtlLow::SHARED_MEMORY_FLAG
55        } else {
56            0
57        })
58    }
59
60    fn mappable(&self) -> sparse_mmap::MappableRef<'_> {
61        self.fd.get().as_fd()
62    }
63}