Skip to content

Commit 7f614b1

Browse files
committed
feat: query host page size
Define global variable with host page size and update it at the very beginning of the main function in Firecracker. This way data types which rely on specific host page size can adapt to it. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 846cdef commit 7f614b1

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

src/firecracker/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use seccomp::FilterError;
2020
use seccompiler::BpfThreadMap;
2121
use utils::arg_parser::{ArgParser, Argument};
2222
use utils::validators::validate_instance_id;
23+
use vmm::arch::host_page_size;
2324
use vmm::builder::StartMicrovmError;
2425
use vmm::logger::{
2526
debug, error, info, LoggerConfig, ProcessTimeReporter, StoreMetric, LOGGER, METRICS,
@@ -108,6 +109,10 @@ fn main_exec() -> Result<(), MainError> {
108109
// Initialize the logger.
109110
LOGGER.init().map_err(MainError::SetLogger)?;
110111

112+
// First call to this function updates the value to current
113+
// host page size.
114+
_ = host_page_size();
115+
111116
// We need this so that we can reset terminal to canonical mode if panic occurs.
112117
let stdin = io::stdin();
113118

src/vmm/src/arch/mod.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use std::fmt;
5+
use std::sync::LazyLock;
56

7+
use log::warn;
68
use serde::{Deserialize, Serialize};
79

810
/// Module for aarch64 related functionality.
@@ -55,8 +57,20 @@ pub struct InitrdConfig {
5557
/// Default page size for the guest OS.
5658
pub const GUEST_PAGE_SIZE: usize = 4096;
5759

58-
/// Default page size for the host OS.
59-
pub const HOST_PAGE_SIZE: usize = 4096;
60+
/// Get the size of the host page size.
61+
pub fn host_page_size() -> usize {
62+
/// Default page size for the host OS.
63+
static PAGE_SIZE: LazyLock<usize> = LazyLock::new(|| {
64+
// # Safety: Value always valid
65+
let r = unsafe { libc::sysconf(libc::_SC_PAGESIZE) };
66+
usize::try_from(r).unwrap_or_else(|_| {
67+
warn!("Could not get host page size with sysconf, assuming default 4K host pages");
68+
4096
69+
})
70+
});
71+
72+
*PAGE_SIZE
73+
}
6074

6175
impl fmt::Display for DeviceType {
6276
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

src/vmm/src/devices/virtio/iov_deque.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::os::fd::AsRawFd;
66
use libc::{c_int, c_void, iovec, off_t, size_t};
77
use memfd;
88

9-
use crate::arch::HOST_PAGE_SIZE;
9+
use crate::arch::host_page_size;
1010

1111
#[derive(Debug, thiserror::Error, displaydoc::Display)]
1212
pub enum IovDequeError {
@@ -93,7 +93,6 @@ unsafe impl<const L: u16> Send for IovDeque<L> {}
9393

9494
impl<const L: u16> IovDeque<L> {
9595
const BYTES: usize = L as usize * std::mem::size_of::<iovec>();
96-
const _ASSERT: () = assert!(Self::BYTES % HOST_PAGE_SIZE == 0);
9796

9897
/// Create a [`memfd`] object that represents a single physical page
9998
fn create_memfd() -> Result<memfd::Memfd, IovDequeError> {
@@ -153,6 +152,8 @@ impl<const L: u16> IovDeque<L> {
153152

154153
/// Create a new [`IovDeque`] that can hold memory described by a single VirtIO queue.
155154
pub fn new() -> Result<Self, IovDequeError> {
155+
assert!(Self::BYTES % host_page_size() == 0);
156+
156157
let memfd = Self::create_memfd()?;
157158
let raw_memfd = memfd.as_file().as_raw_fd();
158159
let buffer = Self::allocate_ring_buffer_memory()?;

0 commit comments

Comments
 (0)