Turn hypervisor backends module into a library

Break out the code in the hyp module of libvmbase
into its own library such that it can be used from
other contexts such as the Trusty kernel.

Update uses in guest/{pvmfw,rialto}.

Add Trusty build rules for the new library.

Test: atest
Test: build.py generic-x86_64-test
Change-Id: I68670549c8c8e1b3c8539c2c297e2ca1ba24edfb
diff --git a/libs/libvmbase/Android.bp b/libs/libvmbase/Android.bp
index c4e8385..3088633 100644
--- a/libs/libvmbase/Android.bp
+++ b/libs/libvmbase/Android.bp
@@ -81,6 +81,7 @@
         "libbuddy_system_allocator",
         "libcfg_if",
         "libcstr",
+        "libhypervisor_backends",
         "liblibfdt_nostd",
         "liblog_rust_nostd",
         "libonce_cell_nostd",
diff --git a/libs/libvmbase/src/entry.rs b/libs/libvmbase/src/entry.rs
index f442a32..2433722 100644
--- a/libs/libvmbase/src/entry.rs
+++ b/libs/libvmbase/src/entry.rs
@@ -15,7 +15,7 @@
 //! Rust entry point.
 
 use crate::{
-    bionic, console, heap, hyp,
+    bionic, console, heap,
     layout::{UART_ADDRESSES, UART_PAGE_ADDR},
     logger,
     memory::{PAGE_SIZE, SIZE_16KB, SIZE_4KB},
@@ -23,10 +23,11 @@
     rand,
 };
 use core::mem::size_of;
+use hypervisor_backends::{get_mmio_guard, Error};
 use static_assertions::const_assert_eq;
 
