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

Add support for running tests inside stage2 #150

Closed
wants to merge 2 commits into from
Closed
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
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ jobs:
# ld to work, so build all the objects without performing the
# final linking step.
- name: Build
run: make FEATURES="default,enable-gdb" stage1/kernel.elf stage1/stage1.o stage1/reset.o
run: make FEATURES="default,enable-gdb" stage1/kernel.elf stage1/test-kernel.elf stage1/stage2.bin stage1/test-stage2.bin stage1/stage1.o stage1/reset.o


- name: Run tests
run: make test
Expand Down
16 changes: 12 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CARGO_ARGS += -vv
endif

STAGE2_ELF = "target/x86_64-unknown-none/${TARGET_PATH}/stage2"
TEST_STAGE2_ELF = target/x86_64-unknown-none/${TARGET_PATH}/stage2-test
KERNEL_ELF = "target/x86_64-unknown-none/${TARGET_PATH}/svsm"
TEST_KERNEL_ELF = target/x86_64-unknown-none/${TARGET_PATH}/svsm-test
FS_FILE ?= none
Expand All @@ -23,12 +24,15 @@ C_BIT_POS ?= 51

STAGE1_OBJS = stage1/stage1.o stage1/reset.o

all: stage1/kernel.elf svsm.bin
all: stage1/kernel.elf stage1/stage2.bin svsm.bin

test:
cargo test --target=x86_64-unknown-linux-gnu

test-in-svsm: utils/cbit stage1/test-kernel.elf svsm.bin
test-in-svsm: utils/cbit stage1/stage2.bin stage1/test-kernel.elf svsm.bin
./scripts/test-in-svsm.sh

test-in-stage2: utils/cbit stage1/test-stage2.bin stage1/kernel.elf svsm.bin
./scripts/test-in-svsm.sh

doc:
Expand All @@ -50,6 +54,10 @@ stage1/stage2.bin:
cargo build ${CARGO_ARGS} --bin stage2
objcopy -O binary ${STAGE2_ELF} $@

stage1/test-stage2.bin:
LINK_STAGE2_TEST=1 cargo +nightly test --config 'target.x86_64-unknown-none.runner=["sh", "-c", "cp $$0 ${TEST_STAGE2_ELF}"]'
objcopy -O binary ${TEST_STAGE2_ELF} stage1/stage2.bin

stage1/kernel.elf:
cargo build ${CARGO_ARGS} --bin svsm
objcopy -O elf64-x86-64 --strip-unneeded ${KERNEL_ELF} $@
Expand All @@ -64,7 +72,7 @@ ifneq ($(FS_FILE), none)
endif
touch stage1/svsm-fs.bin

stage1/stage1.o: stage1/stage1.S stage1/stage2.bin stage1/svsm-fs.bin
stage1/stage1.o: stage1/stage1.S stage1/svsm-fs.bin
cc -c -o $@ stage1/stage1.S

stage1/reset.o: stage1/reset.S stage1/meta.bin
Expand All @@ -79,4 +87,4 @@ clean:
cargo clean
rm -f stage1/stage2.bin svsm.bin stage1/meta.bin stage1/kernel.elf stage1/stage1 stage1/svsm-fs.bin ${STAGE1_OBJS} utils/gen_meta utils/print-meta

