libhyp: Expose MmioGuardedHypervisor::granule()

Split MmioGuardedHypervisor::init() into the calls it wraps to allow
client code to get the MMIO_GUARD granule from the API.

No functional change intended.

Test: m pvmfw_bin rialto_bin vmbase_example_bin
Change-Id: I8ec81d0bbe372dd06e8ea246954a54cbe2e1af44
diff --git a/libs/hyp/src/hypervisor/common.rs b/libs/hyp/src/hypervisor/common.rs
index 7c030a1..70fdd0a 100644
--- a/libs/hyp/src/hypervisor/common.rs
+++ b/libs/hyp/src/hypervisor/common.rs
@@ -14,7 +14,7 @@
 
 //! This module regroups some common traits shared by all the hypervisors.
 
-use crate::error::Result;
+use crate::error::{Error, Result};
 use crate::util::SIZE_4KB;
 
 /// Expected MMIO guard granule size, validated during MMIO guard initialization.
@@ -34,10 +34,9 @@
 }
 
 pub trait MmioGuardedHypervisor {
-    /// Initializes the hypervisor by enrolling a MMIO guard and checking the memory granule size.
-    /// By enrolling, all MMIO will be blocked unless allow-listed with `mmio_guard_map`.
-    /// Protected VMs are auto-enrolled.
-    fn init(&self) -> Result<()>;
+    /// 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.
@@ -46,6 +45,18 @@
     /// 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>;
+
+    // TODO(ptosi): Fully move granule validation to client code.
+    /// Validates the MMIO guard granule size.
+    fn validate_granule(&self) -> Result<()> {
+        match self.granule()? {
+            MMIO_GUARD_GRANULE_SIZE => Ok(()),
+            granule => Err(Error::UnsupportedMmioGuardGranule(granule)),
+        }
+    }
 }
 
 pub trait MemSharingHypervisor {
diff --git a/libs/hyp/src/hypervisor/geniezone.rs b/libs/hyp/src/hypervisor/geniezone.rs
index 513e144..ad18e17 100644
--- a/libs/hyp/src/hypervisor/geniezone.rs
+++ b/libs/hyp/src/hypervisor/geniezone.rs
@@ -14,9 +14,7 @@
 
 //! Wrappers around calls to the GenieZone hypervisor.
 
-use super::common::{
-    Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor, MMIO_GUARD_GRANULE_SIZE,
-};
+use super::common::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
 use crate::error::{Error, Result};
 use crate::util::page_address;
 use core::fmt::{self, Display, Formatter};
@@ -96,13 +94,15 @@
 }
 
 impl MmioGuardedHypervisor for GeniezoneHypervisor {
-    fn init(&self) -> Result<()> {
-        mmio_guard_enroll()?;
-        let mmio_granule = mmio_guard_granule()?;
-        if mmio_granule != MMIO_GUARD_GRANULE_SIZE {
-            return Err(Error::UnsupportedMmioGuardGranule(mmio_granule));
+    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)),
         }
-        Ok(())
     }
 
     fn map(&self, addr: usize) -> Result<()> {
@@ -118,6 +118,12 @@
 
         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 {
@@ -142,24 +148,6 @@
     }
 }
 
-fn mmio_guard_granule() -> Result<usize> {
-    let args = [0u64; 17];
-
-    let granule = checked_hvc64(VENDOR_HYP_GZVM_MMIO_GUARD_INFO_FUNC_ID, args)?;
-    Ok(granule.try_into().unwrap())
-}
-
-fn mmio_guard_enroll() -> 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 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))
 }
diff --git a/libs/hyp/src/hypervisor/kvm.rs b/libs/hyp/src/hypervisor/kvm.rs
index 36c53eb..5835346 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/libs/hyp/src/hypervisor/kvm.rs
@@ -14,9 +14,7 @@
 
 //! Wrappers around calls to the KVM hypervisor.
 
-use super::common::{
-    Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor, MMIO_GUARD_GRANULE_SIZE,
-};
+use super::common::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
 use crate::error::{Error, Result};
 use crate::util::page_address;
 use core::fmt::{self, Display, Formatter};
@@ -95,13 +93,13 @@
 }
 
 impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
-    fn init(&self) -> Result<()> {
-        mmio_guard_enroll()?;
-        let mmio_granule = mmio_guard_granule()?;
-        if mmio_granule != MMIO_GUARD_GRANULE_SIZE {
-            return Err(Error::UnsupportedMmioGuardGranule(mmio_granule));
+    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)),
         }
-        Ok(())
     }
 
     fn map(&self, addr: usize) -> Result<()> {
@@ -125,6 +123,12 @@
             Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
         }
     }
+
+    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 {
@@ -149,22 +153,6 @@
     }
 }
 
-fn mmio_guard_granule() -> Result<usize> {
-    let args = [0u64; 17];
-
-    let granule = checked_hvc64(VENDOR_HYP_KVM_MMIO_GUARD_INFO_FUNC_ID, args)?;
-    Ok(granule.try_into().unwrap())
-}
-
-fn mmio_guard_enroll() -> 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 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))
 }
diff --git a/vmbase/src/entry.rs b/vmbase/src/entry.rs
index 24b5035..2ff66cc 100644
--- a/vmbase/src/entry.rs
+++ b/vmbase/src/entry.rs
@@ -26,7 +26,8 @@
     console::init();
 
     if let Some(mmio_guard) = get_mmio_guard() {
-        mmio_guard.init()?;
+        mmio_guard.enroll()?;
+        mmio_guard.validate_granule()?;
         mmio_guard.map(console::BASE_ADDRESS)?;
     }