-fn try_console_init() -> Result<(), hyp::Error> {
-    if let Some(mmio_guard) = hyp::get_mmio_guard() {
+fn try_console_init() -> Result<(), Error> {
+    if let Some(mmio_guard) = get_mmio_guard() {
         mmio_guard.enroll()?;
 
         // TODO(ptosi): Use MmioSharer::share() to properly track this MMIO_GUARD_MAP.
diff --git a/libs/libvmbase/src/hyp.rs b/libs/libvmbase/src/hyp.rs
deleted file mode 100644
index 1cc2ca7..0000000
--- a/libs/libvmbase/src/hyp.rs
+++ /dev/null
@@ -1,23 +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.
-
-//! This library provides wrappers around various hypervisor backends.
-
-mod error;
-mod hypervisor;
-
-pub use error::{Error, Result};
-pub use hypervisor::{
-    get_device_assigner, get_mem_sharer, get_mmio_guard, DeviceAssigningHypervisor, KvmError,
-};
diff --git a/libs/libvmbase/src/hyp/error.rs b/libs/libvmbase/src/hyp/error.rs
deleted file mode 100644
index e9c37e1..0000000
--- a/libs/libvmbase/src/hyp/error.rs
+++ /dev/null
@@ -1,56 +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.
-
-//! Error and Result types for hypervisor.
-
-use core::{fmt, result};
-
-use super::hypervisor::{GeniezoneError, KvmError};
-use uuid::Uuid;
-
-/// Result type with hypervisor error.
-pub type Result<T> = result::Result<T, Error>;
-
-/// Hypervisor error.
-#[derive(Debug, Clone)]
-pub enum Error {
-    /// MMIO guard is not supported.
-    MmioGuardNotSupported,
-    /// Failed to invoke a certain KVM HVC function.
-    KvmError(KvmError, u32),
-    /// Failed to invoke GenieZone HVC function.
-    GeniezoneError(GeniezoneError, u32),
-    /// Unsupported Hypervisor
-    UnsupportedHypervisorUuid(Uuid),
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            Self::MmioGuardNotSupported => write!(f, "MMIO guard is not supported"),
-            Self::KvmError(e, function_id) => {
-                write!(f, "Failed to invoke the HVC function with function ID {function_id}: {e}")
-            }
-            Self::GeniezoneError(e, function_id) => {
-                write!(
-                    f,
-                    "Failed to invoke GenieZone HVC function with function ID {function_id}: {e}"
-                )
-            }
-            Self::UnsupportedHypervisorUuid(u) => {
-                write!(f, "Unsupported Hypervisor UUID {u}")
-            }
-        }
-    }
-}
diff --git a/libs/libvmbase/src/hyp/hypervisor.rs b/libs/libvmbase/src/hyp/hypervisor.rs
deleted file mode 100644
index 1b45f38..0000000
--- a/libs/libvmbase/src/hyp/hypervisor.rs
+++ /dev/null
@@ -1,127 +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.
-
-//! Wrappers around hypervisor back-ends.
-
-mod common;
-mod geniezone;
-mod gunyah;
-mod kvm;
-
-use super::{Error, Result};
-use alloc::boxed::Box;
-use common::Hypervisor;
-pub use common::{DeviceAssigningHypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
-pub use geniezone::GeniezoneError;
-use geniezone::GeniezoneHypervisor;
-use gunyah::GunyahHypervisor;
-pub use kvm::KvmError;
-use kvm::{ProtectedKvmHypervisor, RegularKvmHypervisor};
-use once_cell::race::OnceBox;
-use smccc::hvc64;
-use uuid::Uuid;
-
-enum HypervisorBackend {
-    RegularKvm,
-    Gunyah,
-    Geniezone,
-    ProtectedKvm,
-}
-
-impl HypervisorBackend {
-    fn get_hypervisor(&self) -> &'static dyn Hypervisor {
-        match self {
-            Self::RegularKvm => &RegularKvmHypervisor,
-            Self::Gunyah => &GunyahHypervisor,
-            Self::Geniezone => &GeniezoneHypervisor,
-            Self::ProtectedKvm => &ProtectedKvmHypervisor,
-        }
-    }
-}
-
-impl TryFrom<Uuid> for HypervisorBackend {
-    type Error = Error;
-
-    fn try_from(uuid: Uuid) -> Result<HypervisorBackend> {
-        match uuid {
-            GeniezoneHypervisor::UUID => Ok(HypervisorBackend::Geniezone),
-            GunyahHypervisor::UUID => Ok(HypervisorBackend::Gunyah),
-            RegularKvmHypervisor::UUID => {
-                // Protected KVM has the same UUID as "regular" KVM so issue an HVC that is assumed
-                // to only be supported by pKVM: if it returns SUCCESS, deduce that this is pKVM
-                // and if it returns NOT_SUPPORTED assume that it is "regular" KVM.
-                match ProtectedKvmHypervisor.as_mmio_guard().unwrap().granule() {
-                    Ok(_) => Ok(HypervisorBackend::ProtectedKvm),
-                    Err(Error::KvmError(KvmError::NotSupported, _)) => {
-                        Ok(HypervisorBackend::RegularKvm)
-                    }
-                    Err(e) => Err(e),
-                }
-            }
-            u => Err(Error::UnsupportedHypervisorUuid(u)),
-        }
-    }
-}
-
-const ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: u32 = 0x8600ff01;
-
-fn query_vendor_hyp_call_uid() -> Uuid {
-    let args = [0u64; 17];
-    let res = hvc64(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, args);
-
-    // KVM's UUID of "28b46fb6-2ec5-11e9-a9ca-4b564d003a74" is generated by
-    // Uuid::from_u128() from an input value of
-    // 0x28b46fb6_2ec511e9_a9ca4b56_4d003a74. ARM's SMC calling convention
-    // (Document number ARM DEN 0028E) describes the UUID register mapping such
-    // that W0 contains bytes 0..3 of UUID, with byte 0 in lower order bits. In
-    // the KVM example, byte 0 of KVM's UUID (0x28) will be returned in the low
-    // 8-bits of W0, while byte 15 (0x74) will be returned in bits 31-24 of W3.
-    //
-    // `uuid` value derived below thus need to be byte-reversed before
-    // being used in Uuid::from_u128(). Alternately use Uuid::from_u128_le()
-    // to achieve the same.
-
-    let uuid = ((res[3] as u32 as u128) << 96)
-        | ((res[2] as u32 as u128) << 64)
-        | ((res[1] as u32 as u128) << 32)
-        | (res[0] as u32 as u128);
-
-    Uuid::from_u128_le(uuid)
-}
-
-fn detect_hypervisor() -> HypervisorBackend {
-    query_vendor_hyp_call_uid().try_into().expect("Failed to detect hypervisor")
-}
-
-/// Gets the hypervisor singleton.
-fn get_hypervisor() -> &'static dyn Hypervisor {
-    static HYPERVISOR: OnceBox<HypervisorBackend> = OnceBox::new();
-
-    HYPERVISOR.get_or_init(|| Box::new(detect_hypervisor())).get_hypervisor()
-}
-
-/// Gets the MMIO_GUARD hypervisor singleton, if any.
-pub fn get_mmio_guard() -> Option<&'static dyn MmioGuardedHypervisor> {
-    get_hypervisor().as_mmio_guard()
-}
-
-/// Gets the dynamic memory sharing hypervisor singleton, if any.
-pub fn get_mem_sharer() -> Option<&'static dyn MemSharingHypervisor> {
-    get_hypervisor().as_mem_sharer()
-}
-
-/// Gets the device assigning hypervisor singleton, if any.
-pub fn get_device_assigner() -> Option<&'static dyn DeviceAssigningHypervisor> {
-    get_hypervisor().as_device_assigner()
-}
diff --git a/libs/libvmbase/src/hyp/hypervisor/common.rs b/libs/libvmbase/src/hyp/hypervisor/common.rs
deleted file mode 100644
index 8f0e4dc..0000000
--- a/libs/libvmbase/src/hyp/hypervisor/common.rs
+++ /dev/null
@@ -1,76 +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.
-
-//! This module regroups some common traits shared by all the hypervisors.
-
-use crate::hyp::Result;
-
-/// Trait for the hypervisor.
-pub trait Hypervisor {
-    /// Returns the hypervisor's MMIO_GUARD implementation, if any.
-    fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
-        None
-    }
-
-    /// Returns the hypervisor's dynamic memory sharing implementation, if any.
-    fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
-        None
-    }
-
-    /// Returns the hypervisor's device assigning implementation, if any.
-    fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
-        None
-    }
-}
-
-pub trait MmioGuardedHypervisor {
-    /// Enrolls with the MMIO guard so that all MMIO will be blocked unless allow-listed with
-    /// `MmioGuardedHypervisor::map`.
-    fn enroll(&self) -> Result<()>;
-
-    /// Maps a page containing the given memory address to the hypervisor MMIO guard.
-    /// The page size corresponds to the MMIO guard granule size.
-    fn map(&self, addr: usize) -> Result<()>;
-
-    /// Unmaps a page containing the given memory address from the hypervisor MMIO guard.
-    /// The page size corresponds to the MMIO guard granule size.
-    fn unmap(&self, addr: usize) -> Result<()>;
-
-    /// Returns the MMIO guard granule size in bytes.
-    fn granule(&self) -> Result<usize>;
-}
-
-pub trait MemSharingHypervisor {
-    /// Shares a region of memory with host, granting it read, write and execute permissions.
-    /// The size of the region is equal to the memory protection granule returned by
-    /// [`hyp_meminfo`].
-    fn share(&self, base_ipa: u64) -> Result<()>;
-
-    /// Revokes access permission from host to a memory region previously shared with
-    /// [`mem_share`]. The size of the region is equal to the memory protection granule returned by
-    /// [`hyp_meminfo`].
-    fn unshare(&self, base_ipa: u64) -> Result<()>;
-
-    /// Returns the memory protection granule size in bytes.
-    fn granule(&self) -> Result<usize>;
-}
-
-/// Device assigning hypervisor
-pub trait DeviceAssigningHypervisor {
-    /// Returns MMIO token.
-    fn get_phys_mmio_token(&self, base_ipa: u64) -> Result<u64>;
-
-    /// Returns DMA token as a tuple of (phys_iommu_id, phys_sid).
-    fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> Result<(u64, u64)>;
-}
diff --git a/libs/libvmbase/src/hyp/hypervisor/geniezone.rs b/libs/libvmbase/src/hyp/hypervisor/geniezone.rs
deleted file mode 100644
index fcb9b42..0000000
--- a/libs/libvmbase/src/hyp/hypervisor/geniezone.rs
+++ /dev/null
@@ -1,161 +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.
-
-//! Wrappers around calls to the GenieZone hypervisor.
-
-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,
-};
-use uuid::{uuid, Uuid};
-
-pub(super) struct GeniezoneHypervisor;
-
-const ARM_SMCCC_GZVM_FUNC_HYP_MEMINFO: u32 = 0xc6000002;
-const ARM_SMCCC_GZVM_FUNC_MEM_SHARE: u32 = 0xc6000003;
-const ARM_SMCCC_GZVM_FUNC_MEM_UNSHARE: u32 = 0xc6000004;
-
-const VENDOR_HYP_GZVM_MMIO_GUARD_INFO_FUNC_ID: u32 = 0xc6000005;
-const VENDOR_HYP_GZVM_MMIO_GUARD_ENROLL_FUNC_ID: u32 = 0xc6000006;
-const VENDOR_HYP_GZVM_MMIO_GUARD_MAP_FUNC_ID: u32 = 0xc6000007;
-const VENDOR_HYP_GZVM_MMIO_GUARD_UNMAP_FUNC_ID: u32 = 0xc6000008;
-
-impl GeniezoneHypervisor {
-    // We generate this uuid by ourselves to identify GenieZone hypervisor
-    // and share the same identification along with guest VMs.
-    // The previous uuid was removed due to duplication elsewhere.
-    pub const UUID: Uuid = uuid!("7e134ed0-3b82-488d-8cee-69c19211dbe7");
-}
-
-/// Error from a GenieZone HVC call.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum GeniezoneError {
-    /// The call is not supported by the implementation.
-    NotSupported,
-    /// The call is not required to implement.
-    NotRequired,
-    /// One of the call parameters has a invalid value.
-    InvalidParameter,
-    /// There was an unexpected return value.
-    Unknown(i64),
-}
-
-impl From<i64> for GeniezoneError {
-    fn from(value: i64) -> Self {
-        match value {
-            -1 => GeniezoneError::NotSupported,
-            -2 => GeniezoneError::NotRequired,
-            -3 => GeniezoneError::InvalidParameter,
-            _ => GeniezoneError::Unknown(value),
-        }
-    }
-}
-
-impl From<i32> for GeniezoneError {
-    fn from(value: i32) -> Self {
-        i64::from(value).into()
-    }
-}
-
-impl Display for GeniezoneError {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        match self {
-            Self::NotSupported => write!(f, "GenieZone call not supported"),
-            Self::NotRequired => write!(f, "GenieZone call not required"),
-            Self::InvalidParameter => write!(f, "GenieZone call received invalid value"),
-            Self::Unknown(e) => write!(f, "Unknown return value from GenieZone {} ({0:#x})", e),
-        }
-    }
-}
-
-impl Hypervisor for GeniezoneHypervisor {
-    fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
-        Some(self)
-    }
-
-    fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
-        Some(self)
-    }
-}
-
-impl MmioGuardedHypervisor for GeniezoneHypervisor {
-    fn enroll(&self) -> Result<()> {
-        let args = [0u64; 17];
-        match success_or_error_64(hvc64(VENDOR_HYP_GZVM_MMIO_GUARD_ENROLL_FUNC_ID, args)[0]) {
-            Ok(()) => Ok(()),
-            Err(GeniezoneError::NotSupported) | Err(GeniezoneError::NotRequired) => {
-                Err(Error::MmioGuardNotSupported)
-            }
-            Err(e) => Err(Error::GeniezoneError(e, VENDOR_HYP_GZVM_MMIO_GUARD_ENROLL_FUNC_ID)),
-        }
-    }
-
-    fn map(&self, addr: usize) -> Result<()> {
-        let mut args = [0u64; 17];
-        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_4kb_of(addr).try_into().unwrap();
-
-        checked_hvc64_expect_zero(VENDOR_HYP_GZVM_MMIO_GUARD_UNMAP_FUNC_ID, args)
-    }
-
-    fn granule(&self) -> Result<usize> {
-        let args = [0u64; 17];
-        let granule = checked_hvc64(VENDOR_HYP_GZVM_MMIO_GUARD_INFO_FUNC_ID, args)?;
-        Ok(granule.try_into().unwrap())
-    }
-}
-
-impl MemSharingHypervisor for GeniezoneHypervisor {
-    fn share(&self, base_ipa: u64) -> Result<()> {
-        let mut args = [0u64; 17];
-        args[0] = base_ipa;
-
-        checked_hvc64_expect_zero(ARM_SMCCC_GZVM_FUNC_MEM_SHARE, args)
-    }
-
-    fn unshare(&self, base_ipa: u64) -> Result<()> {
-        let mut args = [0u64; 17];
-        args[0] = base_ipa;
-
-        checked_hvc64_expect_zero(ARM_SMCCC_GZVM_FUNC_MEM_UNSHARE, args)
-    }
-
-    fn granule(&self) -> Result<usize> {
-        let args = [0u64; 17];
-        let granule = checked_hvc64(ARM_SMCCC_GZVM_FUNC_HYP_MEMINFO, args)?;
-        Ok(granule.try_into().unwrap())
-    }
-}
-
-fn checked_hvc64_expect_zero(function: u32, args: [u64; 17]) -> Result<()> {
-    success_or_error_64(hvc64(function, args)[0]).map_err(|e| Error::GeniezoneError(e, function))
-}
-
-fn checked_hvc64(function: u32, args: [u64; 17]) -> Result<u64> {
-    positive_or_error_64(hvc64(function, args)[0]).map_err(|e| Error::GeniezoneError(e, function))
-}
diff --git a/libs/libvmbase/src/hyp/hypervisor/gunyah.rs b/libs/libvmbase/src/hyp/hypervisor/gunyah.rs
deleted file mode 100644
index 45c01bf..0000000
--- a/libs/libvmbase/src/hyp/hypervisor/gunyah.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use super::common::Hypervisor;
-use uuid::{uuid, Uuid};
-
-pub(super) struct GunyahHypervisor;
-
-impl GunyahHypervisor {
-    pub const UUID: Uuid = uuid!("c1d58fcd-a453-5fdb-9265-ce36673d5f14");
-}
-
-impl Hypervisor for GunyahHypervisor {}
diff --git a/libs/libvmbase/src/hyp/hypervisor/kvm.rs b/libs/libvmbase/src/hyp/hypervisor/kvm.rs
deleted file mode 100644
index 7ed829e..0000000
--- a/libs/libvmbase/src/hyp/hypervisor/kvm.rs
+++ /dev/null
@@ -1,206 +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.
-
-//! Wrappers around calls to the KVM hypervisor.
-
-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,
-};
-use uuid::{uuid, Uuid};
-
-/// 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;
-const ARM_SMCCC_KVM_FUNC_MEM_UNSHARE: u32 = 0xc6000004;
-
-const VENDOR_HYP_KVM_MMIO_GUARD_INFO_FUNC_ID: u32 = 0xc6000005;
-const VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID: u32 = 0xc6000006;
-const VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID: u32 = 0xc6000007;
-const VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID: u32 = 0xc6000008;
-
-const VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID: u32 = 0xc6000012;
-const VENDOR_HYP_KVM_DEV_REQ_DMA_FUNC_ID: u32 = 0xc600001b;
-
-pub(super) struct RegularKvmHypervisor;
-
-impl RegularKvmHypervisor {
-    // Based on ARM_SMCCC_VENDOR_HYP_UID_KVM_REG values listed in Linux kernel source:
-    // https://github.com/torvalds/linux/blob/master/include/linux/arm-smccc.h
-    pub(super) const UUID: Uuid = uuid!("28b46fb6-2ec5-11e9-a9ca-4b564d003a74");
-}
-
-impl Hypervisor for RegularKvmHypervisor {}
-
-pub(super) struct ProtectedKvmHypervisor;
-
-impl Hypervisor for ProtectedKvmHypervisor {
-    fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
-        Some(self)
-    }
-
-    fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
-        Some(self)
-    }
-
-    fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
-        Some(self)
-    }
-}
-
-impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
-    fn enroll(&self) -> Result<()> {
-        let args = [0u64; 17];
-        match success_or_error_64(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID, args)[0]) {
-            Ok(()) => Ok(()),
-            Err(KvmError::NotSupported) => Err(Error::MmioGuardNotSupported),
-            Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID)),
-        }
-    }
-
-    fn map(&self, addr: usize) -> Result<()> {
-        let mut args = [0u64; 17];
-        args[0] = page_4kb_of(addr).try_into().unwrap();
-
-        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_4kb_of(addr).try_into().unwrap();
-
-        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> {
-        let args = [0u64; 17];
-        let granule = checked_hvc64(VENDOR_HYP_KVM_MMIO_GUARD_INFO_FUNC_ID, args)?;
-        Ok(granule.try_into().unwrap())
-    }
-}
-
-impl MemSharingHypervisor for ProtectedKvmHypervisor {
-    fn share(&self, base_ipa: u64) -> Result<()> {
-        let mut args = [0u64; 17];
-        args[0] = base_ipa;
-
-        checked_hvc64_expect_zero(ARM_SMCCC_KVM_FUNC_MEM_SHARE, args)
-    }
-
-    fn unshare(&self, base_ipa: u64) -> Result<()> {
-        let mut args = [0u64; 17];
-        args[0] = base_ipa;
-
-        checked_hvc64_expect_zero(ARM_SMCCC_KVM_FUNC_MEM_UNSHARE, args)
-    }
-
-    fn granule(&self) -> Result<usize> {
-        let args = [0u64; 17];
-        let granule = checked_hvc64(ARM_SMCCC_KVM_FUNC_HYP_MEMINFO, args)?;
-        Ok(granule.try_into().unwrap())
-    }
-}
-
-impl DeviceAssigningHypervisor for ProtectedKvmHypervisor {
-    fn get_phys_mmio_token(&self, base_ipa: u64) -> Result<u64> {
-        let mut args = [0u64; 17];
-        args[0] = base_ipa;
-
-        let ret = checked_hvc64_expect_results(VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID, args)?;
-        Ok(ret[0])
-    }
-
-    fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> Result<(u64, u64)> {
-        let mut args = [0u64; 17];
-        args[0] = pviommu_id;
-        args[1] = vsid;
-
-        let ret = checked_hvc64_expect_results(VENDOR_HYP_KVM_DEV_REQ_DMA_FUNC_ID, args)?;
-        Ok((ret[0], ret[1]))
-    }
-}
-
-fn checked_hvc64_expect_zero(function: u32, args: [u64; 17]) -> Result<()> {
-    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> {
-    positive_or_error_64(hvc64(function, args)[0]).map_err(|e| Error::KvmError(e, function))
-}
-
-fn checked_hvc64_expect_results(function: u32, args: [u64; 17]) -> Result<[u64; 17]> {
-    let [ret, results @ ..] = hvc64(function, args);
-    success_or_error_64(ret).map_err(|e| Error::KvmError(e, function))?;
-    Ok(results)
-}
diff --git a/libs/libvmbase/src/lib.rs b/libs/libvmbase/src/lib.rs
index 630834b..431e899 100644
--- a/libs/libvmbase/src/lib.rs
+++ b/libs/libvmbase/src/lib.rs
@@ -26,7 +26,6 @@
 pub mod fdt;
 pub mod heap;
 mod hvc;
-pub mod hyp;
 pub mod layout;
 pub mod linker;
 pub mod logger;
diff --git a/libs/libvmbase/src/memory/error.rs b/libs/libvmbase/src/memory/error.rs
index 4d08f1e..870e4c9 100644
--- a/libs/libvmbase/src/memory/error.rs
+++ b/libs/libvmbase/src/memory/error.rs
@@ -16,7 +16,7 @@
 
 use core::fmt;
 
-use crate::hyp;
+use hypervisor_backends::Error as HypervisorError;
 
 /// Errors for MemoryTracker operations.
 #[derive(Debug, Clone)]
@@ -38,7 +38,7 @@
     /// Region couldn't be unmapped.
     FailedToUnmap,
     /// Error from the interaction with the hypervisor.
-    Hypervisor(hyp::Error),
+    Hypervisor(HypervisorError),
     /// Failure to set `SHARED_MEMORY`.
     SharedMemorySetFailure,
     /// Failure to set `SHARED_POOL`.
@@ -82,8 +82,8 @@
     }
 }
 
