[hypervisor] Add capabilities

Allow hypervisor backends to advertize their capabilities such as
dynamic memory sharing with host OS.

Test: m pvmfw_img
Bug: 271493784
Change-Id: Id2d755d790254814538ae6e12efb654bb091975c
diff --git a/libs/hyp/Android.bp b/libs/hyp/Android.bp
index 0f125fc..1d572e5 100644
--- a/libs/hyp/Android.bp
+++ b/libs/hyp/Android.bp
@@ -8,6 +8,7 @@
     srcs: ["src/lib.rs"],
     prefer_rlib: true,
     rustlibs: [
+        "libbitflags",
         "libonce_cell_nostd",
         "libpsci",
         "libuuid_nostd",
diff --git a/libs/hyp/src/hypervisor/common.rs b/libs/hyp/src/hypervisor/common.rs
index 87d35b2..accef72 100644
--- a/libs/hyp/src/hypervisor/common.rs
+++ b/libs/hyp/src/hypervisor/common.rs
@@ -15,6 +15,15 @@
 //! This module regroups some common traits shared by all the hypervisors.
 
 use crate::error::Result;
+use bitflags::bitflags;
+
+bitflags! {
+    /// Capabilities that Hypervisor backends can declare support for.
+    pub struct HypervisorCap: u32 {
+        /// Capability for guest to share its memory with host at runtime.
+        const DYNAMIC_MEM_SHARE = 0b1;
+    }
+}
 
 /// Trait for the hypervisor.
 pub trait Hypervisor {
@@ -43,4 +52,7 @@
 
     /// Returns the memory protection granule size in bytes.
     fn memory_protection_granule(&self) -> Result<usize>;
+
+    /// Check if required capabilities are supported.
+    fn has_cap(&self, cap: HypervisorCap) -> bool;
 }
diff --git a/libs/hyp/src/hypervisor/kvm.rs b/libs/hyp/src/hypervisor/kvm.rs
index 00efde4..772160e 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/libs/hyp/src/hypervisor/kvm.rs
@@ -14,7 +14,7 @@
 
 //! Wrappers around calls to the KVM hypervisor.
 
-use super::common::Hypervisor;
+use super::common::{Hypervisor, HypervisorCap};
 use crate::error::{Error, Result};
 use crate::util::{page_address, SIZE_4KB};
 use core::fmt::{self, Display, Formatter};
@@ -76,6 +76,7 @@
     // 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");
+    const CAPABILITIES: HypervisorCap = HypervisorCap::DYNAMIC_MEM_SHARE;
 }
 
 impl Hypervisor for KvmHypervisor {
@@ -129,6 +130,10 @@
         let granule = checked_hvc64(ARM_SMCCC_KVM_FUNC_HYP_MEMINFO, args)?;
         Ok(granule.try_into().unwrap())
     }
+
+    fn has_cap(&self, cap: HypervisorCap) -> bool {
+        Self::CAPABILITIES.contains(cap)
+    }
 }
 
 fn mmio_guard_granule() -> Result<usize> {
diff --git a/libs/hyp/src/hypervisor/mod.rs b/libs/hyp/src/hypervisor/mod.rs
index dc9e7c3..a419726 100644
--- a/libs/hyp/src/hypervisor/mod.rs
+++ b/libs/hyp/src/hypervisor/mod.rs
@@ -22,6 +22,7 @@
 use crate::error::{Error, Result};
 use alloc::boxed::Box;
 pub use common::Hypervisor;
+pub use common::HypervisorCap;
 pub use kvm::KvmError;
 use kvm::KvmHypervisor;
 use once_cell::race::OnceBox;
diff --git a/libs/hyp/src/lib.rs b/libs/hyp/src/lib.rs
index 6db6ba8..694f957 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, KvmError};
+pub use hypervisor::{get_hypervisor, Hypervisor, HypervisorCap, KvmError};