1#![cfg(target_os = "linux")]
7
8use crate::run::RunContext;
9use crate::run::RunnerBuilder;
10use crate::run::TestResult;
11use guestmem::GuestMemory;
12use std::sync::Arc;
13use virt::Partition;
14use virt_mshv_vtl::UhLateParams;
15use virt_mshv_vtl::UhPartitionNewParams;
16use virt_mshv_vtl::UhProcessorBox;
17
18impl RunContext<'_> {
19 pub async fn run_paravisor_vmm(
20 &mut self,
21 isolation: virt::IsolationType,
22 test: &crate::load::TestInfo,
23 ) -> anyhow::Result<TestResult> {
24 let params = UhPartitionNewParams {
25 isolation,
26 hide_isolation: false,
27 lower_vtl_memory_layout: &self.state.memory_layout,
28 topology: &self.state.processor_topology,
29 cvm_cpuid_info: None,
30 snp_secrets: None,
31 vtom: None,
32 handle_synic: true,
33 no_sidecar_hotplug: false,
34 use_mmio_hypercalls: false,
35 intercept_debug_exceptions: false,
36 };
37 let p = virt_mshv_vtl::UhProtoPartition::new(params, |_| self.state.driver.clone())?;
38
39 let m = underhill_mem::init(&underhill_mem::Init {
40 processor_topology: &self.state.processor_topology,
41 isolation,
42 vtl0_alias_map_bit: None,
43 vtom: None,
44 mem_layout: &self.state.memory_layout,
45 complete_memory_layout: &self.state.memory_layout,
46 boot_init: None,
47 shared_pool: &[],
48 maximum_vtl: hvdef::Vtl::Vtl0,
49 })
50 .await?;
51
52 let (partition, vps) = p
53 .build(UhLateParams {
54 gm: [
55 m.vtl0().clone(),
56 m.vtl1().cloned().unwrap_or(GuestMemory::empty()),
57 ]
58 .into(),
59 vtl0_kernel_exec_gm: m.vtl0().clone(),
60 vtl0_user_exec_gm: m.vtl0().clone(),
61 #[cfg(guest_arch = "x86_64")]
62 cpuid: Vec::new(),
63 crash_notification_send: mesh::channel().0,
64 vmtime: self.vmtime_source,
65 cvm_params: None,
66 vmbus_relay: false,
67 })
68 .await?;
69
70 let partition = Arc::new(partition);
71
72 let mut threads = Vec::new();
73 let r = self
74 .run(m.vtl0(), partition.caps(), test, async |_this, runner| {
75 let [vp] = vps.try_into().ok().unwrap();
76 threads.push(start_vp(vp, runner).await?);
77 Ok(())
78 })
79 .await?;
80
81 for thread in threads {
82 thread.join().unwrap();
83 }
84
85 Arc::into_inner(partition).expect("partition is no longer referenced");
87
88 Ok(r)
89 }
90}
91
92async fn start_vp(
93 mut vp: UhProcessorBox,
94 mut runner: RunnerBuilder,
95) -> anyhow::Result<std::thread::JoinHandle<()>> {
96 let vp_thread = std::thread::spawn(move || {
97 let pool = pal_uring::IoUringPool::new("vp", 256).unwrap();
98 let driver = pool.client().initiator().clone();
99 pool.client().set_idle_task(async move |mut control| {
100 let vp = vp
101 .bind_processor::<virt_mshv_vtl::HypervisorBacked>(&driver, Some(&mut control))
102 .unwrap();
103
104 runner.build(vp).unwrap().run_vp().await;
105 });
106 pool.run()
107 });
108 Ok(vp_thread)
109}