Skip to content

Commit 1c79406

Browse files
haowqsjyao1
authored andcommitted
tests/test-td-payload: Run TDX hardware specific unit test cases inside a VM
Signed-off-by: Wei Liu <wei3.liu@intel.com> Signed-off-by: haowei <WeiX.Hao@intel.com>
1 parent 24b8110 commit 1c79406

File tree

8 files changed

+746
-0
lines changed

8 files changed

+746
-0
lines changed

tests/test-td-payload/Cargo.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "test-td-payload"
3+
version = "0.1.0"
4+
description = "Run TDX hardware specific unit test cases inside a VM"
5+
repository = "https://github.com/confidential-containers/td-shim"
6+
homepage = "https://github.com/confidential-containers"
7+
license = "BSD-2-Clause-Patent"
8+
edition = "2018"
9+
10+
[dependencies]
11+
spin = "0.9.2"
12+
r-efi = "3.2.0"
13+
linked_list_allocator = "0.9.0"
14+
log = "0.4.13"
15+
td-uefi-pi = { path = "../../td-uefi-pi" }
16+
tdx-tdcall = { path = "../../tdx-tdcall" , optional = true }
17+
td-logger = { path = "../../td-logger" }
18+
td-exception = { path = "../../td-exception" }
19+
td-layout = { path = "../../td-layout" }
20+
scroll = { version = "0.10.0", default-features = false, features = ["derive"]}
21+
serde = { version = "1.0", default-features = false, features = ["derive"]}
22+
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
23+
24+
[dependencies.lazy_static]
25+
version = "1.0"
26+
features = ["spin_no_std"]
27+
28+
[package.metadata.bootloader]
29+
map-physical-memory = true
30+
31+
[features]
32+
cet-ss = []
33+
tdx = ["tdx-tdcall", "td-logger/tdx"]
34+
main = []

tests/test-td-payload/src/lib.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) 2021 Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-2-Clause-Patent
4+
5+
#![no_std]
6+
extern crate alloc;
7+
8+
use alloc::boxed::Box;
9+
use alloc::string::String;
10+
use alloc::vec::Vec;
11+
use serde::{Deserialize, Serialize};
12+
13+
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
14+
pub enum TestResult {
15+
Pass,
16+
Fail,
17+
None,
18+
}
19+
20+
pub trait TestCase {
21+
fn setup(&mut self);
22+
fn run(&mut self);
23+
fn teardown(&mut self);
24+
fn get_name(&mut self) -> String;
25+
fn get_result(&mut self) -> TestResult;
26+
}
27+
28+
pub struct TestSuite {
29+
pub testsuite: Vec<Box<dyn TestCase>>,
30+
pub passed_cases: u32,
31+
pub failed_cases: u32,
32+
}
33+
34+
impl TestSuite {
35+
pub fn run(&mut self) {
36+
for tc in self.testsuite.iter_mut() {
37+
log::info!("[Test: {}]\n", String::from(tc.get_name()));
38+
tc.setup();
39+
tc.run();
40+
tc.teardown();
41+
42+
let res = tc.get_result();
43+
match res {
44+
TestResult::Pass => {
45+
self.passed_cases += 1;
46+
log::info!("[Test: {0}] - Pass\n", tc.get_name());
47+
}
48+
TestResult::Fail => {
49+
self.failed_cases += 1;
50+
log::info!("[Test: {0}] - Fail\n", tc.get_name());
51+
}
52+
TestResult::None => {
53+
log::info!("[Test: {0}] - Skip\n", tc.get_name());
54+
}
55+
}
56+
57+
log::info!("---------------------------------------------\n")
58+
}
59+
}
60+
}

