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

run tests inside SVSM #120

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

- name: Run tests
run: make test
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ target/
gen_meta
stage1/stage1
print-meta
cbit
.idea/
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ intrusive-collections = "0.9.6"
log = { version = "0.4.17", features = ["max_level_info", "release_max_level_info"] }
packit = { git = "https://github.com/coconut-svsm/packit", version = "0.1.0" }

[build-dependencies]
[target."x86_64-unknown-none".dev-dependencies]
test = { version = "0.1.0", path = "test" }

[features]
default = ["enable-stacktrace"]
Expand Down
6 changes: 6 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ The project also contains a number of unit-tests which can be run by
$ make test
```

Unit tests can be run inside the SVSM by

```
$ QEMU=/path/to/qemu OVMF=/path/to/firmware/ make test-in-svsm
```

Putting it all together
-----------------------

Expand Down
23 changes: 18 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,38 @@ FEATURES ?= "default"
CARGO_ARGS = --features ${FEATURES}

ifdef RELEASE
TARGET_PATH="release"
TARGET_PATH=release
CARGO_ARGS += --release
else
TARGET_PATH="debug"
TARGET_PATH=debug
endif

STAGE2_ELF = "target/x86_64-unknown-none/${TARGET_PATH}/stage2"
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

C_BIT_POS ?= 51

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

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

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

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

utils/gen_meta: utils/gen_meta.c
cc -O3 -Wall -o $@ $<

utils/print-meta: utils/print-meta.c
cc -O3 -Wall -o $@ $<

utils/cbit: utils/cbit.c
cc -O3 -Wall -o $@ $<

stage1/meta.bin: utils/gen_meta utils/print-meta
./utils/gen_meta $@

Expand All @@ -36,13 +45,17 @@ stage1/kernel.elf:
cargo build ${CARGO_ARGS} --bin svsm
objcopy -O elf64-x86-64 --strip-unneeded ${KERNEL_ELF} $@

stage1/test-kernel.elf:
LINK_TEST=1 cargo +nightly test --config 'target.x86_64-unknown-none.runner=["sh", "-c", "cp $$0 ${TEST_KERNEL_ELF}"]'
objcopy -O elf64-x86-64 --strip-unneeded ${TEST_KERNEL_ELF} stage1/kernel.elf

stage1/svsm-fs.bin:
ifneq ($(FS_FILE), none)
cp -f $(FS_FILE) stage1/svsm-fs.bin
endif
touch stage1/svsm-fs.bin

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

stage1/reset.o: stage1/reset.S stage1/meta.bin
Expand All @@ -57,4 +70,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 svsm.bin clean stage1/svsm-fs.bin
.PHONY: stage1/stage2.bin stage1/kernel.elf stage1/test-kernel.elf svsm.bin clean stage1/svsm-fs.bin test test-in-svsm
11 changes: 11 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,15 @@ fn main() {
println!("cargo:rustc-link-arg-bin=svsm=--no-relax");
println!("cargo:rustc-link-arg-bin=svsm=-Tsvsm.lds");
println!("cargo:rustc-link-arg-bin=svsm=-no-pie");

// Extra linker args for tests.
println!("cargo:rerun-if-env-changed=LINK_TEST");
if std::env::var("LINK_TEST").is_ok() {
println!("cargo:rustc-cfg=test_in_svsm");
println!("cargo:rustc-link-arg=-nostdlib");
println!("cargo:rustc-link-arg=--build-id=none");
println!("cargo:rustc-link-arg=--no-relax");
println!("cargo:rustc-link-arg=-Tsvsm.lds");
println!("cargo:rustc-link-arg=-no-pie");
}
}
34 changes: 34 additions & 0 deletions scripts/test-in-svsm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
#

set -e

if [ "$QEMU" == "" ]; then
echo "Set QEMU environment variable to QEMU installation path" && exit 1
fi
if [ "$OVMF_PATH" == "" ]; then
echo "Set OVMF_PATH environment variable to a folder containing OVMF_CODE.fd and OVMF_VARS.fd" && exit 1
fi
if [ "$SUDO" != "" ]; then
SUDO_CMD="sudo"
else
SUDO_CMD=""
fi

C_BIT_POS=`utils/cbit`

$SUDO_CMD $QEMU \
-enable-kvm \
-cpu EPYC-v4 \
-machine q35,confidential-guest-support=sev0,memory-backend=ram1,kvm-type=protected \
-object memory-backend-memfd-private,id=ram1,size=1G,share=true \
-object sev-snp-guest,id=sev0,cbitpos=$C_BIT_POS,reduced-phys-bits=1,svsm=on \
-smp 8 \
-no-reboot \
-drive if=pflash,format=raw,unit=0,file=$OVMF_PATH/OVMF_CODE.fd,readonly=on \
-drive if=pflash,format=raw,unit=1,file=$OVMF_PATH/OVMF_VARS.fd,snapshot=on \
-drive if=pflash,format=raw,unit=2,file=./svsm.bin,readonly=on \
-nographic \
-monitor none \
-serial stdio \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 || true
6 changes: 6 additions & 0 deletions src/fs/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ mod tests {
use crate::mm::alloc::{TestRootMem, DEFAULT_TEST_MEMORY_SIZE};

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

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

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

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

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

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

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

Expand Down
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
// Author: Nicolai Stange <nstange@suse.de>

#![no_std]
#![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")]

pub mod acpi;
pub mod address;
Expand Down Expand Up @@ -33,3 +37,15 @@ pub mod utils;

#[test]
fn test_nop() {}

// When running tests inside the SVSM:
// Build the kernel entrypoint.
#[cfg(all(test, test_in_svsm))]
#[path = "svsm.rs"]
pub mod svsm_bin;
// The kernel expects to access this crate as svsm, so reexport.
#[cfg(all(test, test_in_svsm))]
extern crate self as svsm;
// Include a module containing the test runner.
#[cfg(all(test, test_in_svsm))]
pub mod testing;
12 changes: 6 additions & 6 deletions src/mm/address_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
//
// Author: Joerg Roedel <jroedel@suse.de>

#[cfg(any(test, fuzzing))]
use crate::address::Address;
use crate::address::{PhysAddr, VirtAddr};
use crate::utils::immut_after_init::ImmutAfterInitCell;

Expand All @@ -30,7 +28,7 @@ pub fn init_kernel_mapping_info(vstart: VirtAddr, vend: VirtAddr, pstart: PhysAd
.expect("Already initialized kernel mapping info");
}

#[cfg(not(any(test, fuzzing)))]
#[cfg(target_os = "none")]
pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
if vaddr < KERNEL_MAPPING.virt_start || vaddr >= KERNEL_MAPPING.virt_end {
panic!("Invalid physical address {:#018x}", vaddr);
Expand All @@ -41,7 +39,7 @@ pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
KERNEL_MAPPING.phys_start + offset
}

#[cfg(not(any(test, fuzzing)))]
#[cfg(target_os = "none")]
pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
let size: usize = KERNEL_MAPPING.virt_end - KERNEL_MAPPING.virt_start;
if paddr < KERNEL_MAPPING.phys_start || paddr >= KERNEL_MAPPING.phys_start + size {
Expand All @@ -53,13 +51,15 @@ pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
KERNEL_MAPPING.virt_start + offset
}

#[cfg(any(test, fuzzing))]
#[cfg(not(target_os = "none"))]
pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
use crate::address::Address;
PhysAddr::from(vaddr.bits())
}

#[cfg(any(test, fuzzing))]
#[cfg(not(target_os = "none"))]
pub fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
use crate::address::Address;
VirtAddr::from(paddr.bits())
}

Expand Down
9 changes: 9 additions & 0 deletions src/mm/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1332,12 +1332,14 @@ impl Drop for TestRootMem<'_> {
}

#[test]
#[cfg_attr(test_in_svsm, 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")]
// 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 @@ -1352,6 +1354,7 @@ fn test_page_alloc_one() {
}

#[test]
#[cfg_attr(test_in_svsm, 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 @@ -1384,6 +1387,7 @@ fn test_page_alloc_all_compound() {
}

#[test]
#[cfg_attr(test_in_svsm, 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 @@ -1416,6 +1420,7 @@ fn test_page_alloc_all_single() {
}

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

#[test]
#[cfg_attr(test_in_svsm, 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 @@ -1486,6 +1492,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")]
// Allocate and free a couple of objects for each slab size.
fn test_slab_alloc_free_many() {
extern crate alloc;
Expand Down Expand Up @@ -1525,6 +1532,7 @@ fn test_slab_alloc_free_many() {
}

#[test]
#[cfg_attr(test_in_svsm, 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 @@ -1561,6 +1569,7 @@ fn test_slab_page_slab_for_self() {
}

#[test]
#[cfg_attr(test_in_svsm, ignore = "FIXME")]
// Allocate enough objects to hit an OOM situation and verify null gets
// returned at some point.
fn test_slab_oom() {
Expand Down
7 changes: 5 additions & 2 deletions src/svsm.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)]

extern crate alloc;

Expand Down Expand Up @@ -479,6 +479,9 @@ pub extern "C" fn svsm_main() {
panic!("Failed to launch FW: {:#?}", e);
}

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

request_loop();

panic!("Road ends here!");
Expand Down
Loading
Loading