Skip to content

[feature/virtio-mem] Add dummy implementation for virtio-mem #5365

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

Draft
wants to merge 13 commits into
base: feature/virtio-mem
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
6 changes: 5 additions & 1 deletion resources/guest_configs/ci.config
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ CONFIG_SERIO_I8042=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_GSCPS2=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_INPUT_KEYBOARD=y
CONFIG_INPUT_KEYBOARD=y

# virtio-mem support
CONFIG_STRICT_DEVMEM=y
CONFIG_VIRTIO_MEM=y
6 changes: 6 additions & 0 deletions src/firecracker/src/api_server/parsed_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use super::request::net::{parse_patch_net, parse_put_net};
use super::request::snapshot::{parse_patch_vm_state, parse_put_snapshot};
use super::request::version::parse_get_version;
use super::request::vsock::parse_put_vsock;
use crate::api_server::request::hotplug::parse_hotplug;

#[derive(Debug)]
pub(crate) enum RequestAction {
Expand Down Expand Up @@ -109,6 +110,7 @@ impl TryFrom<&Request> for ParsedRequest {
}
(Method::Patch, "vm", Some(body)) => parse_patch_vm_state(body),
(Method::Patch, _, None) => method_to_error(Method::Patch),
(method, "hotplug", body) => parse_hotplug(method, path_tokens.next(), body),
(method, unknown_uri, _) => Err(RequestError::InvalidPathMethod(
unknown_uri.to_string(),
method,
Expand Down Expand Up @@ -171,6 +173,7 @@ impl ParsedRequest {
Self::success_response_with_data(balloon_config)
}
VmmData::BalloonStats(stats) => Self::success_response_with_data(stats),
VmmData::VirtioMemStatus(data) => Self::success_response_with_data(data),
VmmData::InstanceInformation(info) => Self::success_response_with_data(info),
VmmData::VmmVersion(version) => Self::success_response_with_data(
&serde_json::json!({ "firecracker_version": version.as_str() }),
Expand Down Expand Up @@ -555,6 +558,9 @@ pub mod tests {
VmmData::BalloonStats(stats) => {
http_response(&serde_json::to_string(stats).unwrap(), 200)
}
VmmData::VirtioMemStatus(data) => {
http_response(&serde_json::to_string(data).unwrap(), 200)
}
VmmData::Empty => http_response("", 204),
VmmData::FullVmConfig(cfg) => {
http_response(&serde_json::to_string(cfg).unwrap(), 200)
Expand Down
76 changes: 76 additions & 0 deletions src/firecracker/src/api_server/request/hotplug/memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use micro_http::Body;
use vmm::rpc_interface::VmmAction;
use vmm::vmm_config::memory_hotplug::MemoryHotplugConfig;

use crate::api_server::parsed_request::{ParsedRequest, RequestError};

pub(crate) fn parse_put_memory_hotplug(body: &Body) -> Result<ParsedRequest, RequestError> {
Ok(ParsedRequest::new_sync(VmmAction::SetMemoryHotplugDevice(
serde_json::from_slice::<MemoryHotplugConfig>(body.raw())?,
)))
}

pub(crate) fn parse_get_memory_hotplug() -> Result<ParsedRequest, RequestError> {
Ok(ParsedRequest::new_sync(VmmAction::GetMemoryHotplugStatus))
}

#[cfg(test)]
mod tests {
use vmm::devices::virtio::mem::{VIRTIO_MEM_DEFAULT_BLOCK_SIZE, VIRTIO_MEM_DEFAULT_SLOT_SIZE};
use vmm::utils::bytes_to_mib;

use super::*;
use crate::api_server::parsed_request::tests::vmm_action_from_request;

#[test]
fn test_parse_put_memory_hotplug_request() {
parse_put_memory_hotplug(&Body::new("invalid_payload")).unwrap_err();

// PUT with invalid fields.
let body = r#"{
"total_size_mib": "bar"
}"#;
parse_put_memory_hotplug(&Body::new(body)).unwrap_err();

// PUT with valid input fields with defaults.
let body = r#"{
"total_size_mib": 2048
}"#;
let expected_config = MemoryHotplugConfig {
total_size_mib: 2048,
block_size_mib: bytes_to_mib(VIRTIO_MEM_DEFAULT_BLOCK_SIZE),
slot_size_mib: bytes_to_mib(VIRTIO_MEM_DEFAULT_SLOT_SIZE),
};
assert_eq!(
vmm_action_from_request(parse_put_memory_hotplug(&Body::new(body)).unwrap()),
VmmAction::SetMemoryHotplugDevice(expected_config)
);

// PUT with valid input fields.
let body = r#"{
"total_size_mib": 2048,
"block_size_mib": 64,
"slot_size_mib": 64
}"#;
let expected_config = MemoryHotplugConfig {
total_size_mib: 2048,
block_size_mib: 64,
slot_size_mib: 64,
};
assert_eq!(
vmm_action_from_request(parse_put_memory_hotplug(&Body::new(body)).unwrap()),
VmmAction::SetMemoryHotplugDevice(expected_config)
);
}

#[test]
fn test_parse_parse_get_memory_hotplug_request() {
assert_eq!(
vmm_action_from_request(parse_get_memory_hotplug().unwrap()),
VmmAction::GetMemoryHotplugStatus
);
}
}
28 changes: 28 additions & 0 deletions src/firecracker/src/api_server/request/hotplug/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

mod memory;

use micro_http::{Body, Method};

use crate::api_server::parsed_request::{ParsedRequest, RequestError};
use crate::api_server::request::hotplug::memory::{
parse_get_memory_hotplug, parse_put_memory_hotplug,
};

pub(crate) fn parse_hotplug(
method: Method,
token: Option<&str>,
body: Option<&Body>,
) -> Result<ParsedRequest, RequestError> {
let token =
token.ok_or_else(|| RequestError::InvalidPathMethod("hotplug".to_string(), method))?;
match (method, token, body) {
(Method::Get, "memory", None) => parse_get_memory_hotplug(),
(Method::Put, "memory", Some(body)) => parse_put_memory_hotplug(body),
(method, unknown_uri, _) => Err(RequestError::InvalidPathMethod(
unknown_uri.to_string(),
method,
)),
}
}
1 change: 1 addition & 0 deletions src/firecracker/src/api_server/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod boot_source;
pub mod cpu_configuration;
pub mod drive;
pub mod entropy;
pub mod hotplug;
pub mod instance_info;
pub mod logger;
pub mod machine_configuration;
Expand Down
20 changes: 19 additions & 1 deletion src/firecracker/src/generated/prctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
clippy::undocumented_unsafe_blocks,
missing_debug_implementations,
clippy::tests_outside_test_module,
unsafe_op_in_unsafe_fn
unsafe_op_in_unsafe_fn,
clippy::redundant_static_lifetimes
)]

pub const PR_SET_PDEATHSIG: u32 = 1;
Expand Down Expand Up @@ -179,3 +180,20 @@ pub const PR_RISCV_V_VSTATE_CTRL_INHERIT: u32 = 16;
pub const PR_RISCV_V_VSTATE_CTRL_CUR_MASK: u32 = 3;
pub const PR_RISCV_V_VSTATE_CTRL_NEXT_MASK: u32 = 12;
pub const PR_RISCV_V_VSTATE_CTRL_MASK: u32 = 31;
pub const PR_RISCV_SET_ICACHE_FLUSH_CTX: u32 = 71;
pub const PR_RISCV_CTX_SW_FENCEI_ON: u32 = 0;
pub const PR_RISCV_CTX_SW_FENCEI_OFF: u32 = 1;
pub const PR_RISCV_SCOPE_PER_PROCESS: u32 = 0;
pub const PR_RISCV_SCOPE_PER_THREAD: u32 = 1;
pub const PR_PPC_GET_DEXCR: u32 = 72;
pub const PR_PPC_SET_DEXCR: u32 = 73;
pub const PR_PPC_DEXCR_SBHE: u32 = 0;
pub const PR_PPC_DEXCR_IBRTPD: u32 = 1;
pub const PR_PPC_DEXCR_SRAPD: u32 = 2;
pub const PR_PPC_DEXCR_NPHIE: u32 = 3;
pub const PR_PPC_DEXCR_CTRL_EDITABLE: u32 = 1;
pub const PR_PPC_DEXCR_CTRL_SET: u32 = 2;
pub const PR_PPC_DEXCR_CTRL_CLEAR: u32 = 4;
pub const PR_PPC_DEXCR_CTRL_SET_ONEXEC: u32 = 8;
pub const PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC: u32 = 16;
pub const PR_PPC_DEXCR_CTRL_MASK: u32 = 31;
16 changes: 8 additions & 8 deletions src/vmm/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ pub use aarch64::vm::{ArchVm, ArchVmError, VmState};
pub use aarch64::{
ConfigurationError, arch_memory_regions, configure_system_for_boot, get_kernel_start,
initrd_load_addr, layout::BOOT_DEVICE_MEM_START, layout::CMDLINE_MAX_SIZE,
layout::GSI_LEGACY_END, layout::GSI_LEGACY_NUM, layout::GSI_LEGACY_START, layout::GSI_MSI_END,
layout::GSI_MSI_NUM, layout::GSI_MSI_START, layout::MEM_32BIT_DEVICES_SIZE,
layout::MEM_32BIT_DEVICES_START, layout::MEM_64BIT_DEVICES_SIZE,
layout::MEM_64BIT_DEVICES_START, layout::MMIO32_MEM_SIZE, layout::MMIO32_MEM_START,
layout::PCI_MMCONFIG_SIZE, layout::PCI_MMCONFIG_START,
layout::FIRST_ADDR_PAST_64BITS_MMIO, layout::GSI_LEGACY_END, layout::GSI_LEGACY_NUM,
layout::GSI_LEGACY_START, layout::GSI_MSI_END, layout::GSI_MSI_NUM, layout::GSI_MSI_START,
layout::MEM_32BIT_DEVICES_SIZE, layout::MEM_32BIT_DEVICES_START,
layout::MEM_64BIT_DEVICES_SIZE, layout::MEM_64BIT_DEVICES_START, layout::MMIO32_MEM_SIZE,
layout::MMIO32_MEM_START, layout::PCI_MMCONFIG_SIZE, layout::PCI_MMCONFIG_START,
layout::PCI_MMIO_CONFIG_SIZE_PER_SEGMENT, layout::RTC_MEM_START, layout::SERIAL_MEM_START,
layout::SPI_START, layout::SYSTEM_MEM_SIZE, layout::SYSTEM_MEM_START, load_kernel,
};
Expand All @@ -46,9 +46,9 @@ pub use x86_64::vm::{ArchVm, ArchVmError, VmState};
pub use crate::arch::x86_64::{
ConfigurationError, arch_memory_regions, configure_system_for_boot, get_kernel_start,
initrd_load_addr, layout::APIC_ADDR, layout::BOOT_DEVICE_MEM_START, layout::CMDLINE_MAX_SIZE,
layout::GSI_LEGACY_END, layout::GSI_LEGACY_NUM, layout::GSI_LEGACY_START, layout::GSI_MSI_END,
layout::GSI_MSI_NUM, layout::GSI_MSI_START, layout::IOAPIC_ADDR,
layout::MEM_32BIT_DEVICES_SIZE, layout::MEM_32BIT_DEVICES_START,
layout::FIRST_ADDR_PAST_64BITS_MMIO, layout::GSI_LEGACY_END, layout::GSI_LEGACY_NUM,
layout::GSI_LEGACY_START, layout::GSI_MSI_END, layout::GSI_MSI_NUM, layout::GSI_MSI_START,
layout::IOAPIC_ADDR, layout::MEM_32BIT_DEVICES_SIZE, layout::MEM_32BIT_DEVICES_START,
layout::MEM_64BIT_DEVICES_SIZE, layout::MEM_64BIT_DEVICES_START, layout::MMIO32_MEM_SIZE,
layout::MMIO32_MEM_START, layout::PCI_MMCONFIG_SIZE, layout::PCI_MMCONFIG_START,
layout::PCI_MMIO_CONFIG_SIZE_PER_SEGMENT, layout::SYSTEM_MEM_SIZE, layout::SYSTEM_MEM_START,
Expand Down
3 changes: 2 additions & 1 deletion src/vmm/src/arch/x86_64/generated/arch_prctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
clippy::undocumented_unsafe_blocks,
missing_debug_implementations,
clippy::tests_outside_test_module,
unsafe_op_in_unsafe_fn
unsafe_op_in_unsafe_fn,
clippy::redundant_static_lifetimes
)]