-impl From<hyp::Error> for MemoryTrackerError {
-    fn from(e: hyp::Error) -> Self {
+impl From<HypervisorError> for MemoryTrackerError {
+    fn from(e: HypervisorError) -> Self {
         Self::Hypervisor(e)
     }
 }
diff --git a/libs/libvmbase/src/memory/shared.rs b/libs/libvmbase/src/memory/shared.rs
index 92dd09e..7e5e7e9 100644
--- a/libs/libvmbase/src/memory/shared.rs
+++ b/libs/libvmbase/src/memory/shared.rs
@@ -16,7 +16,6 @@
 
 use super::error::MemoryTrackerError;
 use super::util::virt_to_phys;
-use crate::hyp::{self, get_mem_sharer, get_mmio_guard};
 use crate::layout;
 use crate::util::unchecked_align_down;
 use aarch64_paging::paging::{MemoryRegion as VaRange, VirtualAddress, PAGE_SIZE};
@@ -29,6 +28,7 @@
 use core::ops::Range;
 use core::ptr::NonNull;
 use core::result;
+use hypervisor_backends::{self, get_mem_sharer, get_mmio_guard};
 use log::trace;
 use once_cell::race::OnceBox;
 use spin::mutex::SpinMutex;
@@ -108,7 +108,7 @@
 
 /// 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>> {
+pub(crate) fn alloc_shared(layout: Layout) -> hypervisor_backends::Result<NonNull<u8>> {
     assert_ne!(layout.size(), 0);
     let Some(buffer) = try_shared_alloc(layout) else {
         handle_alloc_error(layout);
@@ -143,7 +143,10 @@
 ///
 /// The memory must have been allocated by `alloc_shared` with the same layout, and not yet
 /// deallocated.
-pub(crate) unsafe fn dealloc_shared(vaddr: NonNull<u8>, layout: Layout) -> hyp::Result<()> {
+pub(crate) unsafe fn dealloc_shared(
+    vaddr: NonNull<u8>,
+    layout: Layout,
+) -> hypervisor_backends::Result<()> {
     SHARED_POOL.get().unwrap().lock().dealloc_aligned(vaddr.as_ptr() as usize, layout);
 
     trace!("Deallocated shared buffer at {vaddr:?} with {layout:?}");
diff --git a/libs/libvmbase/src/memory/tracker.rs b/libs/libvmbase/src/memory/tracker.rs
index acf182f..c1f5d54 100644
--- a/libs/libvmbase/src/memory/tracker.rs
+++ b/libs/libvmbase/src/memory/tracker.rs
@@ -19,7 +19,6 @@
 use super::page_table::{PageTable, MMIO_LAZY_MAP_FLAG};
 use super::shared::{SHARED_MEMORY, SHARED_POOL};
 use crate::dsb;
-use crate::hyp::get_mmio_guard;
 use crate::memory::shared::{MemoryRange, MemorySharer, MmioSharer};
 use crate::util::RangeExt as _;
 use aarch64_paging::paging::{Attributes, Descriptor, MemoryRegion as VaRange, VirtualAddress};
@@ -29,6 +28,7 @@
 use core::num::NonZeroUsize;
 use core::ops::Range;
 use core::result;
+use hypervisor_backends::get_mmio_guard;
 use log::{debug, error};
 use spin::mutex::SpinMutex;
 use tinyvec::ArrayVec;