hyp: Add support for non-protected KvmHypervisor
Use the hypervisor abstraction to properly support non-protected KVM as
a distinct case of pKVM. To clarify the distinction, rename the backend
"ProtectedKvmHypervisor" from its previous name "KvmHypervisor" now used
by (regular) non-protected KVM.
Test: atest DebugPolicyHostTests#testNoAdbInDebugPolicy_withDebugLevelNone_boots
Test: atest rialto_test vmbase_example.integration_test
Change-Id: Idb16920750263f4712884064d4f85525bff164e4
diff --git a/libs/hyp/src/hypervisor/kvm.rs b/libs/hyp/src/hypervisor/kvm.rs
index ab0aa6c..a95b8de 100644
--- a/libs/hyp/src/hypervisor/kvm.rs
+++ b/libs/hyp/src/hypervisor/kvm.rs
@@ -72,15 +72,19 @@
const VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID: u32 = 0xc6000007;
const VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID: u32 = 0xc6000008;
-pub(super) struct KvmHypervisor;
+pub(super) struct RegularKvmHypervisor;
-impl KvmHypervisor {
+impl RegularKvmHypervisor {
// 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");
}
-impl Hypervisor for KvmHypervisor {
+impl Hypervisor for RegularKvmHypervisor {}
+
+pub(super) struct ProtectedKvmHypervisor;
+
+impl Hypervisor for ProtectedKvmHypervisor {
fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
Some(self)
}
@@ -90,7 +94,7 @@
}
}
-impl MmioGuardedHypervisor for KvmHypervisor {
+impl MmioGuardedHypervisor for ProtectedKvmHypervisor {
fn init(&self) -> Result<()> {
mmio_guard_enroll()?;
let mmio_granule = mmio_guard_granule()?;
@@ -123,7 +127,7 @@
}
}
-impl MemSharingHypervisor for KvmHypervisor {
+impl MemSharingHypervisor for ProtectedKvmHypervisor {
fn share(&self, base_ipa: u64) -> Result<()> {
let mut args = [0u64; 17];
args[0] = base_ipa;
diff --git a/libs/hyp/src/hypervisor/mod.rs b/libs/hyp/src/hypervisor/mod.rs
index 2c82fc1..bc9e406 100644
--- a/libs/hyp/src/hypervisor/mod.rs
+++ b/libs/hyp/src/hypervisor/mod.rs
@@ -29,23 +29,25 @@
use geniezone::GeniezoneHypervisor;
use gunyah::GunyahHypervisor;
pub use kvm::KvmError;
-use kvm::KvmHypervisor;
+use kvm::{ProtectedKvmHypervisor, RegularKvmHypervisor};
use once_cell::race::OnceBox;
use smccc::hvc64;
use uuid::Uuid;
enum HypervisorBackend {
- Kvm,
+ RegularKvm,
Gunyah,
Geniezone,
+ ProtectedKvm,
}
impl HypervisorBackend {
fn get_hypervisor(&self) -> &'static dyn Hypervisor {
match self {
- Self::Kvm => &KvmHypervisor,
+ Self::RegularKvm => &RegularKvmHypervisor,
Self::Gunyah => &GunyahHypervisor,
Self::Geniezone => &GeniezoneHypervisor,
+ Self::ProtectedKvm => &ProtectedKvmHypervisor,
}
}
}
@@ -57,7 +59,16 @@
match uuid {
GeniezoneHypervisor::UUID => Ok(HypervisorBackend::Geniezone),
GunyahHypervisor::UUID => Ok(HypervisorBackend::Gunyah),
- KvmHypervisor::UUID => Ok(HypervisorBackend::Kvm),
+ RegularKvmHypervisor::UUID => {
+ // Protected KVM has the same UUID so differentiate based on MEM_SHARE.
+ match ProtectedKvmHypervisor.as_mem_sharer().unwrap().granule() {
+ Ok(_) => Ok(HypervisorBackend::ProtectedKvm),
+ Err(Error::KvmError(KvmError::NotSupported, _)) => {
+ Ok(HypervisorBackend::RegularKvm)
+ }
+ Err(e) => Err(e),
+ }
+ }
u => Err(Error::UnsupportedHypervisorUuid(u)),
}
}