pub const ARCH_SET_GS: u32 = 4097;
Expand Down
3 changes: 2 additions & 1 deletion src/vmm/src/arch/x86_64/generated/hyperv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
clippy::undocumented_unsafe_blocks,
missing_debug_implementations,
clippy::tests_outside_test_module,
unsafe_op_in_unsafe_fn
unsafe_op_in_unsafe_fn,
clippy::redundant_static_lifetimes
)]

pub const HV_X64_MSR_SYNDBG_CONTROL: u32 = 0x400000f1;
Expand Down
9 changes: 8 additions & 1 deletion src/vmm/src/arch/x86_64/generated/hyperv_tlfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
clippy::undocumented_unsafe_blocks,
missing_debug_implementations,
clippy::tests_outside_test_module,
unsafe_op_in_unsafe_fn
unsafe_op_in_unsafe_fn,
clippy::redundant_static_lifetimes
)]

pub const HV_X64_MSR_GUEST_OS_ID: u32 = 0x40000000;
Expand Down Expand Up @@ -49,6 +50,12 @@ pub const HV_X64_MSR_SINT12: u32 = 0x4000009c;
pub const HV_X64_MSR_SINT13: u32 = 0x4000009d;
pub const HV_X64_MSR_SINT14: u32 = 0x4000009e;
pub const HV_X64_MSR_SINT15: u32 = 0x4000009f;
pub const HV_X64_MSR_NESTED_SCONTROL: u32 = 0x40001080;
pub const HV_X64_MSR_NESTED_SVERSION: u32 = 0x40001081;
pub const HV_X64_MSR_NESTED_SIEFP: u32 = 0x40001082;
pub const HV_X64_MSR_NESTED_SIMP: u32 = 0x40001083;
pub const HV_X64_MSR_NESTED_EOM: u32 = 0x40001084;
pub const HV_X64_MSR_NESTED_SINT0: u32 = 0x40001090;
pub const HV_X64_MSR_STIMER0_CONFIG: u32 = 0x400000b0;
pub const HV_X64_MSR_STIMER0_COUNT: u32 = 0x400000b1;
pub const HV_X64_MSR_STIMER1_CONFIG: u32 = 0x400000b2;
Expand Down
25 changes: 15 additions & 10 deletions src/vmm/src/arch/x86_64/generated/mpspec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
clippy::undocumented_unsafe_blocks,
missing_debug_implementations,
clippy::tests_outside_test_module,
unsafe_op_in_unsafe_fn
unsafe_op_in_unsafe_fn,
clippy::redundant_static_lifetimes
)]

