Merge "Use cert hash not public key for APK authority" into main
diff --git a/Android.bp b/Android.bp
index 9c17c7f..54919d4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,5 +61,5 @@
genrule_defaults {
name: "dts_to_dtb",
tools: ["dtc"],
- cmd: "$(location dtc) -I dts -O dtb $(in) -o $(out)",
+ cmd: "FILES=($(in)) && $(location dtc) -I dts -O dtb $${FILES[-1]} -o $(out)",
}
diff --git a/libs/bssl/error/src/lib.rs b/libs/bssl/error/src/lib.rs
index c0dca2e..df79104 100644
--- a/libs/bssl/error/src/lib.rs
+++ b/libs/bssl/error/src/lib.rs
@@ -81,9 +81,14 @@
EVP_AEAD_CTX_new,
EVP_AEAD_CTX_open,
EVP_AEAD_CTX_seal,
+ EVP_Digest,
+ EVP_MD_CTX_new,
EVP_PKEY_new,
+ EVP_PKEY_new_raw_public_key,
EVP_PKEY_set1_EC_KEY,
EVP_marshal_public_key,
+ EVP_DigestVerify,
+ EVP_DigestVerifyInit,
HKDF,
HMAC,
RAND_bytes,
diff --git a/libs/bssl/src/digest.rs b/libs/bssl/src/digest.rs
index 49e66e6..e986a38 100644
--- a/libs/bssl/src/digest.rs
+++ b/libs/bssl/src/digest.rs
@@ -14,7 +14,18 @@
//! Wrappers of the digest functions in BoringSSL digest.h.
-use bssl_ffi::{EVP_MD_size, EVP_sha256, EVP_sha512, EVP_MD};
+use crate::util::{check_int_result, to_call_failed_error};
+use alloc::vec;
+use alloc::vec::Vec;
+use bssl_avf_error::{ApiName, Error, Result};
+use bssl_ffi::{
+ EVP_Digest, EVP_MD_CTX_free, EVP_MD_CTX_new, EVP_MD_size, EVP_sha256, EVP_sha384, EVP_sha512,
+ EVP_MAX_MD_SIZE, EVP_MD, EVP_MD_CTX,
+};
+use core::ptr::{self, NonNull};
+use log::error;
+
+const MAX_DIGEST_SIZE: usize = EVP_MAX_MD_SIZE as usize;
/// Message digester wrapping `EVP_MD`.
#[derive(Clone, Debug)]
@@ -28,7 +39,17 @@
let p = unsafe { EVP_sha256() };
// SAFETY: The returned pointer should always be valid and points to a static
// `EVP_MD`.
- Self(unsafe { &*p })
+ Self(unsafe { p.as_ref().unwrap() })
+ }
+
+ /// Returns a `Digester` implementing `SHA-384` algorithm.
+ pub fn sha384() -> Self {
+ // SAFETY: This function does not access any Rust variables and simply returns
+ // a pointer to the static variable in BoringSSL.
+ let p = unsafe { EVP_sha384() };
+ // SAFETY: The returned pointer should always be valid and points to a static
+ // `EVP_MD`.
+ Self(unsafe { p.as_ref().unwrap() })
}
/// Returns a `Digester` implementing `SHA-512` algorithm.
@@ -38,7 +59,7 @@
let p = unsafe { EVP_sha512() };
// SAFETY: The returned pointer should always be valid and points to a static
// `EVP_MD`.
- Self(unsafe { &*p })
+ Self(unsafe { p.as_ref().unwrap() })
}
/// Returns the digest size in bytes.
@@ -46,4 +67,64 @@
// SAFETY: The inner pointer is fetched from EVP_* hash functions in BoringSSL digest.h
unsafe { EVP_MD_size(self.0) }
}
+
+ /// Computes the digest of the provided `data`.
+ pub fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
+ let mut out = vec![0u8; MAX_DIGEST_SIZE];
+ let mut out_size = 0;
+ let engine = ptr::null_mut(); // Use the default engine.
+ let ret =
+ // SAFETY: This function reads `data` and writes to `out` within its bounds.
+ // `out` has `MAX_DIGEST_SIZE` bytes of space for write as required in the
+ // BoringSSL spec.
+ // The digester is a valid pointer to a static `EVP_MD` as it is returned by
+ // BoringSSL API during the construction of this struct.
+ unsafe {
+ EVP_Digest(
+ data.as_ptr() as *const _,
+ data.len(),
+ out.as_mut_ptr(),
+ &mut out_size,
+ self.0,
+ engine,
+ )
+ };
+ check_int_result(ret, ApiName::EVP_Digest)?;
+ let out_size = usize::try_from(out_size).map_err(|e| {
+ error!("Failed to convert digest size to usize: {:?}", e);
+ Error::InternalError
+ })?;
+ if self.size() != out_size {
+ return Err(to_call_failed_error(ApiName::EVP_Digest));
+ }
+ out.truncate(out_size);
+ Ok(out)
+ }
+}
+
+/// Message digester context wrapping `EVP_MD_CTX`.
+#[derive(Clone, Debug)]
+pub struct DigesterContext(NonNull<EVP_MD_CTX>);
+
+impl Drop for DigesterContext {
+ fn drop(&mut self) {
+ // SAFETY: This function frees any resources owned by `EVP_MD_CTX` and resets it to a
+ // freshly initialised state and then frees the context.
+ // It is safe because `EVP_MD_CTX` has been allocated by BoringSSL and isn't used after
+ // this.
+ unsafe { EVP_MD_CTX_free(self.0.as_ptr()) }
+ }
+}
+
+impl DigesterContext {
+ /// Creates a new `DigesterContext` wrapping a freshly allocated and initialised `EVP_MD_CTX`.
+ pub fn new() -> Result<Self> {
+ // SAFETY: The returned pointer is checked below.
+ let ctx = unsafe { EVP_MD_CTX_new() };
+ NonNull::new(ctx).map(Self).ok_or(to_call_failed_error(ApiName::EVP_MD_CTX_new))
+ }
+
+ pub(crate) fn as_mut_ptr(&mut self) -> *mut EVP_MD_CTX {
+ self.0.as_ptr()
+ }
}
diff --git a/libs/bssl/src/ec_key.rs b/libs/bssl/src/ec_key.rs
index 511b133..0c944cd 100644
--- a/libs/bssl/src/ec_key.rs
+++ b/libs/bssl/src/ec_key.rs
@@ -17,7 +17,9 @@
use crate::cbb::CbbFixed;
use crate::cbs::Cbs;
-use crate::util::{check_int_result, to_call_failed_error};
+use crate::util::{
+ check_int_result, get_label_value, get_label_value_as_bytes, to_call_failed_error,
+};
use alloc::vec;
use alloc::vec::Vec;
use bssl_avf_error::{ApiName, Error, Result};
@@ -33,7 +35,7 @@
use core::ptr::{self, NonNull};
use coset::{
iana::{self, EnumI64},
- CborSerializable, CoseKey, CoseKeyBuilder, Label,
+ CborSerializable, CoseKey, CoseKeyBuilder, KeyType, Label,
};
use log::error;
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
@@ -79,13 +81,27 @@
}
/// Constructs an `EcKey` instance from the provided COSE_Key encoded public key slice.
- pub fn from_cose_public_key(cose_key: &[u8]) -> Result<Self> {
+ pub fn from_cose_public_key_slice(cose_key: &[u8]) -> Result<Self> {
let cose_key = CoseKey::from_slice(cose_key).map_err(|e| {
error!("Failed to deserialize COSE_Key: {e:?}");
Error::CoseKeyDecodingFailed
})?;
+ Self::from_cose_public_key(&cose_key)
+ }
+
+ /// Constructs an `EcKey` instance from the provided `COSE_Key`.
+ ///
+ /// The lifetime of the returned `EcKey` is not tied to the lifetime of the `cose_key`,
+ /// because the affine coordinates stored in the `cose_key` are copied into the `EcKey`.
+ ///
+ /// Currently, only the EC P-256 and P-384 curves are supported.
+ pub fn from_cose_public_key(cose_key: &CoseKey) -> Result<Self> {
+ if cose_key.kty != KeyType::Assigned(iana::KeyType::EC2) {
+ error!("Only EC2 keys are supported. Key type in the COSE Key: {:?}", cose_key.kty);
+ return Err(Error::Unimplemented);
+ }
let ec_key =
- match get_label_value(&cose_key, Label::Int(iana::Ec2KeyParameter::Crv.to_i64()))? {
+ match get_label_value(cose_key, Label::Int(iana::Ec2KeyParameter::Crv.to_i64()))? {
crv if crv == &Value::from(P256_CURVE.to_i64()) => EcKey::new_p256()?,
crv if crv == &Value::from(P384_CURVE.to_i64()) => EcKey::new_p384()?,
crv => {
@@ -96,8 +112,8 @@
return Err(Error::Unimplemented);
}
};
- let x = get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::X.to_i64()))?;
- let y = get_label_value_as_bytes(&cose_key, Label::Int(iana::Ec2KeyParameter::Y.to_i64()))?;
+ let x = get_label_value_as_bytes(cose_key, Label::Int(iana::Ec2KeyParameter::X.to_i64()))?;
+ let y = get_label_value_as_bytes(cose_key, Label::Int(iana::Ec2KeyParameter::Y.to_i64()))?;
let group = ec_key.ec_group()?;
group.check_affine_coordinate_size(x)?;
@@ -309,17 +325,6 @@
}
}
-fn get_label_value_as_bytes(key: &CoseKey, label: Label) -> Result<&[u8]> {
- Ok(get_label_value(key, label)?.as_bytes().ok_or_else(|| {
- error!("Value not a bstr.");
- Error::CoseKeyDecodingFailed
- })?)
-}
-
-fn get_label_value(key: &CoseKey, label: Label) -> Result<&Value> {
- Ok(&key.params.iter().find(|(k, _)| k == &label).ok_or(Error::CoseKeyDecodingFailed)?.1)
-}
-
/// Wrapper of an `EC_GROUP` reference.
struct EcGroup<'a>(&'a EC_GROUP);
diff --git a/libs/bssl/src/evp.rs b/libs/bssl/src/evp.rs
index 5362925..86f99a8 100644
--- a/libs/bssl/src/evp.rs
+++ b/libs/bssl/src/evp.rs
@@ -15,22 +15,32 @@
//! Wrappers of the EVP functions in BoringSSL evp.h.
use crate::cbb::CbbFixed;
+use crate::digest::{Digester, DigesterContext};
use crate::ec_key::EcKey;
-use crate::util::{check_int_result, to_call_failed_error};
-use alloc::vec::Vec;
-use bssl_avf_error::{ApiName, Result};
-use bssl_ffi::{
- CBB_flush, CBB_len, EVP_PKEY_free, EVP_PKEY_new, EVP_PKEY_set1_EC_KEY, EVP_marshal_public_key,
- EVP_PKEY,
+use crate::util::{
+ check_int_result, get_label_value, get_label_value_as_bytes, to_call_failed_error,
};
-use core::ptr::NonNull;
+use alloc::vec::Vec;
+use bssl_avf_error::{ApiName, Error, Result};
+use bssl_ffi::{
+ CBB_flush, CBB_len, EVP_DigestVerify, EVP_DigestVerifyInit, EVP_PKEY_free, EVP_PKEY_new,
+ EVP_PKEY_new_raw_public_key, EVP_PKEY_set1_EC_KEY, EVP_marshal_public_key, EVP_PKEY,
+ EVP_PKEY_ED25519, EVP_PKEY_X25519,
+};
+use ciborium::Value;
+use core::ptr::{self, NonNull};
+use coset::{
+ iana::{self, EnumI64},
+ CoseKey, KeyType, Label,
+};
+use log::error;
/// Wrapper of an `EVP_PKEY` object, representing a public or private key.
pub struct PKey {
pkey: NonNull<EVP_PKEY>,
- /// Since this struct owns the inner key, the inner key remains valid as
+ /// If this struct owns the inner EC key, the inner EC key should remain valid as
/// long as the pointer to `EVP_PKEY` is valid.
- _inner_key: EcKey,
+ _inner_ec_key: Option<EcKey>,
}
impl Drop for PKey {
@@ -53,14 +63,14 @@
fn try_from(key: EcKey) -> Result<Self> {
let pkey = new_pkey()?;
- // SAFETY: The function only sets the inner key of the initialized and
+ // SAFETY: The function only sets the inner EC key of the initialized and
// non-null `EVP_PKEY` to point to the given `EC_KEY`. It only reads from
// and writes to the initialized `EVP_PKEY`.
// Since this struct owns the inner key, the inner key remains valid as
// long as `EVP_PKEY` is valid.
let ret = unsafe { EVP_PKEY_set1_EC_KEY(pkey.as_ptr(), key.0.as_ptr()) };
check_int_result(ret, ApiName::EVP_PKEY_set1_EC_KEY)?;
- Ok(Self { pkey, _inner_key: key })
+ Ok(Self { pkey, _inner_ec_key: Some(key) })
}
}
@@ -87,4 +97,126 @@
let len = unsafe { CBB_len(cbb.as_ref()) };
Ok(buf.get(0..len).ok_or(to_call_failed_error(ApiName::CBB_len))?.to_vec())
}
+
+ /// This function takes a raw public key data slice and creates a `PKey` instance wrapping
+ /// a freshly allocated `EVP_PKEY` object from it.
+ ///
+ /// The lifetime of the returned instance is not tied to the lifetime of the raw public
+ /// key slice because the raw data is copied into the `EVP_PKEY` object.
+ ///
+ /// Currently the only supported raw formats are X25519 and Ed25519, where the formats
+ /// are specified in RFC 7748 and RFC 8032 respectively.
+ pub fn new_raw_public_key(raw_public_key: &[u8], type_: PKeyType) -> Result<Self> {
+ let engine = ptr::null_mut(); // Engine is not used.
+ let pkey =
+ // SAFETY: The function only reads from the given raw public key within its bounds.
+ // The returned pointer is checked below.
+ unsafe {
+ EVP_PKEY_new_raw_public_key(
+ type_.0,
+ engine,
+ raw_public_key.as_ptr(),
+ raw_public_key.len(),
+ )
+ };
+ let pkey =
+ NonNull::new(pkey).ok_or(to_call_failed_error(ApiName::EVP_PKEY_new_raw_public_key))?;
+ Ok(Self { pkey, _inner_ec_key: None })
+ }
+
+ /// Creates a `PKey` from the given `cose_key`.
+ ///
+ /// The lifetime of the returned instance is not tied to the lifetime of the `cose_key` as the
+ /// data of `cose_key` is copied into the `EVP_PKEY` or `EC_KEY` object.
+ pub fn from_cose_public_key(cose_key: &CoseKey) -> Result<Self> {
+ match &cose_key.kty {
+ KeyType::Assigned(iana::KeyType::EC2) => {
+ EcKey::from_cose_public_key(cose_key)?.try_into()
+ }
+ KeyType::Assigned(iana::KeyType::OKP) => {
+ let curve_type =
+ get_label_value(cose_key, Label::Int(iana::OkpKeyParameter::Crv.to_i64()))?;
+ let curve_type = match curve_type {
+ crv if crv == &Value::from(iana::EllipticCurve::Ed25519.to_i64()) => {
+ PKeyType::ED25519
+ }
+ crv if crv == &Value::from(iana::EllipticCurve::X25519.to_i64()) => {
+ PKeyType::X25519
+ }
+ crv => {
+ error!("Unsupported curve type in OKP COSE key: {:?}", crv);
+ return Err(Error::Unimplemented);
+ }
+ };
+ let x = get_label_value_as_bytes(
+ cose_key,
+ Label::Int(iana::OkpKeyParameter::X.to_i64()),
+ )?;
+ Self::new_raw_public_key(x, curve_type)
+ }
+ kty => {
+ error!("Unsupported key type in COSE key: {:?}", kty);
+ Err(Error::Unimplemented)
+ }
+ }
+ }
+
+ /// Verifies the given `signature` of the `message` using the current public key.
+ ///
+ /// The `message` will be hashed using the given `digester` before verification.
+ ///
+ /// For algorithms like Ed25519 that do not use pre-hashed inputs, the `digester` should
+ /// be `None`.
+ pub fn verify(
+ &self,
+ signature: &[u8],
+ message: &[u8],
+ digester: Option<Digester>,
+ ) -> Result<()> {
+ let mut digester_context = DigesterContext::new()?;
+ // The `EVP_PKEY_CTX` is set to null as this function does not collect the context
+ // during the verification.
+ let pkey_context = ptr::null_mut();
+ let engine = ptr::null_mut(); // Use the default engine.
+ let ret =
+ // SAFETY: All the non-null parameters passed to this function have been properly
+ // initialized as required in the BoringSSL spec.
+ unsafe {
+ EVP_DigestVerifyInit(
+ digester_context.as_mut_ptr(),
+ pkey_context,
+ digester.map_or(ptr::null(), |d| d.0),
+ engine,
+ self.pkey.as_ptr(),
+ )
+ };
+ check_int_result(ret, ApiName::EVP_DigestVerifyInit)?;
+
+ // SAFETY: The function only reads from the given slices within their bounds.
+ // The `EVP_MD_CTX` is successfully initialized before this call.
+ let ret = unsafe {
+ EVP_DigestVerify(
+ digester_context.as_mut_ptr(),
+ signature.as_ptr(),
+ signature.len(),
+ message.as_ptr(),
+ message.len(),
+ )
+ };
+ check_int_result(ret, ApiName::EVP_DigestVerify)
+ }
+}
+
+/// Type of the keys supported by `PKey`.
+///
+/// It is a wrapper of the `EVP_PKEY_*` macros defined BoringSSL evp.h, which are the
+/// NID values of the corresponding keys.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct PKeyType(i32);
+
+impl PKeyType {
+ /// EVP_PKEY_X25519 / NID_X25519
+ pub const X25519: PKeyType = PKeyType(EVP_PKEY_X25519);
+ /// EVP_PKEY_ED25519 / NID_ED25519
+ pub const ED25519: PKeyType = PKeyType(EVP_PKEY_ED25519);
}
diff --git a/libs/bssl/src/lib.rs b/libs/bssl/src/lib.rs
index 25b0163..a420168 100644
--- a/libs/bssl/src/lib.rs
+++ b/libs/bssl/src/lib.rs
@@ -38,7 +38,7 @@
pub use cbs::Cbs;
pub use digest::Digester;
pub use ec_key::{EcKey, ZVec};
-pub use evp::PKey;
+pub use evp::{PKey, PKeyType};
pub use hkdf::hkdf;
pub use hmac::hmac_sha256;
pub use rand::rand_bytes;
diff --git a/libs/bssl/src/util.rs b/libs/bssl/src/util.rs
index 880c85b..7473fe1 100644
--- a/libs/bssl/src/util.rs
+++ b/libs/bssl/src/util.rs
@@ -16,6 +16,8 @@
use crate::err::get_error_reason_code;
use bssl_avf_error::{ApiName, Error, Result};
+use ciborium::Value;
+use coset::{CoseKey, Label};
use log::error;
pub(crate) fn check_int_result(ret: i32, api_name: ApiName) -> Result<()> {
@@ -35,3 +37,14 @@
pub(crate) fn to_call_failed_error(api_name: ApiName) -> Error {
Error::CallFailed(api_name, get_error_reason_code())
}
+
+pub(crate) fn get_label_value_as_bytes(key: &CoseKey, label: Label) -> Result<&[u8]> {
+ Ok(get_label_value(key, label)?.as_bytes().ok_or_else(|| {
+ error!("Value not a bstr.");
+ Error::CoseKeyDecodingFailed
+ })?)
+}
+
+pub(crate) fn get_label_value(key: &CoseKey, label: Label) -> Result<&Value> {
+ Ok(&key.params.iter().find(|(k, _)| k == &label).ok_or(Error::CoseKeyDecodingFailed)?.1)
+}
diff --git a/libs/bssl/tests/eckey_test.rs b/libs/bssl/tests/eckey_test.rs
index 4f0697c..9c7eb4f 100644
--- a/libs/bssl/tests/eckey_test.rs
+++ b/libs/bssl/tests/eckey_test.rs
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use bssl_avf::{sha256, ApiName, EcKey, EcdsaError, Error, PKey, Result};
+use bssl_avf::{sha256, ApiName, Digester, EcKey, EcdsaError, Error, PKey, Result};
use coset::CborSerializable;
use spki::{
der::{AnyRef, Decode},
@@ -72,7 +72,7 @@
ec_key.generate_key()?;
let cose_key = ec_key.cose_public_key()?;
let cose_key_data = cose_key.clone().to_vec().unwrap();
- let deserialized_ec_key = EcKey::from_cose_public_key(&cose_key_data)?;
+ let deserialized_ec_key = EcKey::from_cose_public_key_slice(&cose_key_data)?;
assert_eq!(cose_key, deserialized_ec_key.cose_public_key()?);
Ok(())
@@ -82,10 +82,29 @@
fn ecdsa_p256_signing_and_verification_succeed() -> Result<()> {
let mut ec_key = EcKey::new_p256()?;
ec_key.generate_key()?;
- let digest = sha256(MESSAGE1)?;
+ let digester = Digester::sha256();
+ let digest = digester.digest(MESSAGE1)?;
+ assert_eq!(digest, sha256(MESSAGE1)?);
let signature = ec_key.ecdsa_sign(&digest)?;
- ec_key.ecdsa_verify(&signature, &digest)
+ ec_key.ecdsa_verify(&signature, &digest)?;
+ // Building a `PKey` from a temporary `CoseKey` should work as the lifetime
+ // of the `PKey` is not tied to the lifetime of the `CoseKey`.
+ let pkey = PKey::from_cose_public_key(&ec_key.cose_public_key()?)?;
+ pkey.verify(&signature, MESSAGE1, Some(digester))
+}
+
+#[test]
+fn ecdsa_p384_signing_and_verification_succeed() -> Result<()> {
+ let mut ec_key = EcKey::new_p384()?;
+ ec_key.generate_key()?;
+ let digester = Digester::sha384();
+ let digest = digester.digest(MESSAGE1)?;
+
+ let signature = ec_key.ecdsa_sign(&digest)?;
+ ec_key.ecdsa_verify(&signature, &digest)?;
+ let pkey = PKey::from_cose_public_key(&ec_key.cose_public_key()?)?;
+ pkey.verify(&signature, MESSAGE1, Some(digester))
}
#[test]
@@ -100,6 +119,12 @@
let err = ec_key2.ecdsa_verify(&signature, &digest).unwrap_err();
let expected_err = Error::CallFailed(ApiName::ECDSA_verify, EcdsaError::BadSignature.into());
assert_eq!(expected_err, err);
+
+ let pkey: PKey = ec_key2.try_into()?;
+ let err = pkey.verify(&signature, MESSAGE1, Some(Digester::sha256())).unwrap_err();
+ let expected_err =
+ Error::CallFailed(ApiName::EVP_DigestVerify, EcdsaError::BadSignature.into());
+ assert_eq!(expected_err, err);
Ok(())
}
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index c6befb4..d267e2e 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -81,10 +81,10 @@
":test_pvmfw_devices_vm_dtbo",
":test_pvmfw_devices_vm_dtbo_without_symbols",
":test_pvmfw_devices_with_rng",
- ":test_pvmfw_devices_with_rng_iommu",
":test_pvmfw_devices_with_multiple_devices_iommus",
":test_pvmfw_devices_with_iommu_sharing",
":test_pvmfw_devices_with_iommu_id_conflict",
+ ":test_pvmfw_devices_without_iommus",
],
// To use libpvmfw_fdt_template for testing
enabled: false,
@@ -121,37 +121,43 @@
out: ["test_pvmfw_devices_vm_dtbo_without_symbols.dtbo"],
}
+genrule_defaults {
+ name: "test_device_assignment_dts_to_dtb",
+ defaults: ["dts_to_dtb"],
+ srcs: ["testdata/test_crosvm_dt_base.dtsi"],
+}
+
genrule {
name: "test_pvmfw_devices_with_rng",
- defaults: ["dts_to_dtb"],
+ defaults: ["test_device_assignment_dts_to_dtb"],
srcs: ["testdata/test_pvmfw_devices_with_rng.dts"],
out: ["test_pvmfw_devices_with_rng.dtb"],
}
genrule {
- name: "test_pvmfw_devices_with_rng_iommu",
- defaults: ["dts_to_dtb"],
- srcs: ["testdata/test_pvmfw_devices_with_rng_iommu.dts"],
- out: ["test_pvmfw_devices_with_rng_iommu.dtb"],
+ name: "test_pvmfw_devices_without_iommus",
+ defaults: ["test_device_assignment_dts_to_dtb"],
+ srcs: ["testdata/test_pvmfw_devices_without_iommus.dts"],
+ out: ["test_pvmfw_devices_without_iommus.dtb"],
}
genrule {
name: "test_pvmfw_devices_with_multiple_devices_iommus",
- defaults: ["dts_to_dtb"],
+ defaults: ["test_device_assignment_dts_to_dtb"],
srcs: ["testdata/test_pvmfw_devices_with_multiple_devices_iommus.dts"],
out: ["test_pvmfw_devices_with_multiple_devices_iommus.dtb"],
}
genrule {
name: "test_pvmfw_devices_with_iommu_sharing",
- defaults: ["dts_to_dtb"],
+ defaults: ["test_device_assignment_dts_to_dtb"],
srcs: ["testdata/test_pvmfw_devices_with_iommu_sharing.dts"],
out: ["test_pvmfw_devices_with_iommu_sharing.dtb"],
}
genrule {
name: "test_pvmfw_devices_with_iommu_id_conflict",
- defaults: ["dts_to_dtb"],
+ defaults: ["test_device_assignment_dts_to_dtb"],
srcs: ["testdata/test_pvmfw_devices_with_iommu_id_conflict.dts"],
out: ["test_pvmfw_devices_with_iommu_id_conflict.dtb"],
}
diff --git a/pvmfw/platform.dts b/pvmfw/platform.dts
index 4a269c3..9abc123 100644
--- a/pvmfw/platform.dts
+++ b/pvmfw/platform.dts
@@ -265,60 +265,60 @@
pviommu_0: pviommu0 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_1: pviommu1 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_2: pviommu2 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_3: pviommu3 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_4: pviommu4 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_5: pviommu5 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_6: pviommu6 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_7: pviommu7 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_8: pviommu8 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
pviommu_9: pviommu9 {
compatible = "pkvm,pviommu";
id = <PLACEHOLDER>;
- #iommu-cells = <0>;
+ #iommu-cells = <1>;
};
};
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index 60bf21c..14f1fe5 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -452,8 +452,8 @@
const VM_DTBO_FILE_PATH: &str = "test_pvmfw_devices_vm_dtbo.dtbo";
const VM_DTBO_WITHOUT_SYMBOLS_FILE_PATH: &str =
"test_pvmfw_devices_vm_dtbo_without_symbols.dtbo";
+ const FDT_WITHOUT_IOMMUS_FILE_PATH: &str = "test_pvmfw_devices_without_iommus.dtb";
const FDT_FILE_PATH: &str = "test_pvmfw_devices_with_rng.dtb";
- const FDT_WITH_IOMMU_FILE_PATH: &str = "test_pvmfw_devices_with_rng_iommu.dtb";
const FDT_WITH_MULTIPLE_DEVICES_IOMMUS_FILE_PATH: &str =
"test_pvmfw_devices_with_multiple_devices_iommus.dtb";
const FDT_WITH_IOMMU_SHARING: &str = "test_pvmfw_devices_with_iommu_sharing.dtb";
@@ -464,7 +464,7 @@
path: CString,
reg: Vec<u8>,
interrupts: Vec<u8>,
- iommus: Vec<u32>, // pvIOMMU ids
+ iommus: Vec<u32>, // pvIOMMU id and vSID
}
impl AssignedDeviceNode {
@@ -536,6 +536,26 @@
}
#[test]
+ fn device_info_assigned_info_without_iommus() {
+ let mut fdt_data = fs::read(FDT_WITHOUT_IOMMUS_FILE_PATH).unwrap();
+ let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
+ let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
+ let vm_dtbo = VmDtbo::from_mut_slice(&mut vm_dtbo_data).unwrap();
+
+ let device_info = DeviceAssignmentInfo::parse(fdt, vm_dtbo).unwrap().unwrap();
+
+ let expected = [AssignedDeviceInfo {
+ node_path: CString::new("/backlight").unwrap(),
+ dtbo_node_path: cstr!("/fragment@backlight/__overlay__/backlight").into(),
+ reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
+ interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
+ iommus: vec![],
+ }];
+
+ assert_eq!(device_info.assigned_devices, expected);
+ }
+
+ #[test]
fn device_info_assigned_info() {
let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
@@ -549,7 +569,7 @@
dtbo_node_path: cstr!("/fragment@rng/__overlay__/rng").into(),
reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
- iommus: vec![],
+ iommus: vec![(PvIommu { id: 0x4 }, Vsid(0xFF0))],
}];
assert_eq!(device_info.assigned_devices, expected);
@@ -585,13 +605,19 @@
let light = vm_dtbo.node(cstr!("/fragment@rng/__overlay__/light")).unwrap();
assert_eq!(light, None);
+ let led = vm_dtbo.node(cstr!("/fragment@led/__overlay__/led")).unwrap();
+ assert_eq!(led, None);
+
+ let backlight = vm_dtbo.node(cstr!("/fragment@backlight/__overlay__/backlight")).unwrap();
+ assert_eq!(backlight, None);
+
let symbols_node = vm_dtbo.symbols().unwrap();
assert_eq!(symbols_node, None);
}
#[test]
fn device_info_patch() {
- let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
+ let mut fdt_data = fs::read(FDT_WITHOUT_IOMMUS_FILE_PATH).unwrap();
let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
let mut data = vec![0_u8; fdt_data.len() + vm_dtbo_data.len()];
let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
@@ -610,14 +636,14 @@
// Note: Intentionally not using AssignedDeviceNode for matching all props.
type FdtResult<T> = libfdt::Result<T>;
let expected: Vec<(FdtResult<&CStr>, FdtResult<Vec<u8>>)> = vec![
- (Ok(cstr!("android,rng,ignore-gctrl-reset")), Ok(Vec::new())),
- (Ok(cstr!("compatible")), Ok(Vec::from(*b"android,rng\0"))),
+ (Ok(cstr!("android,backlight,ignore-gctrl-reset")), Ok(Vec::new())),
+ (Ok(cstr!("compatible")), Ok(Vec::from(*b"android,backlight\0"))),
(Ok(cstr!("interrupts")), Ok(into_fdt_prop(vec![0x0, 0xF, 0x4]))),
(Ok(cstr!("iommus")), Ok(Vec::new())),
(Ok(cstr!("reg")), Ok(into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]))),
];
- let rng_node = platform_dt.node(cstr!("/rng")).unwrap().unwrap();
+ let rng_node = platform_dt.node(cstr!("/backlight")).unwrap().unwrap();
let mut properties: Vec<_> = rng_node
.properties()
.unwrap()
@@ -634,7 +660,7 @@
#[test]
fn device_info_overlay_iommu() {
- let mut fdt_data = fs::read(FDT_WITH_IOMMU_FILE_PATH).unwrap();
+ let mut fdt_data = fs::read(FDT_FILE_PATH).unwrap();
let mut vm_dtbo_data = fs::read(VM_DTBO_FILE_PATH).unwrap();
let fdt = Fdt::from_mut_slice(&mut fdt_data).unwrap();
let vm_dtbo = VmDtbo::from_mut_slice(&mut vm_dtbo_data).unwrap();
@@ -691,13 +717,13 @@
path: CString::new("/rng").unwrap(),
reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
- iommus: vec![0x4, 0xFF0, 0x9, 0xFF1],
+ iommus: vec![0x4, 0xFF0],
},
AssignedDeviceNode {
path: CString::new("/light").unwrap(),
reg: into_fdt_prop(vec![0x100, 0x9]),
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x5]),
- iommus: vec![0x40, 0xFFA, 0x50, 0xFFB, 0x60, 0xFFC],
+ iommus: vec![0x40, 0xFFA, 0x50, 0xFFB],
},
];
@@ -706,7 +732,7 @@
assert_eq!(node, Ok(expected));
}
let pviommus = collect_pviommus(platform_dt);
- assert_eq!(pviommus, Ok(vec![0x4, 0x9, 0x40, 0x50, 0x60]));
+ assert_eq!(pviommus, Ok(vec![0x4, 0x40, 0x50]));
}
#[test]
@@ -734,13 +760,13 @@
path: CString::new("/rng").unwrap(),
reg: into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]),
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x4]),
- iommus: vec![0x4, 0xFF0, 0x9, 0xFF1],
+ iommus: vec![0x4, 0xFF0],
},
AssignedDeviceNode {
- path: CString::new("/light").unwrap(),
+ path: CString::new("/led").unwrap(),
reg: into_fdt_prop(vec![0x100, 0x9]),
interrupts: into_fdt_prop(vec![0x0, 0xF, 0x5]),
- iommus: vec![0x9, 0xFF1, 0x40, 0xFFA],
+ iommus: vec![0x4, 0xFF0],
},
];
@@ -750,7 +776,7 @@
}
let pviommus = collect_pviommus(platform_dt);
- assert_eq!(pviommus, Ok(vec![0x4, 0x9, 0x40]));
+ assert_eq!(pviommus, Ok(vec![0x4]));
}
#[test]
diff --git a/pvmfw/testdata/test_crosvm_dt_base.dtsi b/pvmfw/testdata/test_crosvm_dt_base.dtsi
new file mode 100644
index 0000000..0c1a311
--- /dev/null
+++ b/pvmfw/testdata/test_crosvm_dt_base.dtsi
@@ -0,0 +1,152 @@
+/dts-v1/;
+/plugin/;
+
+// This is generated manually by removing unassigned pvIOMMU nodes
+// from patched platform.dts.
+
+/ {
+ interrupt-parent = <0x01>;
+ compatible = "linux,dummy-virt";
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+
+ chosen {
+ bootargs = "panic=-1 crashkernel=31M";
+ linux,initrd-end = <0x811d6cb8>;
+ linux,initrd-start = <0x81000000>;
+ stdout-path = "/uart@3f8";
+ 1,pci-probe-only = <0x01>;
+ kaslr-seed = <0x00 0x00>;
+ avf,strict-boot;
+ avf,new-instance;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00 0x80000000 0x00 0x10000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+ ranges;
+
+ restricted_dma_reserved {
+ compatible = "restricted-dma-pool";
+ size = <0x00 0xe00000>;
+ alignment = <0x00 0x1000>;
+ phandle = <0x02>;
+ };
+
+ dice {
+ compatible = "google,open-dice";
+ no-map;
+ reg = <0x00 0x7fe25000 0x00 0x1000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <0x01>;
+ #size-cells = <0x00>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,arm-v8";
+ enable-method = "psci";
+ reg = <0x00>;
+ };
+ };
+
+ intc {
+ compatible = "arm,gic-v3";
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+ #interrupt-cells = <0x03>;
+ interrupt-controller;
+ reg = <0x00 0x3fff0000 0x00 0x10000 0x00 0x3ffd0000 0x00 0x20000>;
+ phandle = <0x01>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ always-on;
+ interrupts = <0x01 0x0d 0x108 0x01 0x0e 0x108 0x01 0x0b 0x108 0x01 0x0a 0x108>;
+ };
+
+ uart@2e8 {
+ compatible = "ns16550a";
+ reg = <0x00 0x2e8 0x00 0x08>;
+ clock-frequency = <0x1c2000>;
+ interrupts = <0x00 0x02 0x01>;
+ };
+
+ uart@2f8 {
+ compatible = "ns16550a";
+ reg = <0x00 0x2f8 0x00 0x08>;
+ clock-frequency = <0x1c2000>;
+ interrupts = <0x00 0x02 0x01>;
+ };
+
+ uart@3e8 {
+ compatible = "ns16550a";
+ reg = <0x00 0x3e8 0x00 0x08>;
+ clock-frequency = <0x1c2000>;
+ interrupts = <0x00 0x00 0x01>;
+ };
+
+ uart@3f8 {
+ compatible = "ns16550a";
+ reg = <0x00 0x3f8 0x00 0x08>;
+ clock-frequency = <0x1c2000>;
+ interrupts = <0x00 0x00 0x01>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "hvc";
+ };
+
+ pci {
+ compatible = "pci-host-cam-generic";
+ device_type = "pci";
+ #address-cells = <0x03>;
+ #size-cells = <0x02>;
+ #interrupt-cells = <0x01>;
+ dma-coherent;
+ memory-region = <0x02>;
+ ranges = <0x3000000 0x00 0x2000000 0x00 0x2000000 0x00 0x2000000 0x3000000 0x00 0x90800000 0x00 0x90800000 0xff 0x6f800000>;
+ bus-range = <0x00 0x00>;
+ reg = <0x00 0x10000 0x00 0x1000000>;
+ interrupt-map = <0x800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x04 0x04 0x1000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x05 0x04 0x1800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x06 0x04 0x2000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x07 0x04 0x2800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x08 0x04 0x3000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x09 0x04 0x3800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0a 0x04 0x4000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0b 0x04 0x4800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0c 0x04>;
+ interrupt-map-mask = <0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07>;
+ };
+
+ pclk@3M {
+ compatible = "fixed-clock";
+ clock-frequency = <0x2fefd8>;
+ #clock-cells = <0x00>;
+ phandle = <0x03>;
+ };
+
+ rtc@2000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x41030>;
+ reg = <0x00 0x2000 0x00 0x1000>;
+ interrupts = <0x00 0x01 0x04>;
+ clock-names = "apb_pclk";
+ clocks = <0x03>;
+ };
+
+ vmwdt@3000 {
+ compatible = "qemu,vcpu-stall-detector";
+ reg = <0x00 0x3000 0x00 0x1000>;
+ clock-frequency = <0x0a>;
+ timeout-sec = <0x08>;
+ };
+
+ __symbols__ {
+ swiotlb = "/reserved-memory/restricted_dma_reserved";
+ intc = "/intc";
+ clk = "/pclk@3M";
+ };
+};
diff --git a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
index e85b55b..da08694 100644
--- a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo.dts
@@ -21,6 +21,33 @@
light {
compatible = "android,light";
version = <0x1 0x2>;
+ android,pvmfw,phy-reg = <0x0 0xF00000 0x1000>;
+ android,pvmfw,phy-iommu = <0x0 0x40000>, <0x0 0x50000>;
+ android,pvmfw,phy-sid = <4>, <5>;
+ };
+ };
+ };
+
+ fragment@led {
+ target-path = "/";
+ __overlay__ {
+ led {
+ compatible = "android,led";
+ prop = <0x555>;
+ android,pvmfw,phy-reg = <0x0 0x12000000 0x1000>;
+ android,pvmfw,phy-iommu = <0x0 0x12E40000>;
+ android,pvmfw,phy-sid = <3>;
+ };
+ };
+ };
+
+ fragment@backlight {
+ target-path = "/";
+ __overlay__ {
+ backlight {
+ compatible = "android,backlight";
+ android,backlight,ignore-gctrl-reset;
+ android,pvmfw,phy-reg = <0x0 0x300 0x100>;
};
};
};
@@ -28,5 +55,7 @@
__symbols__ {
rng = "/fragment@rng/__overlay__/rng";
sensor = "/fragment@sensor/__overlay__/light";
+ led = "/fragment@led/__overlay__/led";
+ backlight = "/fragment@backlight/__overlay__/backlight";
};
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
index 08444ac..18b9e79 100644
--- a/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_vm_dtbo_without_symbols.dts
@@ -21,6 +21,22 @@
light {
compatible = "android,light";
version = <0x1 0x2>;
+ android,pvmfw,phy-reg = <0x0 0xF00000 0x1000>;
+ android,pvmfw,phy-iommu = <0x0 0x40000>, <0x0 0x50000>;
+ android,pvmfw,phy-sid = <4>, <5>;
+ };
+ };
+ };
+
+ fragment@led {
+ target-path = "/";
+ __overlay__ {
+ led {
+ compatible = "android,led";
+ prop;
+ android,pvmfw,phy-reg = <0x0 0x12F00000 0x1000>;
+ android,pvmfw,phy-iommu = <0x0 0x20000>, <0x0 0x30000>;
+ android,pvmfw,phy-sid = <7>, <8>;
};
};
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_with_iommu_id_conflict.dts b/pvmfw/testdata/test_pvmfw_devices_with_iommu_id_conflict.dts
index 199a5ce..70b633c 100644
--- a/pvmfw/testdata/test_pvmfw_devices_with_iommu_id_conflict.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_with_iommu_id_conflict.dts
@@ -1,54 +1,16 @@
/dts-v1/;
/plugin/;
+/include/ "test_crosvm_dt_base.dtsi"
+
/ {
- chosen {
- stdout-path = "/uart@3f8";
- linux,pci-probe-only = <1>;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
- swiotlb: restricted_dma_reserved {
- compatible = "restricted-dma-pool";
- reg = <0xFFFFFFFF>;
- size = <0xFFFFFFFF>;
- alignment = <0xFFFFFFFF>;
- };
-
- dice {
- compatible = "google,open-dice";
- no-map;
- reg = <0xFFFFFFFF>;
- };
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- };
- cpu@1 {
- device_type = "cpu";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
- };
-
rng@90000000 {
compatible = "android,rng";
reg = <0x0 0x9 0x0 0xFF>;
interrupts = <0x0 0xF 0x4>;
google,eh,ignore-gctrl-reset;
status = "okay";
- iommus = <&pviommu_0>, <&pviommu_1>;
+ iommus = <&pviommu_0 0x0>, <&pviommu_1 0x1>;
};
pviommu_0: pviommu0 {
@@ -67,7 +29,7 @@
compatible = "android,light";
reg = <0x100 0x9>;
interrupts = <0x0 0xF 0x5>;
- iommus = <&pviommu_0>, <&pviommu_a>, <&pviommu_b>;
+ iommus = <&pviommu_a 0xA>, <&pviommu_b 0xB>;
};
pviommu_a: pviommua {
diff --git a/pvmfw/testdata/test_pvmfw_devices_with_iommu_sharing.dts b/pvmfw/testdata/test_pvmfw_devices_with_iommu_sharing.dts
index 4906064..7c6d2f2 100644
--- a/pvmfw/testdata/test_pvmfw_devices_with_iommu_sharing.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_with_iommu_sharing.dts
@@ -1,61 +1,23 @@
/dts-v1/;
/plugin/;
+/include/ "test_crosvm_dt_base.dtsi"
+
/ {
- chosen {
- stdout-path = "/uart@3f8";
- linux,pci-probe-only = <1>;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
- swiotlb: restricted_dma_reserved {
- compatible = "restricted-dma-pool";
- reg = <0xFFFFFFFF>;
- size = <0xFFFFFFFF>;
- alignment = <0xFFFFFFFF>;
- };
-
- dice {
- compatible = "google,open-dice";
- no-map;
- reg = <0xFFFFFFFF>;
- };
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- };
- cpu@1 {
- device_type = "cpu";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
- };
-
rng@90000000 {
compatible = "android,rng";
reg = <0x0 0x9 0x0 0xFF>;
interrupts = <0x0 0xF 0x4>;
google,eh,ignore-gctrl-reset;
status = "okay";
- iommus = <&pviommu_0 0xFF0>, <&pviommu_1 0xFF1>;
+ iommus = <&pviommu_0 0xFF0>;
};
- light@70000000 {
+ led@70000000 {
compatible = "android,light";
reg = <0x100 0x9>;
interrupts = <0x0 0xF 0x5>;
- iommus = <&pviommu_1 0xFF1>, <&pviommu_a 0xFFA>;
+ iommus = <&pviommu_0 0xFF0>;
};
pviommu_0: pviommu0 {
@@ -63,16 +25,4 @@
id = <0x4>;
#iommu-cells = <1>;
};
-
- pviommu_1: pviommu1 {
- compatible = "pkvm,pviommu";
- id = <0x9>;
- #iommu-cells = <1>;
- };
-
- pviommu_a: pviommua {
- compatible = "pkvm,pviommu";
- id = <0x40>;
- #iommu-cells = <1>;
- };
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_with_multiple_devices_iommus.dts b/pvmfw/testdata/test_pvmfw_devices_with_multiple_devices_iommus.dts
index 959cd23..76c99c9 100644
--- a/pvmfw/testdata/test_pvmfw_devices_with_multiple_devices_iommus.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_with_multiple_devices_iommus.dts
@@ -1,54 +1,15 @@
/dts-v1/;
/plugin/;
+/include/ "test_crosvm_dt_base.dtsi"
/ {
- chosen {
- stdout-path = "/uart@3f8";
- linux,pci-probe-only = <1>;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
- swiotlb: restricted_dma_reserved {
- compatible = "restricted-dma-pool";
- reg = <0xFFFFFFFF>;
- size = <0xFFFFFFFF>;
- alignment = <0xFFFFFFFF>;
- };
-
- dice {
- compatible = "google,open-dice";
- no-map;
- reg = <0xFFFFFFFF>;
- };
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- };
- cpu@1 {
- device_type = "cpu";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
- };
-
rng@90000000 {
compatible = "android,rng";
reg = <0x0 0x9 0x0 0xFF>;
interrupts = <0x0 0xF 0x4>;
google,eh,ignore-gctrl-reset;
status = "okay";
- iommus = <&pviommu_0 0xFF0>, <&pviommu_1 0xFF1>;
+ iommus = <&pviommu_0 0xFF0>;
};
pviommu_0: pviommu0 {
@@ -57,17 +18,11 @@
#iommu-cells = <1>;
};
- pviommu_1: pviommu1 {
- compatible = "pkvm,pviommu";
- id = <0x9>;
- #iommu-cells = <1>;
- };
-
light@70000000 {
compatible = "android,light";
reg = <0x100 0x9>;
interrupts = <0x0 0xF 0x5>;
- iommus = <&pviommu_a 0xFFA>, <&pviommu_b 0xFFB>, <&pviommu_c 0xFFC>;
+ iommus = <&pviommu_a 0xFFA>, <&pviommu_b 0xFFB>;
};
pviommu_a: pviommua {
@@ -81,10 +36,4 @@
id = <0x50>;
#iommu-cells = <1>;
};
-
- pviommu_c: pviommuc {
- compatible = "pkvm,pviommu";
- id = <0x60>;
- #iommu-cells = <1>;
- };
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_with_rng.dts b/pvmfw/testdata/test_pvmfw_devices_with_rng.dts
index f24fd65..a987098 100644
--- a/pvmfw/testdata/test_pvmfw_devices_with_rng.dts
+++ b/pvmfw/testdata/test_pvmfw_devices_with_rng.dts
@@ -1,52 +1,21 @@
/dts-v1/;
/plugin/;
+/include/ "test_crosvm_dt_base.dtsi"
+
/ {
- chosen {
- stdout-path = "/uart@3f8";
- linux,pci-probe-only = <1>;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
- swiotlb: restricted_dma_reserved {
- compatible = "restricted-dma-pool";
- reg = <0xFFFFFFFF>;
- size = <0xFFFFFFFF>;
- alignment = <0xFFFFFFFF>;
- };
-
- dice {
- compatible = "google,open-dice";
- no-map;
- reg = <0xFFFFFFFF>;
- };
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- };
- cpu@1 {
- device_type = "cpu";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
- };
-
rng@90000000 {
compatible = "android,rng";
reg = <0x0 0x9 0x0 0xFF>;
interrupts = <0x0 0xF 0x4>;
google,eh,ignore-gctrl-reset;
status = "okay";
+ iommus = <&pviommu_0 0xFF0>;
+ };
+
+ pviommu_0: pviommu0 {
+ compatible = "pkvm,pviommu";
+ id = <0x4>;
+ #iommu-cells = <1>;
};
};
diff --git a/pvmfw/testdata/test_pvmfw_devices_with_rng_iommu.dts b/pvmfw/testdata/test_pvmfw_devices_with_rng_iommu.dts
deleted file mode 100644
index 8c04b39..0000000
--- a/pvmfw/testdata/test_pvmfw_devices_with_rng_iommu.dts
+++ /dev/null
@@ -1,59 +0,0 @@
-/dts-v1/;
-/plugin/;
-
-/ {
- chosen {
- stdout-path = "/uart@3f8";
- linux,pci-probe-only = <1>;
- };
-
- memory {
- device_type = "memory";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
- swiotlb: restricted_dma_reserved {
- compatible = "restricted-dma-pool";
- reg = <0xFFFFFFFF>;
- size = <0xFFFFFFFF>;
- alignment = <0xFFFFFFFF>;
- };
-
- dice {
- compatible = "google,open-dice";
- no-map;
- reg = <0xFFFFFFFF>;
- };
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- cpu@0 {
- device_type = "cpu";
- };
- cpu@1 {
- device_type = "cpu";
- reg = <0x00 0x80000000 0xFFFFFFFF>;
- };
- };
-
- rng@90000000 {
- compatible = "android,rng";
- reg = <0x0 0x9 0x0 0xFF>;
- interrupts = <0x0 0xF 0x4>;
- google,eh,ignore-gctrl-reset;
- status = "okay";
- iommus = <&pviommu_0 0xFF0>;
- };
-
- pviommu_0: pviommu0 {
- compatible = "pkvm,pviommu";
- id = <0x4>;
- #iommu-cells = <1>;
- };
-};
diff --git a/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts b/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts
new file mode 100644
index 0000000..2036c9c
--- /dev/null
+++ b/pvmfw/testdata/test_pvmfw_devices_without_iommus.dts
@@ -0,0 +1,14 @@
+/dts-v1/;
+/plugin/;
+
+/include/ "test_crosvm_dt_base.dtsi"
+
+/ {
+ backlight@90000000 {
+ compatible = "android,backlight";
+ reg = <0x0 0x9 0x0 0xFF>;
+ interrupts = <0x0 0xF 0x4>;
+ google,eh,ignore-gctrl-reset;
+ status = "okay";
+ };
+};
diff --git a/rialto/tests/test.rs b/rialto/tests/test.rs
index c1a8394..029895f 100644
--- a/rialto/tests/test.rs
+++ b/rialto/tests/test.rs
@@ -226,7 +226,8 @@
parent_certificate: &X509Certificate,
) -> Result<()> {
let cose_mac = CoseMac0::from_slice(maced_public_key)?;
- let authority_public_key = EcKey::from_cose_public_key(&cose_mac.payload.unwrap()).unwrap();
+ let authority_public_key =
+ EcKey::from_cose_public_key_slice(&cose_mac.payload.unwrap()).unwrap();
let (remaining, cert) = X509Certificate::from_der(certificate)?;
assert!(remaining.is_empty());
@@ -244,7 +245,7 @@
let cose_sign = CoseSign::from_slice(&csr.signed_csr_payload)?;
let csr_payload =
cose_sign.payload.as_ref().and_then(|v| CsrPayload::from_cbor_slice(v).ok()).unwrap();
- let subject_public_key = EcKey::from_cose_public_key(&csr_payload.public_key).unwrap();
+ let subject_public_key = EcKey::from_cose_public_key_slice(&csr_payload.public_key).unwrap();
let expected_spki_data =
PKey::try_from(subject_public_key).unwrap().subject_public_key_info().unwrap();
let (remaining, expected_spki) = SubjectPublicKeyInfo::from_der(&expected_spki_data)?;
diff --git a/service_vm/requests/src/client_vm.rs b/service_vm/requests/src/client_vm.rs
index ddf230b..4e87136 100644
--- a/service_vm/requests/src/client_vm.rs
+++ b/service_vm/requests/src/client_vm.rs
@@ -62,7 +62,7 @@
// the DICE chain in `cose_sign`.
// Verifies the second signature with the public key in the CSR payload.
- let ec_public_key = EcKey::from_cose_public_key(&csr_payload.public_key)?;
+ let ec_public_key = EcKey::from_cose_public_key_slice(&csr_payload.public_key)?;
cose_sign.verify_signature(ATTESTATION_KEY_SIGNATURE_INDEX, aad, |signature, message| {
ecdsa_verify(&ec_public_key, signature, message)
})?;