diff --git a/security-monitor/Cargo.lock b/security-monitor/Cargo.lock new file mode 100644 index 0000000..c400446 --- /dev/null +++ b/security-monitor/Cargo.lock @@ -0,0 +1,657 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "either" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" + +[[package]] +name = "endian-type-rs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fdt-rs" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581d3afdd654deb68c19fcbe4bc411910cc64067d4a13d8637bda7722cb9c2ea" +dependencies = [ + "endian-type-rs", + "fallible-iterator", + "memoffset 0.5.6", + "num-derive", + "num-traits", + "rustc_version", + "static_assertions", + "unsafe_unwrap", +] + +[[package]] +name = "flattened_device_tree" +version = "0.1.0" +dependencies = [ + "fdt-rs", + "thiserror-no-std", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opensbi-sys" +version = "0.1.0" +dependencies = [ + "bindgen", +] + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pointers_utility" +version = "0.1.0" +dependencies = [ + "thiserror-no-std", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "riscv-decode" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec7a6dc0b0bb96a4d23271864a45c0d24dcd9dde2a1b630a35f79fa29c588bf" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "security-monitor" +version = "0.3.0" +dependencies = [ + "flattened_device_tree", + "memoffset 0.9.0", + "opensbi-sys", + "pointers_utility", + "riscv-decode", + "spin", + "thiserror-no-std", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unsafe_unwrap" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/security-monitor/src/confidential_flow/apply_to_confidential_vm.rs b/security-monitor/src/confidential_flow/apply_to_confidential_vm.rs index e83f28e..48a38f3 100644 --- a/security-monitor/src/confidential_flow/apply_to_confidential_vm.rs +++ b/security-monitor/src/confidential_flow/apply_to_confidential_vm.rs @@ -1,11 +1,13 @@ // SPDX-FileCopyrightText: 2023 IBM Corporation // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 +use crate::confidential_flow::handlers::mmio::MmioAccessFault; use crate::confidential_flow::handlers::sbi::SbiResponse; use crate::confidential_flow::handlers::virtual_instructions::VirtualInstruction; /// Transformation of the confidential hart state in a response to processing of a confidential hart call. pub enum ApplyToConfidentialHart { + MmioAccessFault(MmioAccessFault), SbiResponse(SbiResponse), VirtualInstruction(VirtualInstruction), } diff --git a/security-monitor/src/confidential_flow/finite_state_machine.rs b/security-monitor/src/confidential_flow/finite_state_machine.rs index 722fc25..37267d0 100644 --- a/security-monitor/src/confidential_flow/finite_state_machine.rs +++ b/security-monitor/src/confidential_flow/finite_state_machine.rs @@ -173,6 +173,7 @@ impl<'a> ConfidentialFlow<'a> { /// execute the confidential hart on the hardware hart. pub fn apply_and_exit_to_confidential_hart(mut self, transformation: ApplyToConfidentialHart) -> ! { match transformation { + ApplyToConfidentialHart::MmioAccessFault(v) => v.apply_to_confidential_hart(self.confidential_hart_mut()), ApplyToConfidentialHart::SbiResponse(v) => v.apply_to_confidential_hart(self.confidential_hart_mut()), ApplyToConfidentialHart::VirtualInstruction(v) => v.apply_to_confidential_hart(self.confidential_hart_mut()), } diff --git a/security-monitor/src/confidential_flow/handlers/mmio/add_mmio_region.rs b/security-monitor/src/confidential_flow/handlers/mmio/add_mmio_region.rs index d347c3e..2702d78 100644 --- a/security-monitor/src/confidential_flow/handlers/mmio/add_mmio_region.rs +++ b/security-monitor/src/confidential_flow/handlers/mmio/add_mmio_region.rs @@ -1,10 +1,12 @@ // SPDX-FileCopyrightText: 2023 IBM Corporation // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 -use crate::confidential_flow::handlers::sbi::SbiResponse; +use crate::confidential_flow::handlers::sbi::{SbiRequest, SbiResponse}; use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow}; +use crate::core::architecture::sbi::CovgExtension; use crate::core::architecture::GeneralPurposeRegister; -use crate::core::control_data::ConfidentialHart; +use crate::core::control_data::{ConfidentialHart, ConfidentialVmMmioRegion, ControlData, PendingRequest}; +use crate::non_confidential_flow::DeclassifyToHypervisor; pub struct AddMmioRegion { region_start_address: usize, @@ -20,10 +22,20 @@ impl AddMmioRegion { } pub fn handle(self, confidential_flow: ConfidentialFlow) -> ! { - // TODO: make sure region_start_address is aligned to 4KiB - // TODO: make sure the region_start_address is a valid guest address - // TODO: make sure this region does not overlap with any other previously defined region - let transformation = ApplyToConfidentialHart::SbiResponse(SbiResponse::success()); - confidential_flow.apply_and_exit_to_confidential_hart(transformation) + match ControlData::try_confidential_vm(confidential_flow.confidential_vm_id(), |mut confidential_vm| { + Ok(confidential_vm.add_mmio_region(ConfidentialVmMmioRegion::new(self.region_start_address, self.region_length)?)?) + }) { + Ok(_) => confidential_flow + .set_pending_request(PendingRequest::SbiRequest()) + .into_non_confidential_flow() + .declassify_and_exit_to_hypervisor(DeclassifyToHypervisor::SbiRequest(self.sbi_add_mmio_region())), + Err(error) => { + confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::SbiResponse(SbiResponse::error(error))) + } + } + } + + fn sbi_add_mmio_region(&self) -> SbiRequest { + SbiRequest::new(CovgExtension::EXTID, CovgExtension::SBI_EXT_COVG_ADD_MMIO_REGION, self.region_start_address, self.region_length) } } diff --git a/security-monitor/src/confidential_flow/handlers/mmio/mmio_access_fault.rs b/security-monitor/src/confidential_flow/handlers/mmio/mmio_access_fault.rs new file mode 100644 index 0000000..dddd6ae --- /dev/null +++ b/security-monitor/src/confidential_flow/handlers/mmio/mmio_access_fault.rs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2023 IBM Corporation +// SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich +// SPDX-License-Identifier: Apache-2.0 +use crate::core::control_data::{ConfidentialHart, ConfidentialVmId, ConfidentialVmMmioRegion, ControlData}; +use core::mem; + +pub struct MmioAccessFault { + cause: usize, + mtval: usize, + instruction_length: usize, +} + +impl MmioAccessFault { + pub const ADDRESS_ALIGNMENT: usize = mem::size_of::(); + + pub fn new(cause: usize, mtval: usize, instruction_length: usize) -> Self { + Self { cause, mtval, instruction_length } + } + + pub fn apply_to_confidential_hart(&self, confidential_hart: &mut ConfidentialHart) { + let mepc = confidential_hart.csrs().mepc.read_value() + self.instruction_length; + confidential_hart.csrs_mut().vsepc.set(mepc); + let trap_vector_address = confidential_hart.csrs().vstvec.read(); + confidential_hart.csrs_mut().mepc.save_value(trap_vector_address); + confidential_hart.csrs_mut().vscause.set(self.cause); + confidential_hart.csrs_mut().vstval.set(self.mtval); + } + + pub fn tried_to_access_valid_mmio_region(confidential_vm_id: ConfidentialVmId, fault_address: usize) -> bool { + ControlData::try_confidential_vm(confidential_vm_id, |confidential_vm| { + Ok(confidential_vm.is_mmio_region_defined(&ConfidentialVmMmioRegion::new(fault_address, Self::ADDRESS_ALIGNMENT)?)) + }) + .unwrap_or(false) + } +} diff --git a/security-monitor/src/confidential_flow/handlers/mmio/mmio_load_request.rs b/security-monitor/src/confidential_flow/handlers/mmio/mmio_load_request.rs index 960b145..5b7dac0 100644 --- a/security-monitor/src/confidential_flow/handlers/mmio/mmio_load_request.rs +++ b/security-monitor/src/confidential_flow/handlers/mmio/mmio_load_request.rs @@ -1,10 +1,11 @@ // SPDX-FileCopyrightText: 2023 IBM Corporation // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 -use crate::confidential_flow::handlers::mmio::MmioLoadPending; +use crate::confidential_flow::handlers::mmio::{MmioAccessFault, MmioLoadPending}; use crate::confidential_flow::handlers::sbi::SbiResponse; -use crate::confidential_flow::ConfidentialFlow; +use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow}; use crate::core::architecture::is_bit_enabled; +use crate::core::architecture::specification::CAUSE_LOAD_ACCESS; use crate::core::control_data::{ConfidentialHart, HypervisorHart, PendingRequest}; use crate::non_confidential_flow::DeclassifyToHypervisor; @@ -32,6 +33,12 @@ impl MmioLoadRequest { let instruction = self.mtinst | 0x3; let instruction_length = if is_bit_enabled(self.mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 }; + let fault_address = (self.mtval2 << 2) | (self.mtval & 0x3); + if !MmioAccessFault::tried_to_access_valid_mmio_region(confidential_flow.confidential_vm_id(), fault_address) { + let mmio_access_fault_handler = MmioAccessFault::new(CAUSE_LOAD_ACCESS.into(), self.mtval, instruction_length); + confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::MmioAccessFault(mmio_access_fault_handler)); + } + match crate::core::architecture::decode_result_register(instruction) { Ok(gpr) => confidential_flow .set_pending_request(PendingRequest::MmioLoad(MmioLoadPending::new(instruction_length, gpr))) diff --git a/security-monitor/src/confidential_flow/handlers/mmio/mmio_store_request.rs b/security-monitor/src/confidential_flow/handlers/mmio/mmio_store_request.rs index 8a5ad1c..766b7c3 100644 --- a/security-monitor/src/confidential_flow/handlers/mmio/mmio_store_request.rs +++ b/security-monitor/src/confidential_flow/handlers/mmio/mmio_store_request.rs @@ -1,9 +1,10 @@ // SPDX-FileCopyrightText: 2023 IBM Corporation // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 -use crate::confidential_flow::handlers::mmio::MmioStorePending; +use crate::confidential_flow::handlers::mmio::{MmioAccessFault, MmioStorePending}; use crate::confidential_flow::handlers::sbi::SbiResponse; -use crate::confidential_flow::ConfidentialFlow; +use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow}; +use crate::core::architecture::specification::CAUSE_STORE_ACCESS; use crate::core::architecture::{is_bit_enabled, GeneralPurposeRegister}; use crate::core::control_data::{ConfidentialHart, HypervisorHart, PendingRequest}; use crate::error::Error; @@ -33,10 +34,17 @@ impl MmioStoreRequest { let instruction_length = if is_bit_enabled(mtinst, 1) { riscv_decode::instruction_length(instruction as u16) } else { 2 }; let gpr = crate::core::architecture::decode_result_register(instruction); let gpr_value = gpr.as_ref().and_then(|ref gpr| Ok(confidential_hart.gprs().read(**gpr))).unwrap_or(0); + Self { mcause, mtval, mtval2, mtinst, instruction_length, gpr, gpr_value } } pub fn handle(self, confidential_flow: ConfidentialFlow) -> ! { + let fault_address = (self.mtval2 << 2) | (self.mtval & 0x3); + if !MmioAccessFault::tried_to_access_valid_mmio_region(confidential_flow.confidential_vm_id(), fault_address) { + let mmio_access_fault_handler = MmioAccessFault::new(CAUSE_STORE_ACCESS.into(), self.mtval, self.instruction_length); + confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::MmioAccessFault(mmio_access_fault_handler)); + } + match self.gpr { Ok(_) => confidential_flow .set_pending_request(PendingRequest::MmioStore(MmioStorePending::new(self.instruction_length))) diff --git a/security-monitor/src/confidential_flow/handlers/mmio/mod.rs b/security-monitor/src/confidential_flow/handlers/mmio/mod.rs index 6d21c6b..f047f61 100644 --- a/security-monitor/src/confidential_flow/handlers/mmio/mod.rs +++ b/security-monitor/src/confidential_flow/handlers/mmio/mod.rs @@ -2,6 +2,7 @@ // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 pub use crate::confidential_flow::handlers::mmio::add_mmio_region::AddMmioRegion; +pub use crate::confidential_flow::handlers::mmio::mmio_access_fault::MmioAccessFault; pub use crate::confidential_flow::handlers::mmio::mmio_load_pending::MmioLoadPending; pub use crate::confidential_flow::handlers::mmio::mmio_load_request::MmioLoadRequest; pub use crate::confidential_flow::handlers::mmio::mmio_load_response::MmioLoadResponse; @@ -11,6 +12,7 @@ pub use crate::confidential_flow::handlers::mmio::mmio_store_response::MmioStore pub use crate::confidential_flow::handlers::mmio::remove_mmio_region::RemoveMmioRegion; mod add_mmio_region; +mod mmio_access_fault; mod mmio_load_pending; mod mmio_load_request; mod mmio_load_response; diff --git a/security-monitor/src/confidential_flow/handlers/mmio/remove_mmio_region.rs b/security-monitor/src/confidential_flow/handlers/mmio/remove_mmio_region.rs index e3b8b43..bf227b1 100644 --- a/security-monitor/src/confidential_flow/handlers/mmio/remove_mmio_region.rs +++ b/security-monitor/src/confidential_flow/handlers/mmio/remove_mmio_region.rs @@ -1,10 +1,12 @@ // SPDX-FileCopyrightText: 2023 IBM Corporation // SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich // SPDX-License-Identifier: Apache-2.0 -use crate::confidential_flow::handlers::sbi::SbiResponse; +use crate::confidential_flow::handlers::sbi::{SbiRequest, SbiResponse}; use crate::confidential_flow::{ApplyToConfidentialHart, ConfidentialFlow}; +use crate::core::architecture::sbi::CovgExtension; use crate::core::architecture::GeneralPurposeRegister; -use crate::core::control_data::ConfidentialHart; +use crate::core::control_data::{ConfidentialHart, ConfidentialVmMmioRegion, ControlData, PendingRequest}; +use crate::non_confidential_flow::DeclassifyToHypervisor; pub struct RemoveMmioRegion { region_start_address: usize, @@ -20,7 +22,20 @@ impl RemoveMmioRegion { } pub fn handle(self, confidential_flow: ConfidentialFlow) -> ! { - let transformation = ApplyToConfidentialHart::SbiResponse(SbiResponse::success()); - confidential_flow.apply_and_exit_to_confidential_hart(transformation) + match ControlData::try_confidential_vm(confidential_flow.confidential_vm_id(), |mut confidential_vm| { + Ok(confidential_vm.remove_mmio_region(&ConfidentialVmMmioRegion::new(self.region_start_address, self.region_length)?)) + }) { + Ok(_) => confidential_flow + .set_pending_request(PendingRequest::SbiRequest()) + .into_non_confidential_flow() + .declassify_and_exit_to_hypervisor(DeclassifyToHypervisor::SbiRequest(self.sbi_remove_mmio_region())), + Err(error) => { + confidential_flow.apply_and_exit_to_confidential_hart(ApplyToConfidentialHart::SbiResponse(SbiResponse::error(error))) + } + } + } + + fn sbi_remove_mmio_region(&self) -> SbiRequest { + SbiRequest::new(CovgExtension::EXTID, CovgExtension::SBI_EXT_COVG_REMOVE_MMIO_REGION, self.region_start_address, self.region_length) } } diff --git a/security-monitor/src/core/control_data/confidential_vm.rs b/security-monitor/src/core/control_data/confidential_vm.rs index 56a3a97..132d22e 100644 --- a/security-monitor/src/core/control_data/confidential_vm.rs +++ b/security-monitor/src/core/control_data/confidential_vm.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::core::architecture::HartLifecycleState; use crate::core::control_data::{ - ConfidentialHart, ConfidentialHartRemoteCommand, ConfidentialVmId, ConfidentialVmMeasurement, HardwareHart, + ConfidentialHart, ConfidentialHartRemoteCommand, ConfidentialVmId, ConfidentialVmMeasurement, ConfidentialVmMmioRegion, HardwareHart, }; use crate::core::interrupt_controller::InterruptController; use crate::core::memory_protector::ConfidentialVmMemoryProtector; @@ -19,15 +19,21 @@ pub struct ConfidentialVm { confidential_hart_remote_commands: BTreeMap>>, memory_protector: ConfidentialVmMemoryProtector, allowed_external_interrupts: usize, + mmio_regions: Vec, } impl ConfidentialVm { pub const MAX_NUMBER_OF_HARTS_PER_VM: usize = 1024; + /// An average number of inter hart requests that can be buffered before being processed. const AVG_NUMBER_OF_REMOTE_HART_REQUESTS: usize = 3; + /// A maximum number of inter hart requests that can be buffered. const MAX_NUMBER_OF_REMOTE_HART_REQUESTS: usize = 64; + /// A maximum number of MMIO regions that a confidential VM can register + const MAX_NUMBER_OF_MMIO_REGIONS: usize = 1024; + /// Constructs a new confidential VM. /// /// # Safety @@ -45,9 +51,33 @@ impl ConfidentialVm { (confidential_hart.confidential_hart_id(), Mutex::new(Vec::with_capacity(Self::AVG_NUMBER_OF_REMOTE_HART_REQUESTS))) }) .collect(); - Self { id, measurements, confidential_harts, memory_protector, confidential_hart_remote_commands, allowed_external_interrupts: 0 } + let mmio_regions = Vec::with_capacity(8); + Self { + id, + measurements, + confidential_harts, + memory_protector, + confidential_hart_remote_commands, + allowed_external_interrupts: 0, + mmio_regions, + } + } + + pub fn confidential_vm_id(&self) -> ConfidentialVmId { + self.id + } + + pub fn memory_protector_mut(&mut self) -> &mut ConfidentialVmMemoryProtector { + &mut self.memory_protector } + pub(super) fn deallocate(self) { + self.memory_protector.into_root_page_table().deallocate(); + } +} + +/* Heavy context switches */ +impl ConfidentialVm { /// Assigns a confidential hart of the confidential VM to the hardware hart. The hardware memory isolation mechanism /// is reconfigured to enforce memory access control for the confidential VM. Returns error if the confidential VM's /// virtual hart has been already stolen or is in the `Stopped` state. @@ -111,15 +141,10 @@ impl ConfidentialVm { // finite state machine to the non-confidential part and the virtual hart is still assigned to the hardware hart. unsafe { hardware_hart.hypervisor_hart().enable_hypervisor_memory_protector() }; } +} - pub fn confidential_vm_id(&self) -> ConfidentialVmId { - self.id - } - - pub fn memory_protector_mut(&mut self) -> &mut ConfidentialVmMemoryProtector { - &mut self.memory_protector - } - +/* Interrupt related */ +impl ConfidentialVm { pub fn allowed_external_interrupts(&self) -> usize { self.allowed_external_interrupts } @@ -127,7 +152,28 @@ impl ConfidentialVm { pub fn set_allowed_external_interrupts(&mut self, allowed_external_interrupts: usize) { self.allowed_external_interrupts |= allowed_external_interrupts; } +} + +/* Management of untrusted MMIO regions */ +impl ConfidentialVm { + pub fn add_mmio_region(&mut self, region: ConfidentialVmMmioRegion) -> Result<(), Error> { + ensure!(self.mmio_regions.len() < Self::MAX_NUMBER_OF_MMIO_REGIONS, Error::ReachedMaxNumberOfMmioRegions())?; + ensure!(!self.mmio_regions.iter().any(|x| x.overlaps(®ion)), Error::OverlappingMmioRegion())?; + self.mmio_regions.push(region); + Ok(()) + } + + pub fn remove_mmio_region(&mut self, region: &ConfidentialVmMmioRegion) { + self.mmio_regions.retain(|x| !x.overlaps(region)); + } + + pub fn is_mmio_region_defined(&self, region: &ConfidentialVmMmioRegion) -> bool { + self.mmio_regions.iter().any(|x| x.contains(region)) + } +} +/* Lifecycle related */ +impl ConfidentialVm { pub fn are_all_harts_shutdown(&self) -> bool { self.confidential_harts.iter().filter(|hart| hart.lifecycle_state() != &HartLifecycleState::PoweredOff).count() == 0 } @@ -144,7 +190,10 @@ impl ConfidentialVm { let hart = self.confidential_harts.get_mut(confidential_hart_id).ok_or(Error::InvalidHartId())?; hart.transition_from_stopped_to_started(start_address, opaque) } +} +/* Remote commands */ +impl ConfidentialVm { /// Queues a request from one confidential hart to another and emits a hardware interrupt to the physical hart that /// executes that confidential hart. If the confidential hart is not executing, then no hardware interrupt is /// emmited. @@ -184,10 +233,6 @@ impl ConfidentialVm { }) } - pub(super) fn deallocate(self) { - self.memory_protector.into_root_page_table().deallocate(); - } - pub fn try_confidential_hart_remote_commands(&mut self, confidential_hart_id: usize, op: O) -> Result where O: FnOnce(MutexGuard<'_, Vec>) -> Result { op(self.confidential_hart_remote_commands.get(&confidential_hart_id).ok_or(Error::InvalidHartId())?.lock()) diff --git a/security-monitor/src/core/control_data/confidential_vm_mmio_region.rs b/security-monitor/src/core/control_data/confidential_vm_mmio_region.rs new file mode 100644 index 0000000..0a71f39 --- /dev/null +++ b/security-monitor/src/core/control_data/confidential_vm_mmio_region.rs @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2023 IBM Corporation +// SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich +// SPDX-License-Identifier: Apache-2.0 +use crate::error::Error; + +#[derive(Debug)] +pub struct ConfidentialVmMmioRegion { + pub region_start_address: usize, + pub region_length: usize, +} + +impl ConfidentialVmMmioRegion { + pub fn new(region_start_address: usize, region_length: usize) -> Result { + // TODO: make sure region_start_address is aligned to 4KiB + // TODO: make sure the region_start_address is a valid guest address + Ok(Self { region_start_address, region_length }) + } + + pub fn overlaps(&self, other: &Self) -> bool { + self.region_start_address < other.region_start_address + other.region_length + && other.region_start_address < self.region_start_address + self.region_length + } + + pub fn contains(&self, other: &Self) -> bool { + self.region_start_address <= other.region_start_address + && other.region_start_address + other.region_length < self.region_start_address + self.region_length + } +} diff --git a/security-monitor/src/core/control_data/mod.rs b/security-monitor/src/core/control_data/mod.rs index 4b134aa..b4cd0ff 100644 --- a/security-monitor/src/core/control_data/mod.rs +++ b/security-monitor/src/core/control_data/mod.rs @@ -6,6 +6,7 @@ pub use confidential_hart_remote_command::{ConfidentialHartRemoteCommand, Confid pub use confidential_vm::ConfidentialVm; pub use confidential_vm_id::ConfidentialVmId; pub use confidential_vm_measurement::ConfidentialVmMeasurement; +pub use confidential_vm_mmio_region::ConfidentialVmMmioRegion; pub use hardware_hart::{HardwareHart, HART_STACK_ADDRESS_OFFSET}; pub use hypervisor_hart::HypervisorHart; pub use pending_request::PendingRequest; @@ -16,6 +17,7 @@ mod confidential_hart_remote_command; mod confidential_vm; mod confidential_vm_id; mod confidential_vm_measurement; +mod confidential_vm_mmio_region; mod hardware_hart; mod hypervisor_hart; mod pending_request; diff --git a/security-monitor/src/error.rs b/security-monitor/src/error.rs index 4e26f42..3927b78 100644 --- a/security-monitor/src/error.rs +++ b/security-monitor/src/error.rs @@ -69,6 +69,8 @@ pub enum Error { InvalidCall(usize, usize), #[error("Device Tree Error")] DeviceTreeError(#[from] flattened_device_tree::FdtError), + #[error("Mmio region overlaps with a region already defined in the past")] + OverlappingMmioRegion(), /* SBI HSM extension-related errors */ #[error("Cannot start a confidential hart because it is not in the Stopped state.")] @@ -95,6 +97,8 @@ pub enum Error { PendingRequest(), #[error("Reached max number of remote hart requests")] ReachedMaxNumberOfRemoteHartRequests(), + #[error("Reached max number of registered MMIO regions")] + ReachedMaxNumberOfMmioRegions(), #[error("Could not send an IPI, error code: {0}")] InterruptSendingError(usize), }