Skip to content

Commit

Permalink
test: Add support for running tests inside stage2
Browse files Browse the repository at this point in the history
In the same way that support was added for running tests inside the svsm
kernel, add tests that run inside stage2. This is useful for
stage2-specific componenets such as the stage 2 #VC handler.

Signed-off-by: Adam Dunlap <acdunlap@google.com>
  • Loading branch information
AdamCDunlap committed Nov 21, 2023
1 parent 7b7384e commit d7fde53
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 15 deletions.
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");
}
}
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;
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

0 comments on commit d7fde53

Please sign in to comment.