Merge changes Ia4dc9e72,I8ec81d0b,I26b06db0 into main

* changes:
  libhyp: Detect non-protected through MMIO_GUARD
  libhyp: Expose MmioGuardedHypervisor::granule()
  libhyp: Make MmioGuardNotsupported UpperCamelCase
diff --git a/libs/hyp/src/error.rs b/libs/hyp/src/error.rs
index b8498ca..3fdad70 100644
--- a/libs/hyp/src/error.rs
+++ b/libs/hyp/src/error.rs
@@ -26,7 +26,7 @@
 #[derive(Debug, Clone)]
 pub enum Error {
     /// MMIO guard is not supported.
-    MmioGuardNotsupported,
+    MmioGuardNotSupported,
     /// Failed to invoke a certain KVM HVC function.
     KvmError(KvmError, u32),
     /// Failed to invoke GenieZone HVC function.
@@ -40,7 +40,7 @@
 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::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}")
             }
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 24eb89e..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,23 +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(Error::MmioGuardNotsupported),
-        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 a95b8de..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/libs/hyp/src/hypervisor/mod.rs b/libs/hyp/src/hypervisor/mod.rs
index bc9e406..309f967 100644
--- a/libs/hyp/src/hypervisor/mod.rs
+++ b/libs/hyp/src/hypervisor/mod.rs
@@ -60,8 +60,10 @@
             GeniezoneHypervisor::UUID => Ok(HypervisorBackend::Geniezone),
             GunyahHypervisor::UUID => Ok(HypervisorBackend::Gunyah),
             RegularKvmHypervisor::UUID => {
-                // Protected KVM has the same UUID so differentiate based on MEM_SHARE.
-                match ProtectedKvmHypervisor.as_mem_sharer().unwrap().granule() {
+                // 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)
@@ -101,7 +103,7 @@
 }
 
 fn detect_hypervisor() -> HypervisorBackend {
-    query_vendor_hyp_call_uid().try_into().expect("Unknown hypervisor")
+    query_vendor_hyp_call_uid().try_into().expect("Failed to detect hypervisor")
 }
 
 /// Gets the hypervisor singleton.
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)?;
     }