.PHONY: stage1/stage2.bin stage1/kernel.elf stage1/test-kernel.elf svsm.bin clean stage1/svsm-fs.bin test test-in-svsm
.PHONY: stage1/stage2.bin stage1/test-stage2.bin stage1/kernel.elf stage1/test-kernel.elf svsm.bin clean stage1/svsm-fs.bin test test-in-svsm
12 changes: 11 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn main() {
println!("cargo:rustc-link-arg-bin=svsm=-Tsvsm.lds");
println!("cargo:rustc-link-arg-bin=svsm=-no-pie");

// Extra linker args for tests.
// Extra linker args for svsm kernel tests.
println!("cargo:rerun-if-env-changed=LINK_TEST");
if std::env::var("LINK_TEST").is_ok() {
println!("cargo:rustc-cfg=test_in_svsm");
Expand All @@ -28,4 +28,14 @@ fn main() {
println!("cargo:rustc-link-arg=-Tsvsm.lds");
println!("cargo:rustc-link-arg=-no-pie");
}

// Extra linker args for stage2 tests.
println!("cargo:rerun-if-env-changed=LINK_STAGE2_TEST");
if std::env::var("LINK_STAGE2_TEST").is_ok() {
println!("cargo:rustc-cfg=test_in_stage2");
println!("cargo:rustc-link-arg=-nostdlib");
println!("cargo:rustc-link-arg=--build-id=none");
println!("cargo:rustc-link-arg=-Tstage2.lds");
println!("cargo:rustc-link-arg=-no-pie");
}
}
12 changes: 6 additions & 6 deletions src/fs/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ mod tests {
use crate::mm::alloc::{TestRootMem, DEFAULT_TEST_MEMORY_SIZE};

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn create_dir() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand All @@ -510,7 +510,7 @@ mod tests {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn create_and_unlink_file() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand Down Expand Up @@ -541,7 +541,7 @@ mod tests {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn create_sub_dir() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand Down Expand Up @@ -570,7 +570,7 @@ mod tests {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_unlink() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand Down Expand Up @@ -600,7 +600,7 @@ mod tests {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_open_read_write_seek() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand Down Expand Up @@ -652,7 +652,7 @@ mod tests {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_multiple_file_handles() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
initialize_fs();
Expand Down
2 changes: 1 addition & 1 deletion src/fs/ramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ mod tests {
use crate::mm::alloc::{TestRootMem, DEFAULT_TEST_MEMORY_SIZE};

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_ramfs_file_read_write() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);

Expand Down
27 changes: 21 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@
#![no_std]
#![deny(missing_copy_implementations)]
#![deny(missing_debug_implementations)]
#![cfg_attr(all(test, test_in_svsm), no_main)]
#![cfg_attr(all(test, test_in_svsm), feature(custom_test_frameworks))]
#![cfg_attr(all(test, test_in_svsm), test_runner(crate::testing::svsm_test_runner))]
#![cfg_attr(all(test, test_in_svsm), reexport_test_harness_main = "test_main")]
#![cfg_attr(all(test, any(test_in_svsm, test_in_stage2)), no_main)]
#![cfg_attr(
all(test, any(test_in_svsm, test_in_stage2)),
feature(custom_test_frameworks)
)]
#![cfg_attr(
all(test, any(test_in_svsm, test_in_stage2)),
test_runner(crate::testing::svsm_test_runner)
)]
#![cfg_attr(
all(test, any(test_in_svsm, test_in_stage2)),
reexport_test_harness_main = "test_main"
)]

pub mod acpi;
pub mod address;
Expand Down Expand Up @@ -48,8 +57,14 @@ fn test_nop() {}
#[path = "svsm.rs"]
pub mod svsm_bin;
// The kernel expects to access this crate as svsm, so reexport.
#[cfg(all(test, test_in_svsm))]
#[cfg(all(test, any(test_in_svsm, test_in_stage2)))]
extern crate self as svsm;
// Include a module containing the test runner.
#[cfg(all(test, test_in_svsm))]
#[cfg(all(test, any(test_in_svsm, test_in_stage2)))]
pub mod testing;

// When running tests inside the SVSM:
// Build the kernel entrypoint.
#[cfg(all(test, test_in_stage2))]
#[path = "stage2.rs"]
pub mod stage2_bin;
18 changes: 9 additions & 9 deletions src/mm/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,14 +1313,14 @@ impl Drop for TestRootMem<'_> {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_root_mem_setup() {
let test_mem_lock = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
drop(test_mem_lock);
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate one page and free it again, verify that memory_info() reflects it.
fn test_page_alloc_one() {
let _test_mem = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
Expand All @@ -1335,7 +1335,7 @@ fn test_page_alloc_one() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate and free all available compound pages, verify that memory_info()
// reflects it.
fn test_page_alloc_all_compound() {
Expand Down Expand Up @@ -1368,7 +1368,7 @@ fn test_page_alloc_all_compound() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate and free all available 4k pages, verify that memory_info()
// reflects it.
fn test_page_alloc_all_single() {
Expand Down Expand Up @@ -1401,7 +1401,7 @@ fn test_page_alloc_all_single() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate and free all available compound pages, verify that any subsequent
// allocation fails.
fn test_page_alloc_oom() {
Expand Down Expand Up @@ -1439,7 +1439,7 @@ fn test_page_alloc_oom() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
fn test_page_file() {
let _mem_lock = TestRootMem::setup(DEFAULT_TEST_MEMORY_SIZE);
let mut root_mem = ROOT_MEM.lock();
Expand Down Expand Up @@ -1474,7 +1474,7 @@ fn test_page_file() {
const TEST_SLAB_SIZES: [usize; 7] = [32, 64, 128, 256, 512, 1024, 2048];

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate and free a couple of objects for each slab size.
fn test_slab_alloc_free_many() {
extern crate alloc;
Expand Down Expand Up @@ -1514,7 +1514,7 @@ fn test_slab_alloc_free_many() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate enough objects so that the SlabPageSlab will need a SlabPage for
// itself twice.
fn test_slab_page_slab_for_self() {
Expand Down Expand Up @@ -1551,7 +1551,7 @@ fn test_slab_page_slab_for_self() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
#[cfg_attr(any(test_in_svsm, test_in_stage2), ignore = "FIXME")]
// Allocate enough objects to hit an OOM situation and verify null gets
// returned at some point.
fn test_slab_oom() {
Expand Down
9 changes: 6 additions & 3 deletions src/stage2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//
// Author: Joerg Roedel <jroedel@suse.de>

#![no_std]
#![no_main]
#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(test), no_main)]

pub mod boot_stage2;

Expand Down Expand Up @@ -142,7 +142,7 @@ fn map_and_validate(vaddr: VirtAddr, paddr: PhysAddr, len: usize) {
// Launch info from stage1, usually at the bottom of the stack
// The layout has to match the order in which the parts are pushed to the stack
// in stage1/stage1.S
#[derive(Default, Debug)]
#[derive(Default, Debug, Clone, Copy)]
#[repr(C, packed)]
pub struct Stage1LaunchInfo {
kernel_elf_start: u32,
Expand Down Expand Up @@ -297,6 +297,9 @@ pub extern "C" fn stage2_main(launch_info: &Stage1LaunchInfo) {
let kernel_entry = kernel_elf.get_entry(kernel_vaddr_alloc_base);
let valid_bitmap = valid_bitmap_addr();

#[cfg(test)]
crate::test_main();

// Shut down the GHCB
shutdown_percpu();

Expand Down