hypervisor_backends: Add get_granule_size()
Add a helper to get the unique stage-2 page size without requiring an
actual implementation of MemSharingHypervisor or any other trait.
Implement it for pKVM and GZ using the previous approach, relying on
discovering the MEM_SHARE granule.
Note: No functional change intended.
Test: m pvmfw
Bug: 385802423
Change-Id: I04cf5e69cf871d038437e2fc5b94abd63b3dff1e
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index 9afbcc3..30624cd 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -41,7 +41,6 @@
use alloc::boxed::Box;
use bssl_avf::Digester;
use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
-use hypervisor_backends::get_mem_sharer;
use libfdt::Fdt;
use log::{debug, error, info, trace, warn};
use pvmfw_avb::verify_payload;
@@ -99,15 +98,7 @@
}
let guest_page_size = verified_boot_data.page_size.unwrap_or(SIZE_4KB);
- // TODO(ptosi): Cache the (single?) granule once, in vmbase.
- let hyp_page_size = if let Some(mem_sharer) = get_mem_sharer() {
- Some(mem_sharer.granule().map_err(|e| {
- error!("Failed to get granule size: {e}");
- RebootReason::InternalError
- })?)
- } else {
- None
- };
+ let hyp_page_size = hypervisor_backends::get_granule_size();
let _ =
sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt, guest_page_size, hyp_page_size)?;
let fdt = untrusted_fdt; // DT has now been sanitized.
diff --git a/libs/libhypervisor_backends/src/hypervisor.rs b/libs/libhypervisor_backends/src/hypervisor.rs
index aa65133..7c274f5 100644
--- a/libs/libhypervisor_backends/src/hypervisor.rs
+++ b/libs/libhypervisor_backends/src/hypervisor.rs
@@ -152,3 +152,8 @@
pub fn get_device_assigner() -> Option<&'static dyn DeviceAssigningHypervisor> {
get_hypervisor().as_device_assigner()
}
+
+/// Gets the unique hypervisor granule size, if any.
+pub fn get_granule_size() -> Option<usize> {
+ get_hypervisor().get_granule_size()
+}
diff --git a/libs/libhypervisor_backends/src/hypervisor/common.rs b/libs/libhypervisor_backends/src/hypervisor/common.rs
index bfe638f..f229e14 100644
--- a/libs/libhypervisor_backends/src/hypervisor/common.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/common.rs
@@ -32,6 +32,13 @@
fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
None
}
+
+ /// Returns the granule used by all APIs (MEM_SHARE, MMIO_GUARD, device assignment, ...).
+ ///
+ /// If no such API is supported or if they support different granule sizes, returns None.
+ fn get_granule_size(&self) -> Option<usize> {
+ None
+ }
}
pub trait MmioGuardedHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
index 76e010b..0913ff3 100644
--- a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
@@ -84,6 +84,10 @@
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
impl MmioGuardedHypervisor for GeniezoneHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
index 233097b..f183107 100644
--- a/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
@@ -90,6 +90,10 @@
fn as_device_assigner(&self) -> Option<&dyn DeviceAssigningHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
index 7f9ea4d..d72f788 100644
--- a/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
@@ -84,6 +84,10 @@
fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
Some(self)
}
+
+ fn get_granule_size(&self) -> Option<usize> {
+ <Self as MemSharingHypervisor>::granule(self).ok()
+ }
}
macro_rules! vmcall {
diff --git a/libs/libhypervisor_backends/src/lib.rs b/libs/libhypervisor_backends/src/lib.rs
index 33dc5ad..3c81ac8 100644
--- a/libs/libhypervisor_backends/src/lib.rs
+++ b/libs/libhypervisor_backends/src/lib.rs
@@ -24,5 +24,6 @@
pub use error::{Error, Result};
pub use hypervisor::{
- get_device_assigner, get_mem_sharer, get_mmio_guard, DeviceAssigningHypervisor, KvmError,
+ get_device_assigner, get_granule_size, get_mem_sharer, get_mmio_guard,
+ DeviceAssigningHypervisor, KvmError,
};