• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2025 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Tests running an early VM
16 
17 use android_system_virtualizationservice::{
18     aidl::android::system::virtualizationservice::{
19         IVirtualizationService::IVirtualizationService, VirtualMachineConfig::VirtualMachineConfig,
20         VirtualMachineRawConfig::VirtualMachineRawConfig,
21     },
22     binder::{ParcelFileDescriptor, ProcessState, Strong},
23 };
24 use anyhow::{Context, Result};
25 use clap::Parser;
26 use log::info;
27 use std::fs::File;
28 use std::path::PathBuf;
29 
30 use service_vm_comm::{Request, Response, VmType};
31 use service_vm_manager::ServiceVm;
32 use vmclient::VmInstance;
33 
34 const VM_MEMORY_MB: i32 = 16;
35 
36 #[derive(Parser)]
37 /// Collection of CLI for avf_early_vm_test_rialto
38 pub struct Args {
39     /// Path to the Rialto kernel image.
40     #[arg(long)]
41     kernel: PathBuf,
42 
43     /// Whether the VM is protected or not.
44     #[arg(long)]
45     protected: bool,
46 }
47 
get_service() -> Result<Strong<dyn IVirtualizationService>>48 fn get_service() -> Result<Strong<dyn IVirtualizationService>> {
49     let virtmgr = vmclient::VirtualizationService::new_early()
50         .context("Failed to spawn VirtualizationService")?;
51     virtmgr.connect().context("Failed to connect to VirtualizationService")
52 }
53 
main() -> Result<()>54 fn main() -> Result<()> {
55     if std::env::consts::ARCH != "aarch64" {
56         info!("{} not supported. skipping test", std::env::consts::ARCH);
57         return Ok(());
58     }
59 
60     if !cfg!(early_vm_enabled) {
61         info!("early VM disabled. skipping test");
62         return Ok(());
63     }
64 
65     let args = Args::parse();
66 
67     if args.protected {
68         if !hypervisor_props::is_protected_vm_supported()? {
69             info!("pVMs are not supported on device. skipping test");
70             return Ok(());
71         }
72     } else if !hypervisor_props::is_vm_supported()? {
73         info!("non-pVMs are not supported on device. skipping test");
74         return Ok(());
75     }
76 
77     let service = get_service()?;
78     let kernel =
79         File::open(&args.kernel).with_context(|| format!("Failed to open {:?}", &args.kernel))?;
80     let kernel = ParcelFileDescriptor::new(kernel);
81 
82     let vm_config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
83         name: "avf_early_vm_test_launcher".to_owned(),
84         kernel: Some(kernel),
85         protectedVm: args.protected,
86         memoryMib: VM_MEMORY_MB,
87         platformVersion: "~1.0".to_owned(),
88         ..Default::default()
89     });
90 
91     let vm_instance = VmInstance::create(
92         service.as_ref(),
93         &vm_config,
94         // console_in, console_out, and log will be redirected to the kernel log by virtmgr
95         None, // console_in
96         None, // console_out
97         None, // log
98         None, // dump_dt
99     )
100     .context("Failed to create VM")?;
101 
102     ProcessState::start_thread_pool();
103 
104     let vm_type = if args.protected { VmType::ProtectedVm } else { VmType::NonProtectedVm };
105     let mut vm_service = ServiceVm::start_vm(vm_instance, vm_type)?;
106 
107     let request_data = vec![1, 2, 3, 4, 5];
108     let reversed_data = vec![5, 4, 3, 2, 1];
109     let response = vm_service
110         .process_request(Request::Reverse(request_data))
111         .context("Failed to process request")?;
112     assert_eq!(Response::Reverse(reversed_data), response);
113 
114     Ok(())
115 }
116