diff --git a/CHANGELOG.md b/CHANGELOG.md index fe30d08b09c..6ef7fbfdcf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,10 @@ and this project adheres to use memfd to back guest memory if a vhost-user-blk device is configured, otherwise use anonymous private memory. This is because serving page faults of shared memory used by memfd is slower and may impact workloads. +- [#4492](https://github.com/firecracker-microvm/firecracker/pull/4492): Changed + `--config` parameter of `cpu-template-helper` optional. Users no longer need + to prepare kernel, rootfs and Firecracker configuration files to use + `cpu-template-helper`. ### Fixed diff --git a/Cargo.lock b/Cargo.lock index aff7628f794..7786e97b409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,8 +397,8 @@ dependencies = [ "serde", "serde_json", "thiserror", - "utils", "vmm", + "vmm-sys-util", ] [[package]] diff --git a/docs/cpu_templates/cpu-template-helper.md b/docs/cpu_templates/cpu-template-helper.md index e89b5020d76..dc7531f8544 100644 --- a/docs/cpu_templates/cpu-template-helper.md +++ b/docs/cpu_templates/cpu-template-helper.md @@ -16,7 +16,9 @@ This command dumps guest CPU configuration in the custom CPU template JSON format. ``` -cpu-template-helper template dump --config --output +cpu-template-helper template dump \ + --output \ + [--config ] ``` Users can utilize this as an entry point of a custom CPU template creation to @@ -68,7 +70,8 @@ This command verifies that the given custom CPU template is applied correctly. ``` cpu-template-helper template verify \ - --config + --template + [--config ] ``` Firecracker modifies the guest CPU configuration after the CPU template is @@ -77,8 +80,9 @@ not set the given configuration. Since Firecracker does not check them at runtime, it is required to ensure that these situations don't happen with their custom CPU templates before deploying it. -The command uses the same configuration file as Firecracker and the path to the -custom CPU template file should be specified in the "cpu-config" field. +When a template is specified both through `--template` and in Firecracker +configuration file provided via `--config`, the template specified with +`--template` takes precedence. > **Note** This command does not ensure that the contents of the template are > sensible. Thus, users need to make sure that the template does not have any @@ -93,8 +97,8 @@ information that could affect the validity of custom CPU templates. ``` cpu-template-helper fingerprint dump \ - --config \ - --output + --output \ + [--config ] ``` Keeping the underlying hardware and software stack updated is essential for diff --git a/src/cpu-template-helper/Cargo.toml b/src/cpu-template-helper/Cargo.toml index ecbd4dca3c7..3b6a3515990 100644 --- a/src/cpu-template-helper/Cargo.toml +++ b/src/cpu-template-helper/Cargo.toml @@ -18,12 +18,10 @@ log-instrument = { path = "../log-instrument", optional = true } serde = { version = "1.0.196", features = ["derive"] } serde_json = "1.0.113" thiserror = "1.0.57" +vmm-sys-util = "0.12.1" vmm = { path = "../vmm" } -[dev-dependencies] -utils = { path = "../utils" } - [features] tracing = ["log-instrument", "vmm/tracing"] diff --git a/src/cpu-template-helper/src/main.rs b/src/cpu-template-helper/src/main.rs index 9f4f73e73cd..4730c08ac20 100644 --- a/src/cpu-template-helper/src/main.rs +++ b/src/cpu-template-helper/src/main.rs @@ -5,7 +5,7 @@ use std::fs::{read_to_string, write}; use std::path::PathBuf; use clap::{Parser, Subcommand, ValueEnum}; -use vmm::cpu_config::templates::{CustomCpuTemplate, GetCpuTemplate, GetCpuTemplateError}; +use vmm::cpu_config::templates::{GetCpuTemplate, GetCpuTemplateError}; use crate::utils::UtilsError; @@ -58,7 +58,7 @@ enum TemplateOperation { Dump { /// Path of firecracker config file. #[arg(short, long, value_name = "PATH")] - config: PathBuf, + config: Option, /// Path of output file. #[arg(short, long, value_name = "PATH", default_value = "cpu_config.json")] output: PathBuf, @@ -74,9 +74,12 @@ enum TemplateOperation { }, /// Verify that the given CPU template file is applied as intended. Verify { - /// Path of firecracker config file specifying the target CPU template. + /// Path of firecracker config file. + #[arg(short, long, value_name = "PATH")] + config: Option, + /// Path of the target CPU template. #[arg(short, long, value_name = "PATH")] - config: PathBuf, + template: Option, }, } @@ -84,9 +87,9 @@ enum TemplateOperation { enum FingerprintOperation { /// Dump fingerprint consisting of host-related information and guest CPU config. Dump { - /// Path of fingerprint config file. + /// Path of firecracker config file. #[arg(short, long, value_name = "PATH")] - config: PathBuf, + config: Option, /// Path of output file. #[arg(short, long, value_name = "PATH", default_value = "fingerprint.json")] output: PathBuf, @@ -115,8 +118,8 @@ fn run(cli: Cli) -> Result<(), HelperError> { match cli.command { Command::Template(op) => match op { TemplateOperation::Dump { config, output } => { - let config = read_to_string(config)?; - let (vmm, _) = utils::build_microvm_from_config(&config)?; + let config = config.map(read_to_string).transpose()?; + let (vmm, _) = utils::build_microvm_from_config(config, None)?; let cpu_config = template::dump::dump(vmm)?; @@ -127,7 +130,7 @@ fn run(cli: Cli) -> Result<(), HelperError> { let mut templates = Vec::with_capacity(paths.len()); for path in &paths { let template_json = read_to_string(path)?; - let template: CustomCpuTemplate = serde_json::from_str(&template_json)?; + let template = serde_json::from_str(&template_json)?; templates.push(template); } @@ -139,9 +142,16 @@ fn run(cli: Cli) -> Result<(), HelperError> { write(path, template_json)?; } } - TemplateOperation::Verify { config } => { - let config = read_to_string(config)?; - let (vmm, vm_resources) = utils::build_microvm_from_config(&config)?; + TemplateOperation::Verify { config, template } => { + let config = config.map(read_to_string).transpose()?; + let template = match template { + Some(path) => { + let template_json = read_to_string(path)?; + Some(serde_json::from_str(&template_json)?) + } + None => None, + }; + let (vmm, vm_resources) = utils::build_microvm_from_config(config, template)?; let cpu_template = vm_resources .vm_config @@ -155,8 +165,8 @@ fn run(cli: Cli) -> Result<(), HelperError> { }, Command::Fingerprint(op) => match op { FingerprintOperation::Dump { config, output } => { - let config = read_to_string(config)?; - let (vmm, _) = utils::build_microvm_from_config(&config)?; + let config = config.map(read_to_string).transpose()?; + let (vmm, _) = utils::build_microvm_from_config(config, None)?; let fingerprint = fingerprint::dump::dump(vmm)?; @@ -169,9 +179,9 @@ fn run(cli: Cli) -> Result<(), HelperError> { filters, } => { let prev_json = read_to_string(prev)?; - let prev: fingerprint::Fingerprint = serde_json::from_str(&prev_json)?; + let prev = serde_json::from_str(&prev_json)?; let curr_json = read_to_string(curr)?; - let curr: fingerprint::Fingerprint = serde_json::from_str(&curr_json)?; + let curr = serde_json::from_str(&curr_json)?; fingerprint::compare::compare(prev, curr, filters)?; } }, @@ -195,70 +205,10 @@ fn main() -> Result<(), HelperError> { mod tests { use std::io::Write; - use ::utils::tempfile::TempFile; - use vmm::utilities::mock_resources::kernel_image_path; + use vmm_sys_util::tempfile::TempFile; use super::*; - pub fn generate_config(kernel_image_path: &str, rootfs_path: &str) -> String { - format!( - r#"{{ - "boot-source": {{ - "kernel_image_path": "{}" - }}, - "drives": [ - {{ - "drive_id": "rootfs", - "path_on_host": "{}", - "is_root_device": true, - "is_read_only": false - }} - ] - }}"#, - kernel_image_path, rootfs_path, - ) - } - - pub fn generate_config_with_template( - kernel_image_path: &str, - rootfs_path: &str, - cpu_template_path: &str, - ) -> String { - format!( - r#"{{ - "boot-source": {{ - "kernel_image_path": "{}" - }}, - "drives": [ - {{ - "drive_id": "rootfs", - "path_on_host": "{}", - "is_root_device": true, - "is_read_only": false - }} - ], - "cpu-config": "{}" - }}"#, - kernel_image_path, rootfs_path, cpu_template_path, - ) - } - - fn generate_config_file( - kernel_image_path: &str, - rootfs_path: &str, - cpu_template_path: Option<&str>, - ) -> TempFile { - let config = match cpu_template_path { - Some(cpu_template_path) => { - generate_config_with_template(kernel_image_path, rootfs_path, cpu_template_path) - } - None => generate_config(kernel_image_path, rootfs_path), - }; - let config_file = TempFile::new().unwrap(); - config_file.as_file().write_all(config.as_bytes()).unwrap(); - config_file - } - // Sample modifiers for x86_64 that should work correctly as a CPU template and a guest CPU // config. // * CPUID leaf 0x0 / subleaf 0x0 / register eax indicates the maximum input EAX value for basic @@ -334,21 +284,11 @@ mod tests { #[test] fn test_template_dump_command() { - let kernel_image_path = kernel_image_path(None); - let rootfs_file = TempFile::new().unwrap(); - let config_file = generate_config_file( - &kernel_image_path, - rootfs_file.as_path().to_str().unwrap(), - None, - ); let output_file = TempFile::new().unwrap(); - let args = vec![ "cpu-template-helper", "template", "dump", - "--config", - config_file.as_path().to_str().unwrap(), "--output", output_file.as_path().to_str().unwrap(), ]; @@ -374,21 +314,13 @@ mod tests { #[test] fn test_template_verify_command() { - let kernel_image_path = kernel_image_path(None); - let rootfs_file = TempFile::new().unwrap(); let template_file = generate_sample_template(); - let config_file = generate_config_file( - &kernel_image_path, - rootfs_file.as_path().to_str().unwrap(), - Some(template_file.as_path().to_str().unwrap()), - ); - let args = vec![ "cpu-template-helper", "template", "verify", - "--config", - config_file.as_path().to_str().unwrap(), + "--template", + template_file.as_path().to_str().unwrap(), ]; let cli = Cli::parse_from(args); @@ -397,21 +329,11 @@ mod tests { #[test] fn test_fingerprint_dump_command() { - let kernel_image_path = kernel_image_path(None); - let rootfs_file = TempFile::new().unwrap(); - let config_file = generate_config_file( - &kernel_image_path, - rootfs_file.as_path().to_str().unwrap(), - None, - ); let output_file = TempFile::new().unwrap(); - let args = vec![ "cpu-template-helper", "fingerprint", "dump", - "--config", - config_file.as_path().to_str().unwrap(), "--output", output_file.as_path().to_str().unwrap(), ]; diff --git a/src/cpu-template-helper/src/template/dump/mod.rs b/src/cpu-template-helper/src/template/dump/mod.rs index 6f0272a9173..d48a5243f7b 100644 --- a/src/cpu-template-helper/src/template/dump/mod.rs +++ b/src/cpu-template-helper/src/template/dump/mod.rs @@ -32,21 +32,12 @@ pub fn dump(vmm: Arc>) -> Result { #[cfg(test)] mod tests { - use utils::tempfile::TempFile; - use vmm::utilities::mock_resources::kernel_image_path; - use super::*; - use crate::tests::generate_config; use crate::utils::build_microvm_from_config; #[test] fn test_dump() { - let kernel_image_path = kernel_image_path(None); - let tmp_file = TempFile::new().unwrap(); - let valid_config = - generate_config(&kernel_image_path, tmp_file.as_path().to_str().unwrap()); - let (vmm, _) = build_microvm_from_config(&valid_config).unwrap(); - + let (vmm, _) = build_microvm_from_config(None, None).unwrap(); dump(vmm).unwrap(); } } diff --git a/src/cpu-template-helper/src/utils/mock_kernel/Makefile b/src/cpu-template-helper/src/utils/mock_kernel/Makefile new file mode 100644 index 00000000000..db64aee9cb3 --- /dev/null +++ b/src/cpu-template-helper/src/utils/mock_kernel/Makefile @@ -0,0 +1,17 @@ +# This is used to create a mock kernel to be embedded in CPU template helper tool. +# It requires a valid ELF file for x86_64 and a file containing a valid kernel header for aarch64. + +ARCH := $(shell uname -m) + +.PHONY: clean + +$(ARCH).bin: $(ARCH).c +ifeq ($(ARCH),x86_64) + gcc -nostdlib -fno-asynchronous-unwind-tables -s -o $(ARCH).bin $(ARCH).c +else + gcc $(ARCH).c + ./a.out +endif + +clean: + rm -rf a.out $(ARCH).bin diff --git a/src/cpu-template-helper/src/utils/mock_kernel/aarch64.bin b/src/cpu-template-helper/src/utils/mock_kernel/aarch64.bin new file mode 100644 index 00000000000..a92f60894df Binary files /dev/null and b/src/cpu-template-helper/src/utils/mock_kernel/aarch64.bin differ diff --git a/src/cpu-template-helper/src/utils/mock_kernel/aarch64.c b/src/cpu-template-helper/src/utils/mock_kernel/aarch64.c new file mode 100644 index 00000000000..d065202d407 --- /dev/null +++ b/src/cpu-template-helper/src/utils/mock_kernel/aarch64.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +// Kernel header for AArch64. +// It comes from the kernel doc Documentation/arm64/booting.txt. +typedef struct { + uint32_t code0; // Executable code + uint32_t code1; // Executable code + uint64_t text_offset; // Image load offset, little endian + uint64_t image_size; // Effective Image size, little endian + uint64_t flags; // kernel flags, little endian + uint64_t res2; // reserved + uint64_t res3; // reserved + uint64_t res4; // reserved + uint32_t magic; // Magic number, little endian, "ARM\x64" + uint32_t res5; // reserved (used for PE COFF offset) +} __attribute__((packed)) kernel_header; + +int main(int argc, char **argv) { + kernel_header header = { + .code0 = 0, + .code1 = 0, + .text_offset = sizeof(kernel_header), + .image_size = 0, + .flags = 0, + .magic = 0x644d5241, // "ARM\x64" + .res5 = sizeof(kernel_header), + }; + + FILE *output_fp = fopen("aarch64.bin", "wb"); + if (!output_fp) { + perror("Failed to create output image"); + return 1; + } + fwrite(&header, sizeof(header), 1, output_fp); + fclose(output_fp); + + return 0; +} diff --git a/src/cpu-template-helper/src/utils/mock_kernel/x86_64.bin b/src/cpu-template-helper/src/utils/mock_kernel/x86_64.bin new file mode 100755 index 00000000000..ac6e044ffb9 Binary files /dev/null and b/src/cpu-template-helper/src/utils/mock_kernel/x86_64.bin differ diff --git a/src/cpu-template-helper/src/utils/mock_kernel/x86_64.c b/src/cpu-template-helper/src/utils/mock_kernel/x86_64.c new file mode 100644 index 00000000000..924302376ea --- /dev/null +++ b/src/cpu-template-helper/src/utils/mock_kernel/x86_64.c @@ -0,0 +1,3 @@ +void _start() { + while (1) ; +} diff --git a/src/cpu-template-helper/src/utils/mod.rs b/src/cpu-template-helper/src/utils/mod.rs index 74eb5288871..d908fb9d0e5 100644 --- a/src/cpu-template-helper/src/utils/mod.rs +++ b/src/cpu-template-helper/src/utils/mod.rs @@ -4,15 +4,17 @@ use std::ffi::OsString; use std::fmt::Display; use std::hash::Hash; +use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use vmm::builder::{build_microvm_for_boot, StartMicrovmError}; -use vmm::cpu_config::templates::Numeric; +use vmm::cpu_config::templates::{CustomCpuTemplate, Numeric}; use vmm::resources::VmResources; use vmm::seccomp_filters::get_empty_filters; use vmm::vmm_config::instance_info::{InstanceInfo, VmState}; use vmm::{EventManager, Vmm, HTTP_MAX_PAYLOAD_SIZE}; +use vmm_sys_util::tempfile::TempFile; #[cfg(target_arch = "aarch64")] pub mod aarch64; @@ -64,20 +66,66 @@ pub enum UtilsError { CreateVmResources(vmm::resources::ResourcesError), /// Failed to build microVM: {0} BuildMicroVm(#[from] StartMicrovmError), + /// Failed to create temporary file: {0} + CreateTempFile(#[from] vmm_sys_util::errno::Error), + /// Failed to operate file: {0} + FileIo(#[from] std::io::Error), +} + +// Utility function to prepare scratch kernel image and rootfs and build mock Firecracker config. +fn build_mock_config() -> Result<(TempFile, TempFile, String), UtilsError> { + let kernel = TempFile::new()?; + kernel.as_file().write_all( + #[cfg(target_arch = "aarch64")] + include_bytes!("mock_kernel/aarch64.bin"), + #[cfg(target_arch = "x86_64")] + include_bytes!("mock_kernel/x86_64.bin"), + )?; + let rootfs = TempFile::new()?; + let config = format!( + r#"{{ + "boot-source": {{ + "kernel_image_path": "{}" + }}, + "drives": [ + {{ + "drive_id": "rootfs", + "is_root_device": true, + "path_on_host": "{}" + }} + ] + }}"#, + // Temporary file path consists of alphanumerics. + kernel.as_path().to_str().unwrap(), + rootfs.as_path().to_str().unwrap(), + ); + Ok((kernel, rootfs, config)) } pub fn build_microvm_from_config( - config: &str, + config: Option, + template: Option, ) -> Result<(Arc>, VmResources), UtilsError> { // Prepare resources from the given config file. + let (_kernel, _rootfs, config) = match config { + Some(config) => (None, None, config), + None => { + let (kernel, rootfs, config) = build_mock_config()?; + (Some(kernel), Some(rootfs), config) + } + }; let instance_info = InstanceInfo { id: "anonymous-instance".to_string(), state: VmState::NotStarted, vmm_version: CPU_TEMPLATE_HELPER_VERSION.to_string(), app_name: "cpu-template-helper".to_string(), }; - let vm_resources = VmResources::from_json(config, &instance_info, HTTP_MAX_PAYLOAD_SIZE, None) - .map_err(UtilsError::CreateVmResources)?; + let mut vm_resources = + VmResources::from_json(&config, &instance_info, HTTP_MAX_PAYLOAD_SIZE, None) + .map_err(UtilsError::CreateVmResources)?; + if let Some(template) = template { + vm_resources.set_custom_cpu_template(template); + } let mut event_manager = EventManager::new().unwrap(); let seccomp_filters = get_empty_filters(); @@ -111,11 +159,9 @@ pub fn add_suffix(path: &Path, suffix: &str) -> PathBuf { pub mod tests { use std::fmt::Display; - use utils::tempfile::TempFile; - use vmm::utilities::mock_resources::kernel_image_path; + use vmm::resources::VmmConfig; use super::*; - use crate::tests::generate_config; const SUFFIX: &str = "_suffix"; @@ -153,28 +199,29 @@ pub mod tests { pub(crate) use mock_modifier; #[test] - fn test_build_microvm_from_valid_config() { - let kernel_image_path = kernel_image_path(None); - let rootfs_file = TempFile::new().unwrap(); - let valid_config = - generate_config(&kernel_image_path, rootfs_file.as_path().to_str().unwrap()); - - build_microvm_from_config(&valid_config).unwrap(); + fn test_build_mock_config() { + let kernel_path; + let rootfs_path; + { + let (kernel, rootfs, config) = build_mock_config().unwrap(); + kernel_path = kernel.as_path().to_path_buf(); + rootfs_path = rootfs.as_path().to_path_buf(); + + // Ensure the kernel exists and its content is written. + assert!(kernel.as_file().metadata().unwrap().len() > 0); + // Ensure the rootfs exists and it is empty. + assert_eq!(rootfs.as_file().metadata().unwrap().len(), 0); + // Ensure the generated config is valid as `VmmConfig`. + serde_json::from_str::(&config).unwrap(); + } + // Ensure the temporary mock resources are deleted. + assert!(!kernel_path.exists()); + assert!(!rootfs_path.exists()); } #[test] - fn test_build_microvm_from_invalid_config() { - let rootfs_file = TempFile::new().unwrap(); - let invalid_config = generate_config( - "/invalid_kernel_image_path", - rootfs_file.as_path().to_str().unwrap(), - ); - - match build_microvm_from_config(&invalid_config) { - Ok(_) => panic!("Should fail with `No such file or directory`."), - Err(UtilsError::CreateVmResources(_)) => (), - Err(err) => panic!("Unexpected error: {err}"), - } + fn test_build_microvm() { + build_microvm_from_config(None, None).unwrap(); } #[test] diff --git a/src/vmm/src/arch/aarch64/regs.rs b/src/vmm/src/arch/aarch64/regs.rs index 56222efb8cc..3cc0cbf6435 100644 --- a/src/vmm/src/arch/aarch64/regs.rs +++ b/src/vmm/src/arch/aarch64/regs.rs @@ -65,7 +65,7 @@ macro_rules! arm64_core_reg_id { // id = KVM_REG_ARM64 | KVM_REG_SIZE_U64/KVM_REG_SIZE_U32/KVM_REG_SIZE_U128 | // KVM_REG_ARM_CORE | offset KVM_REG_ARM64 as u64 - | u64::from(KVM_REG_ARM_CORE) + | KVM_REG_ARM_CORE as u64 | $size | (($offset / std::mem::size_of::()) as u64) }; @@ -106,8 +106,15 @@ arm64_sys_reg!(ID_AA64ISAR0_EL1, 3, 0, 0, 6, 0); arm64_sys_reg!(ID_AA64ISAR1_EL1, 3, 0, 0, 6, 1); arm64_sys_reg!(ID_AA64MMFR2_EL1, 3, 0, 0, 7, 2); -// EL0 Virtual Timer Registers -arm64_sys_reg!(KVM_REG_ARM_TIMER_CNT, 3, 3, 14, 3, 2); +// Counter-timer Virtual Timer CompareValue register. +// https://developer.arm.com/documentation/ddi0595/2021-12/AArch64-Registers/CNTV-CVAL-EL0--Counter-timer-Virtual-Timer-CompareValue-register +// https://elixir.bootlin.com/linux/v6.8/source/arch/arm64/include/asm/sysreg.h#L468 +arm64_sys_reg!(SYS_CNTV_CVAL_EL0, 3, 3, 14, 3, 2); + +// Counter-timer Physical Count Register +// https://developer.arm.com/documentation/ddi0601/2023-12/AArch64-Registers/CNTPCT-EL0--Counter-timer-Physical-Count-Register +// https://elixir.bootlin.com/linux/v6.8/source/arch/arm64/include/asm/sysreg.h#L459 +arm64_sys_reg!(SYS_CNTPCT_EL0, 3, 3, 14, 0, 1); /// Vector lengths pseudo-register /// TODO: this can be removed after https://github.com/rust-vmm/kvm-bindings/pull/89 @@ -115,6 +122,24 @@ arm64_sys_reg!(KVM_REG_ARM_TIMER_CNT, 3, 3, 14, 3, 2); pub const KVM_REG_ARM64_SVE_VLS: u64 = KVM_REG_ARM64 | KVM_REG_ARM64_SVE as u64 | KVM_REG_SIZE_U512 | 0xffff; +/// Program Counter +/// The offset value (0x100 = 32 * 8) is calcuated as follows: +/// - `kvm_regs` includes `regs` field of type `user_pt_regs` at the beginning (i.e., at offset 0). +/// - `pc` follows `regs[31]` and `sp` within `user_pt_regs` and they are 8 bytes each (i.e. the +/// offset is (31 + 1) * 8 = 256). +/// +/// https://github.com/torvalds/linux/blob/master/Documentation/virt/kvm/api.rst#L2578 +/// > 0x6030 0000 0010 0040 PC 64 regs.pc +pub const PC: u64 = arm64_core_reg_id!(KVM_REG_SIZE_U64, 0x100); + +// TODO: Once `core::mem::offset_of!()` macro becomes stable (maybe since 1.77.0?), use the +// following instead: https://github.com/firecracker-microvm/firecracker/issues/4504 +// pub const PC: u64 = { +// let kreg_off = offset_of!(kvm_regs, regs); +// let pc_off = offset_of!(user_pt_regs, pc); +// arm64_core_reg_id!(KVM_REG_SIZE_U64, kreg_off + pc_off) +// }; + /// Different aarch64 registers sizes #[derive(Debug)] pub enum RegSize { diff --git a/src/vmm/src/vstate/vcpu/aarch64.rs b/src/vmm/src/vstate/vcpu/aarch64.rs index d16745ea76b..68cebd1d4e7 100644 --- a/src/vmm/src/vstate/vcpu/aarch64.rs +++ b/src/vmm/src/vstate/vcpu/aarch64.rs @@ -7,12 +7,11 @@ use std::fmt::{Debug, Write}; -use kvm_bindings::*; use kvm_ioctls::*; use serde::{Deserialize, Serialize}; use crate::arch::aarch64::regs::{ - arm64_core_reg_id, offset__of, Aarch64RegisterVec, KVM_REG_ARM64_SVE_VLS, KVM_REG_ARM_TIMER_CNT, + Aarch64RegisterVec, KVM_REG_ARM64_SVE_VLS, PC, SYS_CNTPCT_EL0, SYS_CNTV_CVAL_EL0, }; use crate::arch::aarch64::vcpu::{ get_all_registers, get_all_registers_ids, get_mpidr, get_mpstate, get_registers, set_mpstate, @@ -223,20 +222,15 @@ impl KvmVcpu { pub fn dump_cpu_config(&self) -> Result { let mut reg_list = get_all_registers_ids(&self.fd).map_err(KvmVcpuError::DumpCpuConfig)?; - let kvm_reg_pc = { - let kreg_off = offset__of!(kvm_regs, regs); - let pc_off = offset__of!(user_pt_regs, pc) + kreg_off; - arm64_core_reg_id!(KVM_REG_SIZE_U64, pc_off) - }; - - // KVM_REG_ARM_TIMER_CNT should be removed, because it depends on the elapsed time and - // the dumped CPU config is used to create custom CPU templates to modify CPU features - // exposed to guests or ot detect CPU configuration changes caused by firecracker/KVM/ - // BIOS. + // SYS_CNTV_CVAL_EL0 and SYS_CNTPCT_EL0 are timer registers and depend on the elapsed time. + // This type of registers are not useful as guest CPU config dump. + // // The value of program counter (PC) is determined by the given kernel image. It should not // be overwritten by a custom CPU template and does not need to be tracked in a fingerprint // file. - reg_list.retain(|®_id| reg_id != KVM_REG_ARM_TIMER_CNT && reg_id != kvm_reg_pc); + reg_list.retain(|®_id| { + reg_id != SYS_CNTV_CVAL_EL0 && reg_id != SYS_CNTPCT_EL0 && reg_id != PC + }); let mut regs = Aarch64RegisterVec::default(); get_registers(&self.fd, ®_list, &mut regs).map_err(KvmVcpuError::DumpCpuConfig)?; diff --git a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_4.14host.json b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_4.14host.json index 87a7ee3cd60..4f25832efd7 100644 --- a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.334-252.552.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.x86_64", "microcode_version": "0xa0011d1", "bios_version": "1.0", "bios_revision": "0.69", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00010111100010111111101111111111" + "bitmap": "0b00000111100010111111101111111111" } ] }, @@ -294,7 +294,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", @@ -689,7 +689,7 @@ }, { "register": "ecx", - "bitmap": "0b00000000000000000111000000000001" + "bitmap": "0b00000000000000000111000000000000" }, { "register": "edx", @@ -1187,7 +1187,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000000000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", diff --git a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_5.10host.json b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_5.10host.json index ec5fb569e9c..750f7c6df3f 100644 --- a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.804.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.x86_64", "microcode_version": "0xa0011d1", "bios_version": "1.0", "bios_revision": "0.69", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00010111100010111111101111111111" + "bitmap": "0b00000111100010111111101111111111" } ] }, @@ -294,7 +294,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", @@ -735,7 +735,7 @@ }, { "register": "ecx", - "bitmap": "0b00000000000000000111000000000001" + "bitmap": "0b00000000000000000111000000000000" }, { "register": "edx", @@ -1279,7 +1279,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000000000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", diff --git a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_6.1host.json b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_6.1host.json index b0f9a675af7..3549d795bcd 100644 --- a/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_AMD_MILAN_6.1host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.66-93.164.amzn2023.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.x86_64", "microcode_version": "0xa0011d1", "bios_version": "1.0", "bios_revision": "0.69", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00010111100010111111101111111111" + "bitmap": "0b00000111100010111111101111111111" } ] }, @@ -294,7 +294,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", @@ -735,7 +735,7 @@ }, { "register": "ecx", - "bitmap": "0b00000000000000000111000000000001" + "bitmap": "0b00000000000000000111000000000000" }, { "register": "edx", @@ -1279,7 +1279,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000000000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_4.14host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_4.14host.json index 97f886776c9..13b4ff2795b 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.334-252.552.amzn2.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.aarch64", "microcode_version": "0x00000000000000ff", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_5.10host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_5.10host.json index 78f20b2474f..2ae9f82904f 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.804.amzn2.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.aarch64", "microcode_version": "0x00000000000000ff", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_6.1host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_6.1host.json index cf3ea1ef670..45f6eb8224b 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_N1_6.1host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.66-93.164.amzn2023.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.aarch64", "microcode_version": "0x00000000000000ff", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_4.14host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_4.14host.json index 35c88c6f95d..3d91c384582 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.334-252.552.amzn2.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.aarch64", "microcode_version": "0x0000000000000001", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_5.10host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_5.10host.json index a27d061010b..d822ac26a93 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.804.amzn2.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.aarch64", "microcode_version": "0x0000000000000001", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_6.1host.json b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_6.1host.json index 0dbcbf891b0..ac29160ce16 100644 --- a/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_ARM_NEOVERSE_V1_6.1host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.66-93.164.amzn2023.aarch64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.aarch64", "microcode_version": "0x0000000000000001", "bios_version": "1.0", "bios_revision": "1.0", @@ -30,7 +30,7 @@ }, { "addr": "0x6030000000100000", - "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001111111000000000000000000000" + "bitmap": "0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000111111000000000000000000000" }, { "addr": "0x6030000000100002", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_4.14host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_4.14host.json index 2e34fccd599..51366b92931 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.334-252.552.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.x86_64", "microcode_version": "0x5003604", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_5.10host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_5.10host.json index c72de709740..9d733826b8d 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.804.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.x86_64", "microcode_version": "0x5003604", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_6.1host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_6.1host.json index 884060ae874..ef6bbc38468 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_6.1host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.66-93.164.amzn2023.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.x86_64", "microcode_version": "0x5003604", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_4.14host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_4.14host.json index d78541a2a14..32d2f3f3380 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.334-252.552.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.x86_64", "microcode_version": "0xd0003b9", "bios_version": "1.0", "bios_revision": "1.33", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_5.10host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_5.10host.json index 8760b372b90..2447a89b38f 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.804.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.x86_64", "microcode_version": "0xd0003b9", "bios_version": "1.0", "bios_revision": "1.33", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -409,7 +409,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_6.1host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_6.1host.json index 69d352fee8b..5376db22d1a 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_ICELAKE_6.1host.json @@ -1,9 +1,9 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.66-93.164.amzn2023.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.x86_64", "microcode_version": "0xd0003b9", "bios_version": "1.0", - "bios_revision": "1.33", + "bios_revision": "1.36", "guest_cpu_config": { "kvm_capabilities": [], "cpuid_modifiers": [ @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111101010111111101111111111" + "bitmap": "0b00001111101010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -409,7 +409,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_4.14host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_4.14host.json index fe4dc09b1dd..71e2bd643d8 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_4.14host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_4.14host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "4.14.336-253.554.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "4.14.336-256.559.amzn2.x86_64", "microcode_version": "0x2007006", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_5.10host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_5.10host.json index 6358d4ab5dd..92694422140 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_5.10host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_5.10host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "5.10.205-195.807.amzn2.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "5.10.209-198.858.amzn2.x86_64", "microcode_version": "0x2007006", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_6.1host.json b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_6.1host.json index 1bb4bc01aec..2375e6e0d7e 100644 --- a/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_6.1host.json +++ b/tests/data/cpu_template_helper/fingerprint_INTEL_SKYLAKE_6.1host.json @@ -1,6 +1,6 @@ { - "firecracker_version": "1.7.0-dev", - "kernel_version": "6.1.72-96.166.amzn2023.x86_64", + "firecracker_version": "1.8.0-dev", + "kernel_version": "6.1.79-99.164.amzn2023.x86_64", "microcode_version": "0x2007006", "bios_version": "1.0", "bios_revision": "3.80", @@ -41,7 +41,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000100000100000000000" + "bitmap": "0b00000000000000010000100000000000" }, { "register": "ecx", @@ -49,7 +49,7 @@ }, { "register": "edx", - "bitmap": "0b00011111100010111111101111111111" + "bitmap": "0b00001111100010111111101111111111" } ] }, @@ -106,7 +106,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100001" + "bitmap": "0b00000000000000000000000100100001" }, { "register": "ebx", @@ -129,7 +129,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000100100010" + "bitmap": "0b00000000000000000000000100100010" }, { "register": "ebx", @@ -152,7 +152,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000000000101000011" + "bitmap": "0b00000000000000000000000101000011" }, { "register": "ebx", @@ -175,7 +175,7 @@ "modifiers": [ { "register": "eax", - "bitmap": "0b00000100000000000100000101100011" + "bitmap": "0b00000000000000000000000101100011" }, { "register": "ebx", @@ -386,7 +386,7 @@ }, { "register": "ebx", - "bitmap": "0b00000000000000000000000000000010" + "bitmap": "0b00000000000000000000000000000001" }, { "register": "ecx", diff --git a/tests/integration_tests/functional/test_cpu_template_helper.py b/tests/integration_tests/functional/test_cpu_template_helper.py index 492185a66e4..334b04060c4 100644 --- a/tests/integration_tests/functional/test_cpu_template_helper.py +++ b/tests/integration_tests/functional/test_cpu_template_helper.py @@ -30,12 +30,9 @@ def __init__(self): """Build CPU template helper tool binary""" self.binary = cargo_build.get_binary(self.BINARY_NAME) - def template_dump(self, vm_config_path, output_path): + def template_dump(self, output_path): """Dump guest CPU config in the JSON custom CPU template format""" - cmd = ( - f"{self.binary} template dump" - f" --config {vm_config_path} --output {output_path}" - ) + cmd = f"{self.binary} template dump --output {output_path}" utils.run_cmd(cmd) def template_strip(self, paths, suffix=""): @@ -44,17 +41,14 @@ def template_strip(self, paths, suffix=""): cmd = f"{self.binary} template strip --paths {paths} --suffix '{suffix}'" utils.run_cmd(cmd) - def template_verify(self, vm_config_path): + def template_verify(self, template_path): """Verify the specified CPU template""" - cmd = f"{self.binary} template verify --config {vm_config_path}" + cmd = f"{self.binary} template verify --template {template_path}" utils.run_cmd(cmd) - def fingerprint_dump(self, vm_config_path, output_path): + def fingerprint_dump(self, output_path): """Dump a fingerprint""" - cmd = ( - f"{self.binary} fingerprint dump" - f" --config {vm_config_path} --output {output_path}" - ) + cmd = f"{self.binary} fingerprint dump --output {output_path}" utils.run_cmd(cmd) def fingerprint_compare( @@ -79,25 +73,6 @@ def cpu_template_helper_fixture(): return CpuTemplateHelper() -def save_vm_config(microvm, tmp_path, custom_cpu_template=None): - """ - Save VM config into JSON file. - """ - config_json = microvm.api.vm_config.get().json() - config_json["boot-source"]["kernel_image_path"] = str(microvm.kernel_file) - config_json["drives"][0]["path_on_host"] = str(microvm.rootfs_file) - if custom_cpu_template is not None: - custom_cpu_template_path = tmp_path / "template.json" - Path(custom_cpu_template_path).write_text( - json.dumps(custom_cpu_template), encoding="utf-8" - ) - config_json["cpu-config"] = str(custom_cpu_template_path) - - vm_config_path = tmp_path / "vm_config.json" - Path(vm_config_path).write_text(json.dumps(config_json), encoding="utf-8") - return vm_config_path - - def build_cpu_config_dict(cpu_config_path): """Build a dictionary from JSON CPU config file.""" cpu_config_dict = { @@ -281,25 +256,16 @@ def test_cpu_config_dump_vs_actual( Verify that the dumped CPU config matches the actual CPU config inside guest. """ - microvm = microvm_factory.build(guest_kernel, rootfs) - microvm.spawn() - microvm.basic_config() - vm_config_path = save_vm_config(microvm, tmp_path) - # Dump CPU config with the helper tool. cpu_config_path = tmp_path / "cpu_config.json" - cpu_template_helper.template_dump(vm_config_path, cpu_config_path) + cpu_template_helper.template_dump(cpu_config_path) dump_cpu_config = build_cpu_config_dict(cpu_config_path) - # Add the network interface after we dump the CPU config via - # the CPU template helper tool. The tool creates a microVM with - # the config we pass it. When we pass it network configuration, we - # run in some sort of race condition with TAP device creation. - # CPU template helper tool doesn't need the network device configuration - # so, add it to `microvm` after we have dumped the CPU config. - microvm.add_net_iface() - # Retrieve actual CPU config from guest + microvm = microvm_factory.build(guest_kernel, rootfs) + microvm.spawn() + microvm.basic_config(vcpu_count=1) + microvm.add_net_iface() microvm.start() actual_cpu_config = { "cpuid": get_guest_cpuid(microvm), @@ -354,23 +320,16 @@ def test_cpu_config_dump_vs_actual( ), f"Mismatched MSR for {key:#010x}: {actual=:#066b} vs. {dump=:#066b}" -def detect_fingerprint_change( - microvm, tmp_path, results_dir, cpu_template_helper, filters=None -): +def detect_fingerprint_change(results_dir, cpu_template_helper, filters=None): """ Compare fingerprint files with filters between one taken at the moment and a baseline file taken in a specific point in time. """ fname = f"fingerprint_{global_props.cpu_codename}_{global_props.host_linux_version}host.json" - # Generate VM config from uvm_plain - microvm.spawn() - microvm.basic_config() - vm_config_path = save_vm_config(microvm, tmp_path) - # Dump a fingerprint with the generated VM config. fingerprint_path = results_dir / fname - cpu_template_helper.fingerprint_dump(vm_config_path, fingerprint_path) + cpu_template_helper.fingerprint_dump(fingerprint_path) # Baseline fingerprint. baseline_path = TEST_RESOURCES_DIR / fname @@ -388,82 +347,40 @@ def detect_fingerprint_change( global_props.host_linux_version not in SUPPORTED_HOST_KERNELS, reason=f"Supported kernels are {SUPPORTED_HOST_KERNELS}", ) -def test_guest_cpu_config_change(uvm_plain, tmp_path, results_dir, cpu_template_helper): +def test_guest_cpu_config_change(results_dir, cpu_template_helper): """ Verify that the guest CPU config has not changed since the baseline fingerprint was gathered. """ detect_fingerprint_change( - uvm_plain, - tmp_path, results_dir, cpu_template_helper, ["guest_cpu_config"], ) -def test_json_static_templates( - uvm_plain, cpu_template_helper, tmp_path, custom_cpu_template -): +def test_json_static_templates(cpu_template_helper, tmp_path, custom_cpu_template): """ Verify that JSON static CPU templates are applied as intended. """ - # Generate VM config with JSON static CPU template - microvm = uvm_plain - microvm.spawn() - microvm.basic_config() - vm_config_path = save_vm_config(microvm, tmp_path, custom_cpu_template["template"]) + custom_cpu_template_path = tmp_path / "template.json" + Path(custom_cpu_template_path).write_text( + json.dumps(custom_cpu_template["template"]), encoding="utf-8" + ) # Verify the JSON static CPU template. - cpu_template_helper.template_verify(vm_config_path) + cpu_template_helper.template_verify(custom_cpu_template_path) -def test_consecutive_cpu_config_consistency(uvm_plain, cpu_template_helper, tmp_path): +def test_consecutive_fingerprint_consistency(cpu_template_helper, tmp_path): """ - Verify that two dumped guest CPU configs obtained consecutively are - consistent. The dumped guest CPU config should not change without - any environmental changes (firecracker, kernel, microcode updates). + Verify that two fingerprints obtained consecutively are consistent. """ - microvm = uvm_plain - microvm.spawn() - microvm.basic_config() - vm_config_path = save_vm_config(microvm, tmp_path) - - # Dump CPU config with the helper tool. - cpu_config_1 = tmp_path / "cpu_config_1.json" - cpu_template_helper.template_dump(vm_config_path, cpu_config_1) - cpu_config_2 = tmp_path / "cpu_config_2.json" - cpu_template_helper.template_dump(vm_config_path, cpu_config_2) - - # Strip common entries. - cpu_template_helper.template_strip([cpu_config_1, cpu_config_2]) - - config_1 = json.loads(cpu_config_1.read_text(encoding="utf-8")) - config_2 = json.loads(cpu_config_2.read_text(encoding="utf-8")) - - # Check the stripped result is empty. - if PLATFORM == "x86_64": - empty_cpu_config = { - "cpuid_modifiers": [], - "kvm_capabilities": [], - "msr_modifiers": [], - } - elif PLATFORM == "aarch64": - # 0x603000000013df01 -> CNTPCT_EL0 - ignore_registers = ["0x603000000013df01"] - - config_1["reg_modifiers"] = [ - rm for rm in config_1["reg_modifiers"] if rm["addr"] not in ignore_registers - ] - config_2["reg_modifiers"] = [ - rm for rm in config_2["reg_modifiers"] if rm["addr"] not in ignore_registers - ] - - empty_cpu_config = { - "kvm_capabilities": [], - "reg_modifiers": [], - "vcpu_features": [], - } - - assert config_1 == empty_cpu_config - assert config_2 == empty_cpu_config + # Dump a fingerprint with the helper tool. + fp1 = tmp_path / "fp1.json" + cpu_template_helper.fingerprint_dump(fp1) + fp2 = tmp_path / "fp2.json" + cpu_template_helper.fingerprint_dump(fp2) + + # Compare them. + cpu_template_helper.fingerprint_compare(fp1, fp2, None)