tests/test-td-payload/src/main.rs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Copyright (c) 2021 Intel Corporation
2+
//
3+
// SPDX-License-Identifier: BSD-2-Clause-Patent
4+
5+
#![no_std]
6+
#![no_main]
7+
#![allow(unused)]
8+
#![feature(alloc_error_handler)]
9+
#[macro_use]
10+
11+
mod lib;
12+
mod testiorw32;
13+
mod testiorw8;
14+
mod testtdinfo;
15+
mod testtdreport;
16+
17+
extern crate alloc;
18+
use alloc::boxed::Box;
19+
use alloc::string::String;
20+
use alloc::string::ToString;
21+
use alloc::vec::Vec;
22+
use core::ffi::c_void;
23+
use core::panic::PanicInfo;
24+
use linked_list_allocator::LockedHeap;
25+
use td_layout::memslice;
26+
27+
use crate::lib::{TestResult, TestSuite};
28+
use crate::testiorw32::Tdiorw32;
29+
use crate::testiorw8::Tdiorw8;
30+
use crate::testtdinfo::Tdinfo;
31+
use crate::testtdreport::Tdreport;
32+
33+
use r_efi::efi::Guid;
34+
use serde::{Deserialize, Serialize};
35+
use serde_json::{Result, Value};
36+
use td_uefi_pi::{fv, hob, pi};
37+
38+
#[derive(Debug, Serialize, Deserialize)]
39+
// The test cases' data structure corresponds to the test config json data structure
40+
pub struct TestCases {
41+
pub tcs001: Tdinfo,
42+
pub tcs002: Tdinfo,
43+
pub tcs003: Tdinfo,
44+
pub tcs004: Tdreport,
45+
pub tcs005: Tdiorw8,
46+
pub tcs006: Tdiorw32,
47+
}
48+
49+
pub const CFV_FFS_HEADER_TEST_CONFIG_GUID: Guid = Guid::from_fields(
50+
0xf10e684e,
51+
0x3abd,
52+
0x20e4,
53+
0x59,
54+
0x32,
55+
&[0x8f, 0x97, 0x3c, 0x35, 0x5e, 0x57],
56+
); // {F10E684E-3ABD-20E4-5932-8F973C355E57}
57+
58+
#[cfg(not(test))]
59+
#[panic_handler]
60+
#[allow(clippy::empty_loop)]
61+
fn panic(_info: &PanicInfo) -> ! {
62+
log::info!("panic ... {:?}\n", _info);
63+
loop {}
64+
}
65+
66+
#[alloc_error_handler]
67+
#[allow(clippy::empty_loop)]
68+
fn alloc_error(_info: core::alloc::Layout) -> ! {
69+
log::info!("alloc_error ... {:?}\n", _info);
70+
panic!("deadloop");
71+
}
72+
73+
#[cfg(not(test))]
74+
#[global_allocator]
75+
static ALLOCATOR: LockedHeap = LockedHeap::empty();
76+
77+
#[cfg(not(test))]
78+
fn init_heap(heap_start: usize, heap_size: usize) {
79+
unsafe {
80+
ALLOCATOR.lock().init(heap_start, heap_size);
81+
}
82+
}
83+
84+
#[cfg(not(test))]
85+
fn build_testcases() -> TestCases {
86+
log::info!("Starting get test data from cfv and parse json data\n");
87+
let cfv = memslice::get_mem_slice(memslice::SliceType::Config);
88+
let json_data = fv::get_file_from_fv(
89+
cfv,
90+
pi::fv::FV_FILETYPE_RAW,
91+
CFV_FFS_HEADER_TEST_CONFIG_GUID,
92+
)
93+
.unwrap();
94+
let json_string = String::from_utf8_lossy(json_data).to_string();
95+
// trim zero in json string
96+
let json_config = json_string.trim_matches(char::from(0));
97+
98+
serde_json::from_str(json_config).unwrap()
99+
}
100+
101+
#[cfg(not(test))]
102+
#[no_mangle]
103+
#[cfg_attr(target_os = "uefi", export_name = "efi_main")]
104+
extern "win64" fn _start(hob: *const c_void) -> ! {
105+
use td_layout::runtime::*;
106+
107+
td_logger::init();
108+
log::info!("Starting rust-tdcall-payload hob - {:p}\n", hob);
109+
110+
// init heap so that we can allocate memory
111+
let hob_buffer = unsafe {
112+
memslice::get_dynamic_mem_slice_mut(memslice::SliceType::PayloadHob, hob as usize)
113+
};
114+
115+
let hob_size = hob::get_hob_total_size(hob_buffer).unwrap();
116+
let hob_list = &hob_buffer[..hob_size];
117+
118+
init_heap(
119+
(hob::get_system_memory_size_below_4gb(hob_list).unwrap() as usize
120+
- (TD_PAYLOAD_HOB_SIZE
121+
+ TD_PAYLOAD_STACK_SIZE
122+
+ TD_PAYLOAD_SHADOW_STACK_SIZE
123+
+ TD_PAYLOAD_ACPI_SIZE
124+
+ TD_PAYLOAD_EVENT_LOG_SIZE) as usize
125+
- TD_PAYLOAD_HEAP_SIZE as usize),
126+
TD_PAYLOAD_HEAP_SIZE as usize,
127+
);
128+
129+
// create TestSuite to hold the test cases
130+
let mut ts = TestSuite {
131+
testsuite: Vec::new(),
132+
passed_cases: 0,
133+
failed_cases: 0,
134+
};
135+
136+
// build test cases with test configuration data in CFV
137+
let tcs = build_testcases();
138+
139+
// Add test cases in ts.testsuite
140+
if tcs.tcs001.run {
141+
ts.testsuite.push(Box::new(tcs.tcs001));
142+
}
143+
144+
if tcs.tcs002.run {
145+
ts.testsuite.push(Box::new(tcs.tcs002));
146+
}
147+
148+
if tcs.tcs003.run {
149+
ts.testsuite.push(Box::new(tcs.tcs003));
150+
}
151+
152+
if tcs.tcs004.run {
153+
ts.testsuite.push(Box::new(tcs.tcs004));
154+
}
155+
156+
if tcs.tcs005.run {
157+
ts.testsuite.push(Box::new(tcs.tcs005));
158+
}
159+
160+
if tcs.tcs006.run {
161+
ts.testsuite.push(Box::new(tcs.tcs006));
162+
}
163+
164+
// run the TestSuite which contains the test cases
165+
log::info!("---------------------------------------------\n");
166+
log::info!("Start to run tests.\n");
167+
log::info!("---------------------------------------------\n");
168+
ts.run();
169+
log::info!(
170+
"Test Result: Total run {0} tests; {1} passed; {2} failed\n",
171+
ts.testsuite.len(),
172+
ts.passed_cases,
173+
ts.failed_cases
174+
);
175+
176+
panic!("deadloop");
177+
}

