libhyp: Add DeviceAssigningHypervisor
Bug: 277993056
Test: TH
Change-Id: Ie14389a2895e05c16ee3f18951e3125da21b415a
diff --git a/libs/hyp/src/hypervisor.rs b/libs/hyp/src/hypervisor.rs
index 309f967..3d42ccb 100644
--- a/libs/hyp/src/hypervisor.rs
+++ b/libs/hyp/src/hypervisor.rs
@@ -34,6 +34,8 @@
use smccc::hvc64;
use uuid::Uuid;
+use self::common::DeviceAssigningHypervisor;
+
enum HypervisorBackend {
RegularKvm,
Gunyah,
@@ -122,3 +124,8 @@
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/hyp/src/hypervisor/common.rs b/libs/hyp/src/hypervisor/common.rs
index 70fdd0a..2ea18f3 100644
--- a/libs/hyp/src/hypervisor/common.rs
+++ b/libs/hyp/src/hypervisor/common.rs
@@ -31,6 +31,11 @@
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 {
@@ -73,3 +78,11 @@
/// Returns the memory protection granule size in bytes.
fn granule(&self) -> Result<usize>;
}
+
+pub trait DeviceAssigningHypervisor {
+ /// Returns MMIO token.
+ fn get_phys_mmio_token(&self, base_ipa: u64, size: 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/hyp/src/hypervisor/kvm.rs b/libs/hyp/src/hypervisor/kvm.rs
index 5835346..720318e 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/libs/hyp/src/hypervisor/kvm.rs
@@ -14,7 +14,9 @@
//! Wrappers around calls to the KVM hypervisor.
-use super::common::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
+use super::common::{
+ DeviceAssigningHypervisor, Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor,
+};
use crate::error::{Error, Result};
use crate::util::page_address;
use core::fmt::{self, Display, Formatter};
@@ -70,6 +72,9 @@
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 = 0xc6000013;
+
pub(super) struct RegularKvmHypervisor;
impl RegularKvmHypervisor {
@@ -90,6 +95,10 @@
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
Some(self)
}
+
+ fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
+ Some(self)
+ }
}
impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
@@ -153,6 +162,26 @@
}
}
+impl DeviceAssigningHypervisor for ProtectedKvmHypervisor {
+ fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> Result<u64> {
+ let mut args = [0u64; 17];
+ args[0] = base_ipa;
+ args[1] = size;
+
+ 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))
}
@@ -160,3 +189,9 @@
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/hyp/src/lib.rs b/libs/hyp/src/lib.rs
index 486a181..505aade 100644
--- a/libs/hyp/src/lib.rs
+++ b/libs/hyp/src/lib.rs
@@ -21,6 +21,8 @@
mod util;
pub use error::{Error, Result};
-pub use hypervisor::{get_mem_sharer, get_mmio_guard, KvmError, MMIO_GUARD_GRANULE_SIZE};
+pub use hypervisor::{
+ get_device_assigner, get_mem_sharer, get_mmio_guard, KvmError, MMIO_GUARD_GRANULE_SIZE,
+};
use hypervisor::GeniezoneError;