Use new psci::smccc error handling rather than smccc library.
Test: Built pvmfw and rialto
Change-Id: I79eb0ca966a6e970dde1c1d73a55db38c549df5c
diff --git a/libs/hyp/Android.bp b/libs/hyp/Android.bp
index bc66190..e4353c8 100644
--- a/libs/hyp/Android.bp
+++ b/libs/hyp/Android.bp
@@ -8,7 +8,7 @@
srcs: ["src/lib.rs"],
prefer_rlib: true,
rustlibs: [
- "libsmccc",
+ "libpsci",
],
no_stdlibs: true,
stdlibs: [
diff --git a/libs/hyp/src/error.rs b/libs/hyp/src/error.rs
index 20a0cff..4e25e7f 100644
--- a/libs/hyp/src/error.rs
+++ b/libs/hyp/src/error.rs
@@ -14,6 +14,7 @@
//! Error and Result types for hypervisor.
+use crate::KvmError;
use core::{fmt, result};
/// Result type with hypervisor error.
@@ -24,8 +25,8 @@
pub enum Error {
/// MMIO guard is not supported.
MmioGuardNotsupported,
- /// Failed to invoke a certain HVC function.
- HvcError(smccc::Error, u32),
+ /// Failed to invoke a certain KVM HVC function.
+ KvmError(KvmError, u32),
/// The MMIO_GUARD granule used by the hypervisor is not supported.
UnsupportedMmioGuardGranule(usize),
}
@@ -34,7 +35,7 @@
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::MmioGuardNotsupported => write!(f, "MMIO guard is not supported"),
- Self::HvcError(e, function_id) => {
+ Self::KvmError(e, function_id) => {
write!(f, "Failed to invoke the HVC function with function ID {function_id}: {e}")
}
Self::UnsupportedMmioGuardGranule(g) => {
diff --git a/libs/hyp/src/hypervisor/kvm.rs b/libs/hyp/src/hypervisor/kvm.rs
index 615c75a..c0c1ac9 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/libs/hyp/src/hypervisor/kvm.rs
@@ -17,6 +17,48 @@
use super::common::Hypervisor;
use crate::error::{Error, Result};
use crate::util::{page_address, SIZE_4KB};
+use core::fmt::{self, Display, Formatter};
+use psci::smccc::{
+ error::{positive_or_error_64, success_or_error_32, success_or_error_64},
+ hvc64,
+};
+
+/// Error from a KVM HVC call.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum KvmError {
+ /// The call is not supported by the implementation.
+ NotSupported,
+ /// One of the call parameters has a non-supported value.
+ InvalidParameter,
+ /// There was an unexpected return value.
+ Unknown(i64),
+}
+
+impl From<i64> for KvmError {
+ fn from(value: i64) -> Self {
+ match value {
+ -1 => KvmError::NotSupported,
+ -3 => KvmError::InvalidParameter,
+ _ => KvmError::Unknown(value),
+ }
+ }
+}
+
+impl From<i32> for KvmError {
+ fn from(value: i32) -> Self {
+ i64::from(value).into()
+ }
+}
+
+impl Display for KvmError {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match self {
+ Self::NotSupported => write!(f, "KVM call not supported"),
+ Self::InvalidParameter => write!(f, "KVM call received non-supported value"),
+ Self::Unknown(e) => write!(f, "Unknown return value from KVM {} ({0:#x})", e),
+ }
+ }
+}
const ARM_SMCCC_KVM_FUNC_HYP_MEMINFO: u32 = 0xc6000002;
const ARM_SMCCC_KVM_FUNC_MEM_SHARE: u32 = 0xc6000003;
@@ -45,17 +87,8 @@
// TODO(b/277859415): pKVM returns a i32 instead of a i64 in T.
// Drop this hack once T reaches EoL.
- let is_i32_error_code = |n| u32::try_from(n).ok().filter(|v| (*v as i32) < 0).is_some();
- match smccc::checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args) {
- Err(smccc::Error::Unexpected(e)) if is_i32_error_code(e) => match e as u32 as i32 {
- -1 => Err(smccc::Error::NotSupported),
- -2 => Err(smccc::Error::NotRequired),
- -3 => Err(smccc::Error::InvalidParameter),
- ret => Err(smccc::Error::Unknown(ret as i64)),
- },
- res => res,
- }
- .map_err(|e| Error::HvcError(e, VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID))
+ 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))
}
fn mmio_guard_unmap(&self, addr: usize) -> Result<()> {
@@ -64,9 +97,9 @@
// TODO(b/277860860): pKVM returns NOT_SUPPORTED for SUCCESS in T.
// Drop this hack once T reaches EoL.
- match smccc::checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args) {
- Err(smccc::Error::NotSupported) | Ok(_) => Ok(()),
- Err(e) => Err(Error::HvcError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
+ 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)),
}
}
@@ -100,17 +133,17 @@
fn mmio_guard_enroll() -> Result<()> {
let args = [0u64; 17];
- match smccc::checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID, args) {
+ match success_or_error_64(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID, args)[0]) {
Ok(_) => Ok(()),
- Err(smccc::Error::NotSupported) => Err(Error::MmioGuardNotsupported),
- Err(e) => Err(Error::HvcError(e, VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID)),
+ Err(KvmError::NotSupported) => Err(Error::MmioGuardNotsupported),
+ Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID)),
}
}
fn checked_hvc64_expect_zero(function: u32, args: [u64; 17]) -> Result<()> {
- smccc::checked_hvc64_expect_zero(function, args).map_err(|e| Error::HvcError(e, function))
+ success_or_error_64(hvc64(function, args)[0]).map_err(|e| Error::KvmError(e, function))
}
fn checked_hvc64(function: u32, args: [u64; 17]) -> Result<u64> {
- smccc::checked_hvc64(function, args).map_err(|e| Error::HvcError(e, function))
+ positive_or_error_64(hvc64(function, args)[0]).map_err(|e| Error::KvmError(e, function))
}
diff --git a/libs/hyp/src/hypervisor/mod.rs b/libs/hyp/src/hypervisor/mod.rs
index 87925d2..a694029 100644
--- a/libs/hyp/src/hypervisor/mod.rs
+++ b/libs/hyp/src/hypervisor/mod.rs
@@ -18,6 +18,7 @@
mod kvm;
pub use common::Hypervisor;
+pub use kvm::KvmError;
use kvm::KvmHypervisor;
static HYPERVISOR: HypervisorBackend = HypervisorBackend::Kvm;
diff --git a/libs/hyp/src/lib.rs b/libs/hyp/src/lib.rs
index 66c78f4..6db6ba8 100644
--- a/libs/hyp/src/lib.rs
+++ b/libs/hyp/src/lib.rs
@@ -21,4 +21,4 @@
mod util;
pub use error::{Error, Result};
-pub use hypervisor::{get_hypervisor, Hypervisor};
+pub use hypervisor::{get_hypervisor, Hypervisor, KvmError};