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};
diff --git a/libs/smccc/Android.bp b/libs/smccc/Android.bp
deleted file mode 100644
index 96943d8..0000000
--- a/libs/smccc/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_library_rlib {
-    name: "libsmccc",
-    crate_name: "smccc",
-    srcs: ["src/lib.rs"],
-    prefer_rlib: true,
-    rustlibs: [
-        "libpsci",
-    ],
-    no_stdlibs: true,
-    stdlibs: [
-        "libcore.rust_sysroot",
-    ],
-    apex_available: ["com.android.virt"],
-}
diff --git a/libs/smccc/src/lib.rs b/libs/smccc/src/lib.rs
deleted file mode 100644
index 2cd31dc..0000000
--- a/libs/smccc/src/lib.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.
-
-//! Structs and functions for making SMCCC calls following the SMC Calling
-//! Convention version 1.4.
-
-#![no_std]
-
-mod smccc;
-
-pub use smccc::{checked_hvc64, checked_hvc64_expect_zero, hvc64, Error, Result};
diff --git a/libs/smccc/src/smccc.rs b/libs/smccc/src/smccc.rs
deleted file mode 100644
index c0070e0..0000000
--- a/libs/smccc/src/smccc.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2022, 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.
-
-//! Structs and functions for making SMCCC calls.
-
-use core::{fmt, result};
-// Ideally, smccc shouldn't depend on psci. Smccc isn't split as a separate
-// upstream crate currently mostly for maintenance consideration.
-// See b/245889995 for more context.
-pub use psci::smccc::hvc64;
-
-/// Standard SMCCC error values as described in DEN 0028E.
-#[derive(Debug, Clone)]
-pub enum Error {
-    /// The call is not supported by the implementation.
-    NotSupported,
-    /// The call is deemed not required by the implementation.
-    NotRequired,
-    /// One of the call parameters has a non-supported value.
-    InvalidParameter,
-    /// Negative values indicate error.
-    Unknown(i64),
-    /// The call returned a positive value when 0 was expected.
-    Unexpected(u64),
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            Self::NotSupported => write!(f, "SMCCC call not supported"),
-            Self::NotRequired => write!(f, "SMCCC call not required"),
-            Self::InvalidParameter => write!(f, "SMCCC call received non-supported value"),
-            Self::Unexpected(v) => write!(f, "Unexpected SMCCC return value {} ({0:#x})", v),
-            Self::Unknown(e) => write!(f, "Unknown SMCCC return value {} ({0:#x})", e),
-        }
-    }
-}
-
-/// Result type with smccc::Error.
-pub type Result<T> = result::Result<T, Error>;
-
-/// Makes a checked HVC64 call to the hypervisor, following the SMC Calling Convention version 1.4.
-/// Returns Ok only when the return code is 0.
-pub fn checked_hvc64_expect_zero(function: u32, args: [u64; 17]) -> Result<()> {
-    match checked_hvc64(function, args)? {
-        0 => Ok(()),
-        v => Err(Error::Unexpected(v)),
-    }
-}
-
-/// Makes a checked HVC64 call to the hypervisor, following the SMC Calling Convention version 1.4.
-/// Returns Ok with the return code only when the return code >= 0.
-pub fn checked_hvc64(function: u32, args: [u64; 17]) -> Result<u64> {
-    match hvc64(function, args)[0] as i64 {
-        ret if ret >= 0 => Ok(ret as u64),
-        -1 => Err(Error::NotSupported),
-        -2 => Err(Error::NotRequired),
-        -3 => Err(Error::InvalidParameter),
-        ret => Err(Error::Unknown(ret)),
-    }
-}
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 0571c36..8be5f7d 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -21,10 +21,10 @@
         "liblibfdt",
         "liblog_rust_nostd",
         "libonce_cell_nostd",
+        "libpsci",
         "libpvmfw_avb_nostd",
         "libpvmfw_embedded_key",
         "libpvmfw_fdt_template",
-        "libsmccc",
         "libstatic_assertions",
         "libtinyvec_nostd",
         "libuuid_nostd",
diff --git a/pvmfw/src/hvc.rs b/pvmfw/src/hvc.rs
index 6c5017f..1e2bca2 100644
--- a/pvmfw/src/hvc.rs
+++ b/pvmfw/src/hvc.rs
@@ -15,6 +15,11 @@
 //! Wrappers around calls to the hypervisor.
 
 pub mod trng;
+use self::trng::Error;
+use psci::smccc::{
+    error::{positive_or_error_64, success_or_error_64},
+    hvc64,
+};
 
 // TODO(b/272226230): Move all the trng functions to trng module
 const ARM_SMCCC_TRNG_VERSION: u32 = 0x8400_0050;
@@ -30,7 +35,7 @@
 pub fn trng_version() -> trng::Result<(u16, u16)> {
     let args = [0u64; 17];
 
-    let version = trng::hvc64(ARM_SMCCC_TRNG_VERSION, args)?[0];
+    let version = positive_or_error_64::<Error>(hvc64(ARM_SMCCC_TRNG_VERSION, args)[0])?;
     Ok(((version >> 16) as u16, version as u16))
 }
 
@@ -40,7 +45,8 @@
     let mut args = [0u64; 17];
     args[0] = nbits;
 
-    let regs = trng::hvc64_expect_zero(ARM_SMCCC_TRNG_RND64, args)?;
+    let regs = hvc64(ARM_SMCCC_TRNG_RND64, args);
+    success_or_error_64::<Error>(regs[0])?;
 
     Ok((regs[1], regs[2], regs[3]))
 }
diff --git a/pvmfw/src/hvc/trng.rs b/pvmfw/src/hvc/trng.rs
index 05ecc6b..6331d66 100644
--- a/pvmfw/src/hvc/trng.rs
+++ b/pvmfw/src/hvc/trng.rs
@@ -42,23 +42,16 @@
     }
 }
 
+impl From<i64> for Error {
+    fn from(value: i64) -> Self {
+        match value {
+            -1 => Error::NotSupported,
+            -2 => Error::InvalidParameter,
+            -3 => Error::NoEntropy,
+            _ if value < 0 => Error::Unknown(value),
+            _ => Error::Unexpected(value as u64),
+        }
+    }
+}
+
 pub type Result<T> = result::Result<T, Error>;
-
-pub fn hvc64(function: u32, args: [u64; 17]) -> Result<[u64; 18]> {
-    let res = smccc::hvc64(function, args);
-    match res[0] as i64 {
-        ret if ret >= 0 => Ok(res),
-        -1 => Err(Error::NotSupported),
-        -2 => Err(Error::InvalidParameter),
-        -3 => Err(Error::NoEntropy),
-        ret => Err(Error::Unknown(ret)),
-    }
-}
-
-pub fn hvc64_expect_zero(function: u32, args: [u64; 17]) -> Result<[u64; 18]> {
-    let res = hvc64(function, args)?;
-    match res[0] {
-        0 => Ok(res),
-        v => Err(Error::Unexpected(v)),
-    }
-}