[pkvm][API] Add API to connect payload and VM service
Bug: 243512047
Test: MicrodroidTests
Change-Id: Id017a2a4236026a2687fe734f2a2c3dd480474bd
diff --git a/microdroid/vm_payload/Android.bp b/microdroid/vm_payload/Android.bp
new file mode 100644
index 0000000..0424fc1
--- /dev/null
+++ b/microdroid/vm_payload/Android.bp
@@ -0,0 +1,19 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_ffi_static {
+ name: "libvm_payload",
+ crate_name: "vm_payload",
+ srcs: ["src/*.rs"],
+ include_dirs: ["include"],
+ prefer_rlib: true,
+ rustlibs: [
+ "android.system.virtualmachineservice-rust",
+ "libandroid_logger",
+ "libanyhow",
+ "libbinder_rs",
+ "liblog_rust",
+ "librpcbinder_rs",
+ ],
+}
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
new file mode 100644
index 0000000..36480da
--- /dev/null
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Notifies the host that the payload is ready.
+/// Returns true if the notification succeeds else false.
+bool notify_payload_ready();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/microdroid/vm_payload/src/lib.rs b/microdroid/vm_payload/src/lib.rs
new file mode 100644
index 0000000..394578a
--- /dev/null
+++ b/microdroid/vm_payload/src/lib.rs
@@ -0,0 +1,19 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Library for payload to communicate with the VM service.
+
+mod vm_service;
+
+pub use vm_service::notify_payload_ready;
diff --git a/microdroid/vm_payload/src/vm_service.rs b/microdroid/vm_payload/src/vm_service.rs
new file mode 100644
index 0000000..e5a6b9a
--- /dev/null
+++ b/microdroid/vm_payload/src/vm_service.rs
@@ -0,0 +1,52 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! This module handles the interaction with virtual machine service.
+
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::{
+ VM_BINDER_SERVICE_PORT, IVirtualMachineService};
+use anyhow::{Context, Result};
+use binder::Strong;
+use log::{error, info, Level};
+use rpcbinder::get_vsock_rpc_interface;
+
+/// The CID representing the host VM
+const VMADDR_CID_HOST: u32 = 2;
+
+/// Notifies the host that the payload is ready.
+/// Returns true if the notification succeeds else false.
+#[no_mangle]
+pub extern "C" fn notify_payload_ready() -> bool {
+ android_logger::init_once(
+ android_logger::Config::default().with_tag("vm_payload").with_min_level(Level::Debug),
+ );
+ if let Err(e) = try_notify_payload_ready() {
+ error!("Failed to notify ready: {}", e);
+ false
+ } else {
+ info!("Notified host payload ready successfully");
+ true
+ }
+}
+
+/// Notifies the host that the payload is ready.
+/// Returns a `Result` containing error information if failed.
+fn try_notify_payload_ready() -> Result<()> {
+ get_vm_service()?.notifyPayloadReady().context("Cannot notify payload ready")
+}
+
+fn get_vm_service() -> Result<Strong<dyn IVirtualMachineService>> {
+ get_vsock_rpc_interface(VMADDR_CID_HOST, VM_BINDER_SERVICE_PORT as u32)
+ .context("Connecting to IVirtualMachineService")
+}
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index 47116eb..9e6958c 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -33,7 +33,6 @@
srcs: ["src/native/testbinary.cpp"],
shared_libs: [
"android.security.dice-ndk",
- "android.system.virtualmachineservice-ndk",
"com.android.microdroid.testservice-ndk",
"libbase",
"libbinder_ndk",
@@ -44,6 +43,7 @@
"libfsverity_digests_proto_cc",
"liblog",
"libprotobuf-cpp-lite-ndk",
+ "libvm_payload",
],
}
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index b4fee86..fd8e776 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
#include <aidl/android/security/dice/IDiceNode.h>
-#include <aidl/android/system/virtualmachineservice/IVirtualMachineService.h>
#include <aidl/com/android/microdroid/testservice/BnTestService.h>
#include <android-base/file.h>
#include <android-base/properties.h>
@@ -33,11 +32,11 @@
#include <binder_rpc_unstable.hpp>
#include <string>
+#include "vm_payload.h"
+
using aidl::android::hardware::security::dice::BccHandover;
using aidl::android::security::dice::IDiceNode;
-using aidl::android::system::virtualmachineservice::IVirtualMachineService;
-
using android::base::ErrnoError;
using android::base::Error;
using android::base::Result;
@@ -133,23 +132,11 @@
auto testService = ndk::SharedRefBase::make<TestService>();
auto callback = []([[maybe_unused]] void* param) {
- // Tell microdroid_manager that we're ready.
- // If we can't, abort in order to fail fast - the host won't proceed without
- // receiving the onReady signal.
- ndk::SpAIBinder binder(
- RpcClient(VMADDR_CID_HOST, IVirtualMachineService::VM_BINDER_SERVICE_PORT));
- auto virtualMachineService = IVirtualMachineService::fromBinder(binder);
- if (virtualMachineService == nullptr) {
- std::cerr << "failed to connect VirtualMachineService\n";
- abort();
- }
- if (auto status = virtualMachineService->notifyPayloadReady(); !status.isOk()) {
- std::cerr << "failed to notify payload ready to virtualizationservice: "
- << status.getDescription() << std::endl;
+ if (!notify_payload_ready()) {
+ std::cerr << "failed to notify payload ready to virtualizationservice" << std::endl;
abort();
}
};
-
if (!RunRpcServerCallback(testService->asBinder().get(), testService->SERVICE_PORT, callback,
nullptr)) {
return Error() << "RPC Server failed to run";