tests/test-td-payload/src/test.json

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"tcs001": {
3+
"name": "tdinfo001",
4+
"expected": {
5+
"gpaw": 52,
6+
"attributes": 0,
7+
"max_vcpus": 1,
8+
"num_vcpus": 1,
9+
"rsvd": [0,0,0]
10+
},
11+
"result": "None",
12+
"run": true
13+
},
14+
"tcs002": {
15+
"name": "tdinfo002",
16+
"expected": {
17+
"gpaw": 52,
18+
"attributes": 0,
19+
"max_vcpus": 8,
20+
"num_vcpus": 8,
21+
"rsvd": [0,0,0]
22+
},
23+
"result": "None",
24+
"run": false
25+
},
26+
"tcs003": {
27+
"name": "tdinfo003",
28+
"expected": {
29+
"gpaw": 48,
30+
"attributes": 0,
31+
"max_vcpus": 1,
32+
"num_vcpus": 1,
33+
"rsvd": [0,0,0]
34+
},
35+
"result": "None",
36+
"run": false
37+
},
38+
"tcs004": {
39+
"name": "tdreport001",
40+
"input": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
44+
"expected": {
45+
"type": 129,
46+
"subtype": 0,
47+
"version": 0
48+
},
49+
"result": "None",
50+
"run": true
51+
},
52+
"tcs005": {
53+
"name": "testiorw8",
54+
"result": "None",
55+
"run": true
56+
},
57+
"tcs006": {
58+
"name": "testiorw32",
59+
"result": "None",
60+
"run": true
61+
}
62+
}

0 commit comments

Comments
 (0)