vmbase: Introduce compat_android_13 feature

Put the workarounds for Android 13 recently added to vmbase (previously
in libhyp) behind a Rust crate feature to ensure that the "proper"
implementation gets compiled (then optimized out), more clearly document
that particular code, and provide a single point for "flipping the
switch" when the support gets removed (possibly progressively, by using
Android Trunk Stable flags).

Test: m libvmbase # with the feature set and unset in Android.bp
Change-Id: Ib012ce2e5aff1a8c8b9cf49f270aee89e695650e
diff --git a/vmbase/Android.bp b/vmbase/Android.bp
index 236a895..17f4bda 100644
--- a/vmbase/Android.bp
+++ b/vmbase/Android.bp
@@ -93,7 +93,9 @@
     whole_static_libs: [
         "librust_baremetal",
     ],
+    // TODO(b/277859415, b/277860860): Drop "compat_android_13".
     features: [
+        "compat_android_13",
         "cpu_feat_hafdbs",
     ],
 }
diff --git a/vmbase/src/hyp/hypervisor/kvm.rs b/vmbase/src/hyp/hypervisor/kvm.rs
index 09fe0ec..8450bed 100644
--- a/vmbase/src/hyp/hypervisor/kvm.rs
+++ b/vmbase/src/hyp/hypervisor/kvm.rs
@@ -117,22 +117,30 @@
         let mut args = [0u64; 17];
         args[0] = page_4kb_of(addr).try_into().unwrap();
 
-        // TODO(b/277859415): pKVM returns a i32 instead of a i64 in T.
-        // Drop this hack once T reaches EoL.
-        success_or_error_32(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)[0] as u32)
-            .map_err(|e| Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID))
+        if cfg!(feature = "compat_android_13") {
+            let res = hvc64(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)[0];
+            // pKVM returns i32 instead of the intended i64 in Android 13.
+            return success_or_error_32(res as u32)
+                .map_err(|e| Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID));
+        }
+
+        checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID, args)
     }
 
     fn unmap(&self, addr: usize) -> Result<()> {
         let mut args = [0u64; 17];
         args[0] = page_4kb_of(addr).try_into().unwrap();
 
-        // TODO(b/277860860): pKVM returns NOT_SUPPORTED for SUCCESS in T.
-        // Drop this hack once T reaches EoL.
-        match success_or_error_64(hvc64(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)[0]) {
-            Err(KvmError::NotSupported) | Ok(_) => Ok(()),
-            Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
+        if cfg!(feature = "compat_android_13") {
+            let res = hvc64(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)[0];
+            // pKVM returns NOT_SUPPORTED for SUCCESS in Android 13.
+            return match success_or_error_64(res) {
+                Err(KvmError::NotSupported) | Ok(_) => Ok(()),
+                Err(e) => Err(Error::KvmError(e, VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID)),
+            };
         }
+
+        checked_hvc64_expect_zero(VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID, args)
     }
 
     fn granule(&self) -> Result<usize> {