pub const MPC_SIGNATURE: &[u8; 5] = b"PCMP\0";
Expand Down Expand Up @@ -205,11 +206,13 @@ const _: () = {
["Offset of field: mpc_intsrc::dstapic"][::std::mem::offset_of!(mpc_intsrc, dstapic) - 6usize];
["Offset of field: mpc_intsrc::dstirq"][::std::mem::offset_of!(mpc_intsrc, dstirq) - 7usize];
};
pub const mp_irq_source_types_mp_INT: mp_irq_source_types = 0;
pub const mp_irq_source_types_mp_NMI: mp_irq_source_types = 1;
pub const mp_irq_source_types_mp_SMI: mp_irq_source_types = 2;
pub const mp_irq_source_types_mp_ExtINT: mp_irq_source_types = 3;
pub type mp_irq_source_types = ::std::os::raw::c_uint;
pub mod mp_irq_source_types {
pub type Type = ::std::os::raw::c_uint;
pub const mp_INT: Type = 0;
pub const mp_NMI: Type = 1;
pub const mp_SMI: Type = 2;
pub const mp_ExtINT: Type = 3;
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct mpc_lintsrc {
Expand Down Expand Up @@ -261,7 +264,9 @@ const _: () = {
[::std::mem::offset_of!(mpc_oemtable, checksum) - 7usize];
["Offset of field: mpc_oemtable::mpc"][::std::mem::offset_of!(mpc_oemtable, mpc) - 8usize];
};
pub const mp_bustype_MP_BUS_ISA: mp_bustype = 1;
pub const mp_bustype_MP_BUS_EISA: mp_bustype = 2;
pub const mp_bustype_MP_BUS_PCI: mp_bustype = 3;
pub type mp_bustype = ::std::os::raw::c_uint;
pub mod mp_bustype {
pub type Type = ::std::os::raw::c_uint;
pub const MP_BUS_ISA: Type = 1;
pub const MP_BUS_EISA: Type = 2;
pub const MP_BUS_PCI: Type = 3;
}
Loading