Merge "Use soong variable avf_remote_attestation_enabled to enable RA" into main
diff --git a/libs/cborutil/src/lib.rs b/libs/cborutil/src/lib.rs
index 4d308c1..b218c82 100644
--- a/libs/cborutil/src/lib.rs
+++ b/libs/cborutil/src/lib.rs
@@ -21,7 +21,10 @@
use alloc::string::String;
use alloc::vec::Vec;
use ciborium::value::{Integer, Value};
-use coset::{CborSerializable, CoseError, CoseKey, Label, Result};
+use coset::{
+ iana::{self, EnumI64},
+ CborSerializable, CoseError, CoseKey, Label, Result,
+};
use log::error;
use serde::{de::DeserializeOwned, Serialize};
@@ -132,3 +135,19 @@
.ok_or(CoseError::UnexpectedItem("", "Label not found in CoseKey"))?
.1)
}
+
+/// Converts the provided COSE key algorithm integer to an `iana::Algorithm` used
+/// by DICE chains.
+pub fn dice_cose_key_alg(cose_key_alg: i32) -> Result<iana::Algorithm> {
+ let key_alg = iana::Algorithm::from_i64(cose_key_alg as i64).ok_or_else(|| {
+ error!("Unsupported COSE key algorithm for DICE: {cose_key_alg}");
+ CoseError::UnexpectedItem("COSE key algorithm", "")
+ })?;
+ match key_alg {
+ iana::Algorithm::EdDSA | iana::Algorithm::ES256 | iana::Algorithm::ES384 => Ok(key_alg),
+ _ => {
+ error!("Unsupported COSE key algorithm for DICE: {key_alg:?}");
+ Err(CoseError::UnexpectedItem("-8, -7 or -35", ""))
+ }
+ }
+}
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index ab3220e..4904672 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -161,6 +161,7 @@
"--allowlist-var=DICE_PUBLIC_KEY_SIZE",
"--allowlist-var=DICE_PRIVATE_KEY_SIZE",
"--allowlist-var=DICE_SIGNATURE_SIZE",
+ "--allowlist-var=DICE_COSE_KEY_ALG_VALUE",
],
}
diff --git a/libs/dice/open_dice/src/lib.rs b/libs/dice/open_dice/src/lib.rs
index d0004b1..085a2cd 100644
--- a/libs/dice/open_dice/src/lib.rs
+++ b/libs/dice/open_dice/src/lib.rs
@@ -40,6 +40,10 @@
PublicKey, Signature, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
};
pub use error::{DiceError, Result};
+// Currently, open-dice library only supports a single signing and verification algorithm.
+// The value of DICE_COSE_KEY_ALG_VALUE depends on the algorithm chosen by the underlying C
+// library at build time. Refer to b/342333212 for more information.
+pub use open_dice_cbor_bindgen::DICE_COSE_KEY_ALG_VALUE;
pub use ops::{
derive_cdi_leaf_priv, generate_certificate, hash, kdf, keypair_from_seed, sign, verify,
};
diff --git a/libs/hyp/Android.bp b/libs/hyp/Android.bp
deleted file mode 100644
index 404269a..0000000
--- a/libs/hyp/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_library_rlib {
- name: "libhyp",
- crate_name: "hyp",
- defaults: ["avf_build_flags_rust"],
- srcs: ["src/lib.rs"],
- prefer_rlib: true,
- rustlibs: [
- "libonce_cell_nostd",
- "libsmccc",
- "libuuid_nostd",
- ],
- no_stdlibs: true,
- stdlibs: [
- "libcore.rust_sysroot",
- ],
- enabled: false,
- target: {
- android_arm64: {
- enabled: true,
- },
- },
- apex_available: ["com.android.virt"],
-}
diff --git a/libs/hyp/src/util.rs b/libs/hyp/src/util.rs
deleted file mode 100644
index 56f94fd..0000000
--- a/libs/hyp/src/util.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2023, The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! Utility functions.
-
-pub(crate) const SIZE_4KB: usize = 4 << 10;
-
-/// Computes the low memory page address of the 4KiB page containing a given address.
-pub(crate) fn page_address(addr: usize) -> u64 {
- (addr & !(SIZE_4KB - 1)).try_into().unwrap()
-}
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 4ee02c1..37a321d 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -19,7 +19,6 @@
"libcstr",
"libdiced_open_dice_nostd",
"libfdtpci",
- "libhyp",
"liblibfdt",
"liblog_rust_nostd",
"libonce_cell_nostd",
@@ -75,7 +74,6 @@
defaults: ["libpvmfw.test.defaults"],
rustlibs: [
"libdts",
- "libhyp",
"liblibfdt",
"liblog_rust",
"libpvmfw_fdt_template",
diff --git a/pvmfw/platform.dts b/pvmfw/platform.dts
index 92ab19c..68acf13 100644
--- a/pvmfw/platform.dts
+++ b/pvmfw/platform.dts
@@ -8,6 +8,42 @@
#define PLACEHOLDER2 PLACEHOLDER PLACEHOLDER
#define PLACEHOLDER4 PLACEHOLDER2 PLACEHOLDER2
+#define PLACEHOLDER_CPU_MAP_CORE(n) core##n { cpu = <PLACEHOLDER>; };
+#define PLACEHOLDER_CPU_MAP_CLUSTER \
+ PLACEHOLDER_CPU_MAP_CORE(0) \
+ PLACEHOLDER_CPU_MAP_CORE(1) \
+ PLACEHOLDER_CPU_MAP_CORE(2) \
+ PLACEHOLDER_CPU_MAP_CORE(3) \
+ PLACEHOLDER_CPU_MAP_CORE(4) \
+ PLACEHOLDER_CPU_MAP_CORE(5) \
+ PLACEHOLDER_CPU_MAP_CORE(6) \
+ PLACEHOLDER_CPU_MAP_CORE(7) \
+ PLACEHOLDER_CPU_MAP_CORE(8) \
+ PLACEHOLDER_CPU_MAP_CORE(9)
+
+#define PLACEHOLDER_OPP_TABLE_ENTRY(n) opp##n { opp-hz = <PLACEHOLDER2>; };
+#define PLACEHOLDER_OPP_TABLE \
+ PLACEHOLDER_OPP_TABLE_ENTRY(1) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(2) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(3) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(4) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(5) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(6) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(7) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(8) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(9) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(10) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(11) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(12) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(13) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(14) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(15) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(16) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(17) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(18) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(19) \
+ PLACEHOLDER_OPP_TABLE_ENTRY(20)
+
#define IRQ_BASE 4
/dts-v1/;
@@ -54,42 +90,9 @@
#size-cells = <0>;
cpu-map {
- cluster0 {
- core0 { cpu = <PLACEHOLDER>; };
- core1 { cpu = <PLACEHOLDER>; };
- core2 { cpu = <PLACEHOLDER>; };
- core3 { cpu = <PLACEHOLDER>; };
- core4 { cpu = <PLACEHOLDER>; };
- core5 { cpu = <PLACEHOLDER>; };
- core6 { cpu = <PLACEHOLDER>; };
- core7 { cpu = <PLACEHOLDER>; };
- core8 { cpu = <PLACEHOLDER>; };
- core9 { cpu = <PLACEHOLDER>; };
- };
- cluster1 {
- core0 { cpu = <PLACEHOLDER>; };
- core1 { cpu = <PLACEHOLDER>; };
- core2 { cpu = <PLACEHOLDER>; };
- core3 { cpu = <PLACEHOLDER>; };
- core4 { cpu = <PLACEHOLDER>; };
- core5 { cpu = <PLACEHOLDER>; };
- core6 { cpu = <PLACEHOLDER>; };
- core7 { cpu = <PLACEHOLDER>; };
- core8 { cpu = <PLACEHOLDER>; };
- core9 { cpu = <PLACEHOLDER>; };
- };
- cluster2 {
- core0 { cpu = <PLACEHOLDER>; };
- core1 { cpu = <PLACEHOLDER>; };
- core2 { cpu = <PLACEHOLDER>; };
- core3 { cpu = <PLACEHOLDER>; };
- core4 { cpu = <PLACEHOLDER>; };
- core5 { cpu = <PLACEHOLDER>; };
- core6 { cpu = <PLACEHOLDER>; };
- core7 { cpu = <PLACEHOLDER>; };
- core8 { cpu = <PLACEHOLDER>; };
- core9 { cpu = <PLACEHOLDER>; };
- };
+ cluster0 { PLACEHOLDER_CPU_MAP_CLUSTER };
+ cluster1 { PLACEHOLDER_CPU_MAP_CLUSTER };
+ cluster2 { PLACEHOLDER_CPU_MAP_CLUSTER };
};
cpu0: cpu@0 {
@@ -101,27 +104,7 @@
operating-points-v2 = <&opp_table0>;
opp_table0: opp-table-0 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu1: cpu@1 {
@@ -133,27 +116,7 @@
operating-points-v2 = <&opp_table1>;
opp_table1: opp-table-1 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu2: cpu@2 {
@@ -165,27 +128,7 @@
operating-points-v2 = <&opp_table2>;
opp_table2: opp-table-2 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu3: cpu@3 {
@@ -197,27 +140,7 @@
operating-points-v2 = <&opp_table3>;
opp_table3: opp-table-3 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu4: cpu@4 {
@@ -229,27 +152,7 @@
operating-points-v2 = <&opp_table4>;
opp_table4: opp-table-4 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu5: cpu@5 {
@@ -261,27 +164,7 @@
operating-points-v2 = <&opp_table5>;
opp_table5: opp-table-5 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu6: cpu@6 {
@@ -293,27 +176,7 @@
operating-points-v2 = <&opp_table6>;
opp_table6: opp-table-6 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu7: cpu@7 {
@@ -325,27 +188,7 @@
operating-points-v2 = <&opp_table7>;
opp_table7: opp-table-7 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu8: cpu@8 {
@@ -357,27 +200,7 @@
operating-points-v2 = <&opp_table8>;
opp_table8: opp-table-8 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu9: cpu@9 {
@@ -389,27 +212,7 @@
operating-points-v2 = <&opp_table9>;
opp_table9: opp-table-9 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu10: cpu@a {
@@ -421,27 +224,7 @@
operating-points-v2 = <&opp_table10>;
opp_table10: opp-table-10 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu11: cpu@b {
@@ -453,27 +236,7 @@
operating-points-v2 = <&opp_table11>;
opp_table11: opp-table-11 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu12: cpu@c {
@@ -485,27 +248,7 @@
operating-points-v2 = <&opp_table12>;
opp_table12: opp-table-12 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu13: cpu@d {
@@ -517,27 +260,7 @@
operating-points-v2 = <&opp_table13>;
opp_table13: opp-table-13 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu14: cpu@e {
@@ -549,27 +272,7 @@
operating-points-v2 = <&opp_table14>;
opp_table14: opp-table-14 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
cpu15: cpu@f {
@@ -581,27 +284,7 @@
operating-points-v2 = <&opp_table15>;
opp_table15: opp-table-15 {
compatible = "operating-points-v2";
-
- opp1 { opp-hz = <PLACEHOLDER2>; };
- opp2 { opp-hz = <PLACEHOLDER2>; };
- opp3 { opp-hz = <PLACEHOLDER2>; };
- opp4 { opp-hz = <PLACEHOLDER2>; };
- opp5 { opp-hz = <PLACEHOLDER2>; };
- opp6 { opp-hz = <PLACEHOLDER2>; };
- opp7 { opp-hz = <PLACEHOLDER2>; };
- opp8 { opp-hz = <PLACEHOLDER2>; };
- opp9 { opp-hz = <PLACEHOLDER2>; };
- opp10 { opp-hz = <PLACEHOLDER2>; };
- opp11 { opp-hz = <PLACEHOLDER2>; };
- opp12 { opp-hz = <PLACEHOLDER2>; };
- opp13 { opp-hz = <PLACEHOLDER2>; };
- opp14 { opp-hz = <PLACEHOLDER2>; };
- opp15 { opp-hz = <PLACEHOLDER2>; };
- opp16 { opp-hz = <PLACEHOLDER2>; };
- opp17 { opp-hz = <PLACEHOLDER2>; };
- opp18 { opp-hz = <PLACEHOLDER2>; };
- opp19 { opp-hz = <PLACEHOLDER2>; };
- opp20 { opp-hz = <PLACEHOLDER2>; };
+ PLACEHOLDER_OPP_TABLE
};
};
};
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index 885cd22..5edfe97 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -28,9 +28,11 @@
use core::iter::Iterator;
use core::mem;
use core::ops::Range;
-use hyp::DeviceAssigningHypervisor;
use libfdt::{Fdt, FdtError, FdtNode, FdtNodeMut, Phandle, Reg};
use log::error;
+// TODO(b/308694211): Use vmbase::hyp::{DeviceAssigningHypervisor, Error} proper for tests.
+#[cfg(not(test))]
+use vmbase::hyp::DeviceAssigningHypervisor;
use zerocopy::byteorder::big_endian::U32;
use zerocopy::FromBytes as _;
@@ -936,6 +938,18 @@
Ok(())
}
+ // TODO(b/308694211): Remove this workaround for visibility once using
+ // vmbase::hyp::DeviceAssigningHypervisor for tests.
+ #[cfg(test)]
+ fn parse(
+ fdt: &Fdt,
+ vm_dtbo: &VmDtbo,
+ hypervisor: &dyn DeviceAssigningHypervisor,
+ ) -> Result<Option<Self>> {
+ Self::internal_parse(fdt, vm_dtbo, hypervisor)
+ }
+
+ #[cfg(not(test))]
/// Parses fdt and vm_dtbo, and creates new DeviceAssignmentInfo
// TODO(b/277993056): Parse __local_fixups__
// TODO(b/277993056): Parse __fixups__
@@ -944,6 +958,14 @@
vm_dtbo: &VmDtbo,
hypervisor: &dyn DeviceAssigningHypervisor,
) -> Result<Option<Self>> {
+ Self::internal_parse(fdt, vm_dtbo, hypervisor)
+ }
+
+ fn internal_parse(
+ fdt: &Fdt,
+ vm_dtbo: &VmDtbo,
+ hypervisor: &dyn DeviceAssigningHypervisor,
+ ) -> Result<Option<Self>> {
let Some(symbols_node) = vm_dtbo.as_ref().symbols()? else {
// /__symbols__ should contain all assignable devices.
// If empty, then nothing can be assigned.
@@ -1061,6 +1083,39 @@
}
#[cfg(test)]
+#[derive(Clone, Copy, Debug)]
+enum MockHypervisorError {
+ FailedGetPhysMmioToken,
+ FailedGetPhysIommuToken,
+}
+
+#[cfg(test)]
+type MockHypervisorResult<T> = core::result::Result<T, MockHypervisorError>;
+
+#[cfg(test)]
+impl fmt::Display for MockHypervisorError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ MockHypervisorError::FailedGetPhysMmioToken => {
+ write!(f, "Failed to get physical MMIO token")
+ }
+ MockHypervisorError::FailedGetPhysIommuToken => {
+ write!(f, "Failed to get physical IOMMU token")
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+trait DeviceAssigningHypervisor {
+ /// Returns MMIO token.
+ fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> MockHypervisorResult<u64>;
+
+ /// Returns DMA token as a tuple of (phys_iommu_id, phys_sid).
+ fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> MockHypervisorResult<(u64, u64)>;
+}
+
+#[cfg(test)]
mod tests {
use super::*;
use alloc::collections::{BTreeMap, BTreeSet};
@@ -1105,18 +1160,20 @@
}
impl DeviceAssigningHypervisor for MockHypervisor {
- fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> hyp::Result<u64> {
- Ok(*self.mmio_tokens.get(&(base_ipa, size)).ok_or(hyp::Error::KvmError(
- hyp::KvmError::InvalidParameter,
- 0xc6000012, /* VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID */
- ))?)
+ fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> MockHypervisorResult<u64> {
+ let token = self.mmio_tokens.get(&(base_ipa, size));
+
+ Ok(*token.ok_or(MockHypervisorError::FailedGetPhysMmioToken)?)
}
- fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> hyp::Result<(u64, u64)> {
- Ok(*self.iommu_tokens.get(&(pviommu_id, vsid)).ok_or(hyp::Error::KvmError(
- hyp::KvmError::InvalidParameter,
- 0xc6000013, /* VENDOR_HYP_KVM_DEV_REQ_DMA_FUNC_ID */
- ))?)
+ fn get_phys_iommu_token(
+ &self,
+ pviommu_id: u64,
+ vsid: u64,
+ ) -> MockHypervisorResult<(u64, u64)> {
+ let token = self.iommu_tokens.get(&(pviommu_id, vsid));
+
+ Ok(*token.ok_or(MockHypervisorError::FailedGetPhysIommuToken)?)
}
}
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 72212c3..43822a5 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -23,7 +23,6 @@
use core::num::NonZeroUsize;
use core::ops::Range;
use core::slice;
-use hyp::{get_mem_sharer, get_mmio_guard};
use log::debug;
use log::error;
use log::info;
@@ -32,6 +31,7 @@
use vmbase::util::RangeExt as _;
use vmbase::{
configure_heap, console,
+ hyp::{get_mem_sharer, get_mmio_guard},
layout::{self, crosvm},
main,
memory::{min_dcache_line_size, MemoryTracker, MEMORY, SIZE_128KB, SIZE_4KB},
@@ -249,7 +249,7 @@
config_entries.bcc.zeroize();
info!("Expecting a bug making MMIO_GUARD_UNMAP return NOT_SUPPORTED on success");
- MEMORY.lock().as_mut().unwrap().mmio_unmap_all().map_err(|e| {
+ MEMORY.lock().as_mut().unwrap().unshare_all_mmio().map_err(|e| {
error!("Failed to unshare MMIO ranges: {e}");
RebootReason::InternalError
})?;
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 6038f12..9206588 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -46,6 +46,7 @@
use static_assertions::const_assert;
use tinyvec::ArrayVec;
use vmbase::fdt::SwiotlbInfo;
+use vmbase::hyp;
use vmbase::layout::{crosvm::MEM_START, MAX_VIRT_ADDR};
use vmbase::memory::SIZE_4KB;
use vmbase::util::flatten;
diff --git a/rialto/Android.bp b/rialto/Android.bp
index d7aac35..33fe189 100644
--- a/rialto/Android.bp
+++ b/rialto/Android.bp
@@ -15,7 +15,6 @@
"libciborium_nostd",
"libcstr",
"libdiced_open_dice_nostd",
- "libhyp",
"libfdtpci",
"liblibfdt",
"liblog_rust_nostd",
diff --git a/rialto/src/error.rs b/rialto/src/error.rs
index d2bdbbe..033159b 100644
--- a/rialto/src/error.rs
+++ b/rialto/src/error.rs
@@ -18,10 +18,9 @@
use core::{fmt, result};
use diced_open_dice::DiceError;
use fdtpci::PciError;
-use hyp::Error as HypervisorError;
use libfdt::FdtError;
use service_vm_comm::RequestProcessingError;
-use vmbase::{memory::MemoryTrackerError, virtio::pci};
+use vmbase::{hyp::Error as HypervisorError, memory::MemoryTrackerError, virtio::pci};
pub type Result<T> = result::Result<T, Error>;
diff --git a/rialto/src/main.rs b/rialto/src/main.rs
index 11e67cb..864f5e4 100644
--- a/rialto/src/main.rs
+++ b/rialto/src/main.rs
@@ -34,7 +34,6 @@
use core::slice;
use diced_open_dice::{bcc_handover_parse, DiceArtifacts};
use fdtpci::PciInfo;
-use hyp::{get_mem_sharer, get_mmio_guard};
use libfdt::FdtError;
use log::{debug, error, info};
use service_vm_comm::{ServiceVmRequest, VmType};
@@ -48,6 +47,7 @@
use vmbase::{
configure_heap,
fdt::SwiotlbInfo,
+ hyp::{get_mem_sharer, get_mmio_guard},
layout::{self, crosvm},
main,
memory::{MemoryTracker, PageTable, MEMORY, PAGE_SIZE, SIZE_128KB},
diff --git a/service_vm/client_vm_csr/Android.bp b/service_vm/client_vm_csr/Android.bp
index 8d738d8..097779f 100644
--- a/service_vm/client_vm_csr/Android.bp
+++ b/service_vm/client_vm_csr/Android.bp
@@ -8,6 +8,7 @@
srcs: ["src/lib.rs"],
rustlibs: [
"libanyhow",
+ "libcbor_util",
"libcoset",
"libdiced_open_dice",
"libopenssl",
diff --git a/service_vm/client_vm_csr/src/lib.rs b/service_vm/client_vm_csr/src/lib.rs
index 0babfff..70152cb 100644
--- a/service_vm/client_vm_csr/src/lib.rs
+++ b/service_vm/client_vm_csr/src/lib.rs
@@ -20,7 +20,9 @@
iana, CborSerializable, CoseKey, CoseKeyBuilder, CoseSign, CoseSignBuilder, CoseSignature,
CoseSignatureBuilder, HeaderBuilder,
};
-use diced_open_dice::{derive_cdi_leaf_priv, sign, DiceArtifacts, PrivateKey};
+use diced_open_dice::{
+ derive_cdi_leaf_priv, sign, DiceArtifacts, PrivateKey, DICE_COSE_KEY_ALG_VALUE,
+};
use openssl::{
bn::{BigNum, BigNumContext},
ec::{EcGroup, EcKey, EcKeyRef},
@@ -91,7 +93,8 @@
cdi_leaf_priv: &PrivateKey,
attestation_key: &EcKeyRef<Private>,
) -> Result<CoseSign> {
- let cdi_leaf_sig_headers = build_signature_headers(iana::Algorithm::EdDSA);
+ let dice_key_alg = cbor_util::dice_cose_key_alg(DICE_COSE_KEY_ALG_VALUE)?;
+ let cdi_leaf_sig_headers = build_signature_headers(dice_key_alg);
let attestation_key_sig_headers = build_signature_headers(ATTESTATION_KEY_ALGO);
let aad = &[];
let signed_data = CoseSignBuilder::new()
diff --git a/service_vm/comm/src/client_vm_csr.cddl b/service_vm/comm/src/client_vm_csr.cddl
index bbc709a..7ddbfa3 100644
--- a/service_vm/comm/src/client_vm_csr.cddl
+++ b/service_vm/comm/src/client_vm_csr.cddl
@@ -33,9 +33,10 @@
; COSE_Signature [RFC9052 s4.1]
COSE_Signature_Dice_Cdi_Leaf = [
- protected: bstr .cbor { 1: AlgorithmEdDSA },
+ protected: bstr .cbor { 1: AlgorithmEdDSA / AlgorithmES256 / AlgorithmES384 },
unprotected: {},
- signature: bstr, ; Ed25519(CDI_Leaf_Priv, SigStruct)
+ signature: bstr, ; PureEd25519(CDI_Leaf_Priv, SigStruct)
+ ; ECDSA(CDI_Leaf_Priv, SigStruct)
]
; COSE_Signature [RFC9052 s4.1]
diff --git a/service_vm/requests/src/rkp.rs b/service_vm/requests/src/rkp.rs
index 4f2262f..aa363e5 100644
--- a/service_vm/requests/src/rkp.rs
+++ b/service_vm/requests/src/rkp.rs
@@ -26,8 +26,10 @@
value::{CanonicalValue, Value},
};
use core::result;
-use coset::{iana, AsCborValue, CoseSign1, CoseSign1Builder, HeaderBuilder};
-use diced_open_dice::{derive_cdi_leaf_priv, kdf, sign, DiceArtifacts, PrivateKey};
+use coset::{AsCborValue, CoseSign1, CoseSign1Builder, HeaderBuilder};
+use diced_open_dice::{
+ derive_cdi_leaf_priv, kdf, sign, DiceArtifacts, PrivateKey, DICE_COSE_KEY_ALG_VALUE,
+};
use log::{debug, error};
use service_vm_comm::{EcdsaP256KeyPair, GenerateCertificateRequestParams, RequestProcessingError};
use zeroize::Zeroizing;
@@ -151,8 +153,8 @@
error!("Failed to derive the CDI_Leaf_Priv: {e}");
RequestProcessingError::InternalError
})?;
- let signing_algorithm = iana::Algorithm::EdDSA;
- let protected = HeaderBuilder::new().algorithm(signing_algorithm).build();
+ let dice_key_alg = cbor_util::dice_cose_key_alg(DICE_COSE_KEY_ALG_VALUE)?;
+ let protected = HeaderBuilder::new().algorithm(dice_key_alg).build();
let signed_data = CoseSign1Builder::new()
.protected(protected)
.payload(cbor_util::serialize(payload)?)
diff --git a/tests/helper/src/java/com/android/microdroid/test/common/DeviceProperties.java b/tests/helper/src/java/com/android/microdroid/test/common/DeviceProperties.java
index 2ea748b..69527be 100644
--- a/tests/helper/src/java/com/android/microdroid/test/common/DeviceProperties.java
+++ b/tests/helper/src/java/com/android/microdroid/test/common/DeviceProperties.java
@@ -32,6 +32,7 @@
private static final String KEY_METRICS_TAG = "debug.hypervisor.metrics_tag";
private static final String CUTTLEFISH_DEVICE_PREFIX = "vsoc_";
+ private static final String CUTTLEFISH_ARM64_DEVICE_PREFIX = "vsoc_arm64";
private static final String USER_BUILD_TYPE = "user";
private static final String HWASAN_SUFFIX = "_hwasan";
@@ -55,6 +56,15 @@
}
/**
+ * @return whether the device is a cuttlefish device running on 64 bit Arm.
+ */
+ public boolean isCuttlefishArm64() {
+ String vendorDeviceName = getProperty(KEY_VENDOR_DEVICE);
+ return vendorDeviceName != null
+ && vendorDeviceName.startsWith(CUTTLEFISH_ARM64_DEVICE_PREFIX);
+ }
+
+ /**
* @return whether the build is HWASAN.
*/
public boolean isHwasan() {
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index b2a77a7..6040531 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -75,6 +75,10 @@
return getDeviceProperties().isCuttlefish();
}
+ private static boolean isCuttlefishArm64() {
+ return getDeviceProperties().isCuttlefishArm64();
+ }
+
public static boolean isHwasan() {
return getDeviceProperties().isHwasan();
}
@@ -207,17 +211,27 @@
assume().withMessage("Device doesn't support AVF")
.that(mCtx.getPackageManager().hasSystemFeature(FEATURE_VIRTUALIZATION_FRAMEWORK))
.isTrue();
- int vendorApiLevel = SystemProperties.getInt("ro.vendor.api_level", 0);
+ int vendorApiLevel = getVendorApiLevel();
boolean isGsi = new File("/system/system_ext/etc/init/init.gsi.rc").exists();
assume().withMessage("GSI with vendor API level < 202404 may not support AVF")
.that(isGsi && vendorApiLevel < 202404)
.isFalse();
}
+ protected static int getVendorApiLevel() {
+ return SystemProperties.getInt("ro.vendor.api_level", 0);
+ }
+
protected void assumeSupportedDevice() {
assume().withMessage("Skip on 5.4 kernel. b/218303240")
.that(KERNEL_VERSION)
.isNotEqualTo("5.4");
+
+ // Cuttlefish on Arm 64 doesn't and cannot support any form of virtualization, so there's
+ // no point running any of these tests.
+ assume().withMessage("Virtualization not supported on Arm64 Cuttlefish. b/341889915")
+ .that(isCuttlefishArm64())
+ .isFalse();
}
protected void assumeNoUpdatableVmSupport() throws VirtualMachineException {
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
index c50e59a..3b755a0 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
@@ -20,14 +20,12 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.TruthJUnit.assume;
-import android.os.SystemProperties;
import android.system.virtualmachine.VirtualMachineManager;
import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.VsrTest;
import com.android.microdroid.test.device.MicrodroidDeviceTestBase;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -65,9 +63,8 @@
@Test
@VsrTest(requirements = "VSR-7.1-001.005")
public void avfIsRequired() {
- int vendorApiLevel = SystemProperties.getInt("ro.vendor.api_level", 0);
assume().withMessage("Requirement doesn't apply due to vendor API level")
- .that(vendorApiLevel)
+ .that(getVendorApiLevel())
.isAtLeast(202404);
boolean avfSupported =
getContext().getPackageManager().hasSystemFeature(FEATURE_VIRTUALIZATION_FRAMEWORK);
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 6308072..4ffef3c 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -1285,17 +1285,20 @@
assertThat(dataItems.size()).isEqualTo(1);
assertThat(dataItems.get(0).getMajorType()).isEqualTo(MajorType.ARRAY);
List<DataItem> rootArrayItems = ((Array) dataItems.get(0)).getDataItems();
- assertThat(rootArrayItems.size()).isAtLeast(2); // Root public key and one certificate
+ int diceChainSize = rootArrayItems.size();
+ assertThat(diceChainSize).isAtLeast(2); // Root public key and one certificate
if (mProtectedVm) {
if (isFeatureEnabled(VirtualMachineManager.FEATURE_DICE_CHANGES)) {
- // When a true DICE chain is created, we expect the root public key, at least one
- // entry for the boot before pvmfw, then pvmfw, vm_entry (Microdroid kernel) and
- // Microdroid payload entries.
- assertThat(rootArrayItems.size()).isAtLeast(5);
+ // We expect the root public key, at least one entry for the boot before pvmfw,
+ // then pvmfw, vm_entry (Microdroid kernel) and Microdroid payload entries.
+ // Before Android V we did not require that vendor code contain any DICE entries
+ // preceding pvmfw, so the minimum is one less.
+ int minDiceChainSize = getVendorApiLevel() >= 202404 ? 5 : 4;
+ assertThat(diceChainSize).isAtLeast(minDiceChainSize);
} else {
// pvmfw truncates the DICE chain it gets, so we expect exactly entries for
// public key, vm_entry (Microdroid kernel) and Microdroid payload.
- assertThat(rootArrayItems.size()).isEqualTo(3);
+ assertThat(diceChainSize).isEqualTo(3);
}
}
}
diff --git a/vmbase/Android.bp b/vmbase/Android.bp
index 07e1b4c..f01e8aa 100644
--- a/vmbase/Android.bp
+++ b/vmbase/Android.bp
@@ -79,13 +79,14 @@
"libbuddy_system_allocator",
"libcstr",
"libfdtpci",
- "libhyp",
"liblibfdt",
"liblog_rust_nostd",
"libonce_cell_nostd",
"libsmccc",
"libspin_nostd",
+ "libstatic_assertions",
"libtinyvec_nostd",
+ "libuuid_nostd",
"libvirtio_drivers",
"libzerocopy_nostd",
"libzeroize_nostd",
@@ -93,7 +94,9 @@
whole_static_libs: [
"librust_baremetal",
],
+ // TODO(b/277859415, b/277860860): Drop "compat_android_13".
features: [
+ "compat_android_13",
"cpu_feat_hafdbs",
],
}
diff --git a/vmbase/src/entry.rs b/vmbase/src/entry.rs
index b19efce..bb5ccef 100644
--- a/vmbase/src/entry.rs
+++ b/vmbase/src/entry.rs
@@ -15,19 +15,35 @@
//! Rust entry point.
use crate::{
- bionic, console, heap, logger,
+ bionic, console, heap, hyp, logger,
+ memory::{page_4kb_of, SIZE_16KB, SIZE_4KB},
power::{reboot, shutdown},
rand,
};
use core::mem::size_of;
-use hyp::{self, get_mmio_guard};
+use static_assertions::const_assert_eq;
fn try_console_init() -> Result<(), hyp::Error> {
console::init();
- if let Some(mmio_guard) = get_mmio_guard() {
+ if let Some(mmio_guard) = hyp::get_mmio_guard() {
mmio_guard.enroll()?;
- mmio_guard.validate_granule()?;
+
+ // TODO(ptosi): Use MmioSharer::share() to properly track this MMIO_GUARD_MAP.
+ //
+ // The following call shares the UART but also anything else present in 0..granule.
+ //
+ // For 4KiB, that's only the UARTs. For 16KiB, it also covers the RTC and watchdog but, as
+ // neither is used by vmbase clients (and as both are outside of the UART page), they
+ // will never have valid stage-1 mappings to those devices. As a result, this
+ // MMIO_GUARD_MAP isn't affected by the granule size in any visible way. Larger granule
+ // sizes will need to be checked separately, if needed.
+ assert!({
+ let granule = mmio_guard.granule()?;
+ granule == SIZE_4KB || granule == SIZE_16KB
+ });
+ // Validate the assumption above by ensuring that the UART is not moved to another page:
+ const_assert_eq!(page_4kb_of(console::BASE_ADDRESS), 0);
mmio_guard.map(console::BASE_ADDRESS)?;
}
diff --git a/libs/hyp/src/lib.rs b/vmbase/src/hyp.rs
similarity index 78%
rename from libs/hyp/src/lib.rs
rename to vmbase/src/hyp.rs
index 6a23585..1cc2ca7 100644
--- a/libs/hyp/src/lib.rs
+++ b/vmbase/src/hyp.rs
@@ -14,16 +14,10 @@
//! This library provides wrappers around various hypervisor backends.
-#![no_std]
-
mod error;
mod hypervisor;
-mod util;
-pub use crate::hypervisor::DeviceAssigningHypervisor;
pub use error::{Error, Result};
pub use hypervisor::{
- get_device_assigner, get_mem_sharer, get_mmio_guard, KvmError, MMIO_GUARD_GRANULE_SIZE,
+ get_device_assigner, get_mem_sharer, get_mmio_guard, DeviceAssigningHypervisor, KvmError,
};
-
-use hypervisor::GeniezoneError;
diff --git a/libs/hyp/src/error.rs b/vmbase/src/hyp/error.rs
similarity index 86%
rename from libs/hyp/src/error.rs
rename to vmbase/src/hyp/error.rs
index 3fdad70..e9c37e1 100644
--- a/libs/hyp/src/error.rs
+++ b/vmbase/src/hyp/error.rs
@@ -14,9 +14,9 @@
//! Error and Result types for hypervisor.
-use crate::GeniezoneError;
-use crate::KvmError;
use core::{fmt, result};
+
+use super::hypervisor::{GeniezoneError, KvmError};
use uuid::Uuid;
/// Result type with hypervisor error.
@@ -33,8 +33,6 @@
GeniezoneError(GeniezoneError, u32),
/// Unsupported Hypervisor
UnsupportedHypervisorUuid(Uuid),
- /// The MMIO_GUARD granule used by the hypervisor is not supported.
- UnsupportedMmioGuardGranule(usize),
}
impl fmt::Display for Error {
@@ -53,9 +51,6 @@
Self::UnsupportedHypervisorUuid(u) => {
write!(f, "Unsupported Hypervisor UUID {u}")
}
- Self::UnsupportedMmioGuardGranule(g) => {
- write!(f, "Unsupported MMIO guard granule: {g}")
- }
}
}
}
diff --git a/libs/hyp/src/hypervisor.rs b/vmbase/src/hyp/hypervisor.rs
similarity index 95%
rename from libs/hyp/src/hypervisor.rs
rename to vmbase/src/hyp/hypervisor.rs
index c53b886..1b45f38 100644
--- a/libs/hyp/src/hypervisor.rs
+++ b/vmbase/src/hyp/hypervisor.rs
@@ -14,19 +14,15 @@
//! Wrappers around hypervisor back-ends.
-extern crate alloc;
-
mod common;
mod geniezone;
mod gunyah;
mod kvm;
-use crate::error::{Error, Result};
+use super::{Error, Result};
use alloc::boxed::Box;
use common::Hypervisor;
-pub use common::{
- DeviceAssigningHypervisor, MemSharingHypervisor, MmioGuardedHypervisor, MMIO_GUARD_GRANULE_SIZE,
-};
+pub use common::{DeviceAssigningHypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
pub use geniezone::GeniezoneError;
use geniezone::GeniezoneHypervisor;
use gunyah::GunyahHypervisor;
diff --git a/libs/hyp/src/hypervisor/common.rs b/vmbase/src/hyp/hypervisor/common.rs
similarity index 84%
rename from libs/hyp/src/hypervisor/common.rs
rename to vmbase/src/hyp/hypervisor/common.rs
index eaac652..de0fe12 100644
--- a/libs/hyp/src/hypervisor/common.rs
+++ b/vmbase/src/hyp/hypervisor/common.rs
@@ -14,11 +14,7 @@
//! This module regroups some common traits shared by all the hypervisors.
-use crate::error::{Error, Result};
-use crate::util::SIZE_4KB;
-
-/// Expected MMIO guard granule size, validated during MMIO guard initialization.
-pub const MMIO_GUARD_GRANULE_SIZE: usize = SIZE_4KB;
+use crate::hyp::Result;
/// Trait for the hypervisor.
pub trait Hypervisor {
@@ -53,15 +49,6 @@
/// Returns the MMIO guard granule size in bytes.
fn granule(&self) -> Result<usize>;
-
- // TODO(ptosi): Fully move granule validation to client code.
- /// Validates the MMIO guard granule size.
- fn validate_granule(&self) -> Result<()> {
- match self.granule()? {
- MMIO_GUARD_GRANULE_SIZE => Ok(()),
- granule => Err(Error::UnsupportedMmioGuardGranule(granule)),
- }
- }
}
pub trait MemSharingHypervisor {
diff --git a/libs/hyp/src/hypervisor/geniezone.rs b/vmbase/src/hyp/hypervisor/geniezone.rs
similarity index 94%
rename from libs/hyp/src/hypervisor/geniezone.rs
rename to vmbase/src/hyp/hypervisor/geniezone.rs
index ad18e17..fcb9b42 100644
--- a/libs/hyp/src/hypervisor/geniezone.rs
+++ b/vmbase/src/hyp/hypervisor/geniezone.rs
@@ -14,10 +14,14 @@
//! Wrappers around calls to the GenieZone hypervisor.
-use super::common::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
-use crate::error::{Error, Result};
-use crate::util::page_address;
use core::fmt::{self, Display, Formatter};
+
+use super::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
+use crate::{
+ hyp::{Error, Result},
+ memory::page_4kb_of,
+};
+
use smccc::{
error::{positive_or_error_64, success_or_error_64},
hvc64,
@@ -107,14 +111,14 @@
fn map(&self, addr: usize) -> Result<()> {
let mut args = [0u64; 17];
- args[0] = page_address(addr);
+ args[0] = page_4kb_of(addr).try_into().unwrap();
checked_hvc64_expect_zero(VENDOR_HYP_GZVM_MMIO_GUARD_MAP_FUNC_ID, args)
}
fn unmap(&self, addr: usize) -> Result<()> {
let mut args = [0u64; 17];
- args[0] = page_address(addr);
+ args[0] = page_4kb_of(addr).try_into().unwrap();
checked_hvc64_expect_zero(VENDOR_HYP_GZVM_MMIO_GUARD_UNMAP_FUNC_ID, args)
}
diff --git a/libs/hyp/src/hypervisor/gunyah.rs b/vmbase/src/hyp/hypervisor/gunyah.rs
similarity index 100%
rename from libs/hyp/src/hypervisor/gunyah.rs
rename to vmbase/src/hyp/hypervisor/gunyah.rs
diff --git a/libs/hyp/src/hypervisor/kvm.rs b/vmbase/src/hyp/hypervisor/kvm.rs
similarity index 82%
rename from libs/hyp/src/hypervisor/kvm.rs
rename to vmbase/src/hyp/hypervisor/kvm.rs
index 720318e..8450bed 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/vmbase/src/hyp/hypervisor/kvm.rs
@@ -14,12 +14,14 @@
//! Wrappers around calls to the KVM hypervisor.
-use super::common::{
- DeviceAssigningHypervisor, Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor,
-};
-use crate::error::{Error, Result};
-use crate::util::page_address;
use core::fmt::{self, Display, Formatter};
+
+use super::{DeviceAssigningHypervisor, Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
+use crate::{
+ hyp::{Error, Result},
+ memory::page_4kb_of,
+};
+
use smccc::{
error::{positive_or_error_64, success_or_error_32, success_or_error_64},
hvc64,
@@ -113,24 +115,32 @@
fn map(&self, addr: usize) -> Result<()> {
let mut args = [0u64; 17];
- args[0] = page_address(addr);
+ args[0] = page_4kb_of(addr).try_into().unwrap();
- // TODO(b/277859415): pKVM returns a i32 instead of a i64 in T.
- // Drop this hack once T reaches EoL.
- success_or_error_32(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)[0] as u32)
- .map_err(|e| Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID))
+ if cfg!(feature = "compat_android_13") {
+ let res = hvc64(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)[0];
+ // pKVM returns i32 instead of the intended i64 in Android 13.
+ return success_or_error_32(res as u32)
+ .map_err(|e| Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID));
+ }
+
+ checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)
}
fn unmap(&self, addr: usize) -> Result<()> {
let mut args = [0u64; 17];
- args[0] = page_address(addr);
+ args[0] = page_4kb_of(addr).try_into().unwrap();
- // TODO(b/277860860): pKVM returns NOT_SUPPORTED for SUCCESS in T.
- // Drop this hack once T reaches EoL.
- match success_or_error_64(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)[0]) {
- Err(KvmError::NotSupported) | Ok(_) => Ok(()),
- Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
+ if cfg!(feature = "compat_android_13") {
+ let res = hvc64(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)[0];
+ // pKVM returns NOT_SUPPORTED for SUCCESS in Android 13.
+ return match success_or_error_64(res) {
+ Err(KvmError::NotSupported) | Ok(_) => Ok(()),
+ Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
+ };
}
+
+ checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)
}
fn granule(&self) -> Result<usize> {
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index 431e899..630834b 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -26,6 +26,7 @@
pub mod fdt;
pub mod heap;
mod hvc;
+pub mod hyp;
pub mod layout;
pub mod linker;
pub mod logger;
diff --git a/vmbase/src/memory.rs b/vmbase/src/memory.rs
index 2f72fc4..299d50f 100644
--- a/vmbase/src/memory.rs
+++ b/vmbase/src/memory.rs
@@ -26,8 +26,8 @@
handle_permission_fault, handle_translation_fault, MemoryRange, MemoryTracker, MEMORY,
};
pub use util::{
- flush, flushed_zeroize, min_dcache_line_size, page_4kb_of, PAGE_SIZE, SIZE_128KB, SIZE_2MB,
- SIZE_4KB, SIZE_4MB, SIZE_64KB,
+ flush, flushed_zeroize, min_dcache_line_size, page_4kb_of, PAGE_SIZE, SIZE_128KB, SIZE_16KB,
+ SIZE_2MB, SIZE_4KB, SIZE_4MB, SIZE_64KB,
};
pub(crate) use shared::{alloc_shared, dealloc_shared};
diff --git a/vmbase/src/memory/error.rs b/vmbase/src/memory/error.rs
index 273db56..4d08f1e 100644
--- a/vmbase/src/memory/error.rs
+++ b/vmbase/src/memory/error.rs
@@ -16,6 +16,8 @@
use core::fmt;
+use crate::hyp;
+
/// Errors for MemoryTracker operations.
#[derive(Debug, Clone)]
pub enum MemoryTrackerError {
@@ -47,6 +49,10 @@
FlushRegionFailed,
/// Failed to set PTE dirty state.
SetPteDirtyFailed,
+ /// Attempting to MMIO_GUARD_MAP more than once the same region.
+ DuplicateMmioShare(usize),
+ /// The MMIO_GUARD granule used by the hypervisor is not supported.
+ UnsupportedMmioGuardGranule(usize),
}
impl fmt::Display for MemoryTrackerError {
@@ -66,6 +72,12 @@
Self::InvalidPte => write!(f, "Page table entry is not valid"),
Self::FlushRegionFailed => write!(f, "Failed to flush memory region"),
Self::SetPteDirtyFailed => write!(f, "Failed to set PTE dirty state"),
+ Self::DuplicateMmioShare(addr) => {
+ write!(f, "Attempted to share the same MMIO region at {addr:#x} twice")
+ }
+ Self::UnsupportedMmioGuardGranule(g) => {
+ write!(f, "Unsupported MMIO guard granule: {g}")
+ }
}
}
}
diff --git a/vmbase/src/memory/shared.rs b/vmbase/src/memory/shared.rs
index dd433d4..5a25d9f 100644
--- a/vmbase/src/memory/shared.rs
+++ b/vmbase/src/memory/shared.rs
@@ -18,14 +18,18 @@
use super::error::MemoryTrackerError;
use super::page_table::{PageTable, MMIO_LAZY_MAP_FLAG};
use super::util::{page_4kb_of, virt_to_phys};
+use crate::console;
use crate::dsb;
use crate::exceptions::HandleExceptionError;
+use crate::hyp::{self, get_mem_sharer, get_mmio_guard};
+use crate::util::unchecked_align_down;
use crate::util::RangeExt as _;
use aarch64_paging::paging::{
- Attributes, Descriptor, MemoryRegion as VaRange, VirtualAddress, BITS_PER_LEVEL, PAGE_SIZE,
+ Attributes, Descriptor, MemoryRegion as VaRange, VirtualAddress, PAGE_SIZE,
};
use alloc::alloc::{alloc_zeroed, dealloc, handle_alloc_error};
use alloc::boxed::Box;
+use alloc::collections::BTreeSet;
use alloc::vec::Vec;
use buddy_system_allocator::{FrameAllocator, LockedFrameAllocator};
use core::alloc::Layout;
@@ -35,7 +39,6 @@
use core::ops::Range;
use core::ptr::NonNull;
use core::result;
-use hyp::{get_mem_sharer, get_mmio_guard, MMIO_GUARD_GRANULE_SIZE};
use log::{debug, error, trace};
use once_cell::race::OnceBox;
use spin::mutex::SpinMutex;
@@ -77,6 +80,7 @@
mmio_regions: ArrayVec<[MemoryRange; MemoryTracker::MMIO_CAPACITY]>,
mmio_range: MemoryRange,
payload_range: Option<MemoryRange>,
+ mmio_sharer: MmioSharer,
}
impl MemoryTracker {
@@ -113,6 +117,7 @@
mmio_regions: ArrayVec::new(),
mmio_range,
payload_range: payload_range.map(|r| r.start.0..r.end.0),
+ mmio_sharer: MmioSharer::new().unwrap(),
}
}
@@ -248,17 +253,10 @@
Ok(self.regions.last().unwrap().range.clone())
}
- /// Unmaps all tracked MMIO regions from the MMIO guard.
- ///
- /// Note that they are not unmapped from the page table.
- pub fn mmio_unmap_all(&mut self) -> Result<()> {
- if get_mmio_guard().is_some() {
- for range in &self.mmio_regions {
- self.page_table
- .walk_range(&get_va_range(range), &mmio_guard_unmap_page)
- .map_err(|_| MemoryTrackerError::FailedToUnmap)?;
- }
- }
+ /// Unshares any MMIO region previously shared with the MMIO guard.
+ pub fn unshare_all_mmio(&mut self) -> Result<()> {
+ self.mmio_sharer.unshare_all();
+
Ok(())
}
@@ -320,15 +318,21 @@
/// Handles translation fault for blocks flagged for lazy MMIO mapping by enabling the page
/// table entry and MMIO guard mapping the block. Breaks apart a block entry if required.
fn handle_mmio_fault(&mut self, addr: VirtualAddress) -> Result<()> {
- let page_start = VirtualAddress(page_4kb_of(addr.0));
- assert_eq!(page_start.0 % MMIO_GUARD_GRANULE_SIZE, 0);
- let page_range: VaRange = (page_start..page_start + MMIO_GUARD_GRANULE_SIZE).into();
- let mmio_guard = get_mmio_guard().unwrap();
+ let shared_range = self.mmio_sharer.share(addr)?;
+ self.map_lazy_mmio_as_valid(&shared_range)?;
+
+ Ok(())
+ }
+
+ /// Modify the PTEs corresponding to a given range from (invalid) "lazy MMIO" to valid MMIO.
+ ///
+ /// Returns an error if any PTE in the range is not an invalid lazy MMIO mapping.
+ fn map_lazy_mmio_as_valid(&mut self, page_range: &VaRange) -> Result<()> {
// This must be safe and free from break-before-make (BBM) violations, given that the
// initial lazy mapping has the valid bit cleared, and each newly created valid descriptor
// created inside the mapping has the same size and alignment.
self.page_table
- .modify_range(&page_range, &|_: &VaRange, desc: &mut Descriptor, _: usize| {
+ .modify_range(page_range, &|_: &VaRange, desc: &mut Descriptor, _: usize| {
let flags = desc.flags().expect("Unsupported PTE flags set");
if flags.contains(MMIO_LAZY_MAP_FLAG) && !flags.contains(Attributes::VALID) {
desc.modify_flags(Attributes::VALID, Attributes::empty());
@@ -337,8 +341,7 @@
Err(())
}
})
- .map_err(|_| MemoryTrackerError::InvalidPte)?;
- Ok(mmio_guard.map(page_start.0)?)
+ .map_err(|_| MemoryTrackerError::InvalidPte)
}
/// Flush all memory regions marked as writable-dirty.
@@ -376,6 +379,71 @@
}
}
+struct MmioSharer {
+ granule: usize,
+ frames: BTreeSet<usize>,
+}
+
+impl MmioSharer {
+ fn new() -> Result<Self> {
+ let granule = Self::get_granule()?;
+ let frames = BTreeSet::new();
+
+ // Allows safely calling util::unchecked_align_down().
+ assert!(granule.is_power_of_two());
+
+ Ok(Self { granule, frames })
+ }
+
+ fn get_granule() -> Result<usize> {
+ let Some(mmio_guard) = get_mmio_guard() else {
+ return Ok(PAGE_SIZE);
+ };
+ match mmio_guard.granule()? {
+ granule if granule % PAGE_SIZE == 0 => Ok(granule), // For good measure.
+ granule => Err(MemoryTrackerError::UnsupportedMmioGuardGranule(granule)),
+ }
+ }
+
+ /// Share the MMIO region aligned to the granule size containing addr (not validated as MMIO).
+ fn share(&mut self, addr: VirtualAddress) -> Result<VaRange> {
+ // This can't use virt_to_phys() since 0x0 is a valid MMIO address and we are ID-mapped.
+ let phys = addr.0;
+ let base = unchecked_align_down(phys, self.granule);
+
+ // TODO(ptosi): Share the UART using this method and remove the hardcoded check.
+ if self.frames.contains(&base) || base == page_4kb_of(console::BASE_ADDRESS) {
+ return Err(MemoryTrackerError::DuplicateMmioShare(base));
+ }
+
+ if let Some(mmio_guard) = get_mmio_guard() {
+ mmio_guard.map(base)?;
+ }
+
+ let inserted = self.frames.insert(base);
+ assert!(inserted);
+
+ let base_va = VirtualAddress(base);
+ Ok((base_va..base_va + self.granule).into())
+ }
+
+ fn unshare_all(&mut self) {
+ let Some(mmio_guard) = get_mmio_guard() else {
+ return self.frames.clear();
+ };
+
+ while let Some(base) = self.frames.pop_first() {
+ mmio_guard.unmap(base).unwrap();
+ }
+ }
+}
+
+impl Drop for MmioSharer {
+ fn drop(&mut self) {
+ self.unshare_all();
+ }
+}
+
/// Allocates a memory range of at least the given size and alignment that is shared with the host.
/// Returns a pointer to the buffer.
pub(crate) fn alloc_shared(layout: Layout) -> hyp::Result<NonNull<u8>> {
@@ -479,41 +547,6 @@
}
}
-/// MMIO guard unmaps page
-fn mmio_guard_unmap_page(
- va_range: &VaRange,
- desc: &Descriptor,
- level: usize,
-) -> result::Result<(), ()> {
- let flags = desc.flags().expect("Unsupported PTE flags set");
- // This function will be called on an address range that corresponds to a device. Only if a
- // page has been accessed (written to or read from), will it contain the VALID flag and be MMIO
- // guard mapped. Therefore, we can skip unmapping invalid pages, they were never MMIO guard
- // mapped anyway.
- if flags.contains(Attributes::VALID) {
- assert!(
- flags.contains(MMIO_LAZY_MAP_FLAG),
- "Attempting MMIO guard unmap for non-device pages"
- );
- const MMIO_GUARD_GRANULE_SHIFT: u32 = MMIO_GUARD_GRANULE_SIZE.ilog2() - PAGE_SIZE.ilog2();
- const MMIO_GUARD_GRANULE_LEVEL: usize =
- 3 - (MMIO_GUARD_GRANULE_SHIFT as usize / BITS_PER_LEVEL);
- assert_eq!(
- level, MMIO_GUARD_GRANULE_LEVEL,
- "Failed to break down block mapping before MMIO guard mapping"
- );
- let page_base = va_range.start().0;
- assert_eq!(page_base % MMIO_GUARD_GRANULE_SIZE, 0);
- // Since mmio_guard_map takes IPAs, if pvmfw moves non-ID address mapping, page_base
- // should be converted to IPA. However, since 0x0 is a valid MMIO address, we don't use
- // virt_to_phys here, and just pass page_base instead.
- get_mmio_guard().unwrap().unmap(page_base).map_err(|e| {
- error!("Error MMIO guard unmapping: {e}");
- })?;
- }
- Ok(())
-}
-
/// Handles a translation fault with the given fault address register (FAR).
#[inline]
pub fn handle_translation_fault(far: VirtualAddress) -> result::Result<(), HandleExceptionError> {
diff --git a/vmbase/src/memory/util.rs b/vmbase/src/memory/util.rs
index 2b75414..e9f867f 100644
--- a/vmbase/src/memory/util.rs
+++ b/vmbase/src/memory/util.rs
@@ -22,6 +22,8 @@
/// The size of a 4KB memory in bytes.
pub const SIZE_4KB: usize = 4 << 10;
+/// The size of a 16KB memory in bytes.
+pub const SIZE_16KB: usize = 16 << 10;
/// The size of a 64KB memory in bytes.
pub const SIZE_64KB: usize = 64 << 10;
/// The size of a 128KB memory in bytes.