1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::collections::BTreeMap;
6 use std::thread;
7 use std::thread::JoinHandle;
8 use std::time::Duration;
9
10 use anyhow::Result;
11 use arch::RunnableLinuxVm;
12 use arch::VcpuArch;
13 use arch::VirtioDeviceStub;
14 use arch::VmArch;
15 use base::info;
16 use base::AsRawDescriptor;
17 use base::CloseNotifier;
18 use base::Event;
19 use base::EventToken;
20 use base::ProtoTube;
21 use base::ReadNotifier;
22 use base::SendTube;
23 use base::Tube;
24 use base::WaitContext;
25 use crosvm_cli::sys::windows::exit::Exit;
26 use crosvm_cli::sys::windows::exit::ExitContext;
27 use devices::virtio;
28 #[cfg(feature = "gpu")]
29 use devices::virtio::gpu::EventDevice;
30 #[cfg(feature = "gpu")]
31 use devices::virtio::vhost::user::gpu::sys::windows::product::GpuBackendConfig as GpuBackendConfigProduct;
32 #[cfg(feature = "gpu")]
33 use devices::virtio::vhost::user::gpu::sys::windows::product::GpuVmmConfig as GpuVmmConfigProduct;
34 #[cfg(feature = "gpu")]
35 use devices::virtio::vhost::user::gpu::sys::windows::product::WindowProcedureThreadVmmConfig as WindowProcedureThreadVmmConfigProduct;
36 #[cfg(feature = "gpu")]
37 use devices::virtio::vhost::user::gpu::sys::windows::GpuVmmConfig;
38 #[cfg(feature = "gpu")]
39 use devices::virtio::vhost::user::gpu::sys::windows::InputEventVmmConfig;
40 #[cfg(feature = "gpu")]
41 use devices::virtio::vhost::user::gpu::sys::windows::WindowProcedureThreadVmmConfig;
42 #[cfg(feature = "audio")]
43 use devices::virtio::vhost::user::snd::sys::windows::product::SndBackendConfig as SndBackendConfigProduct;
44 #[cfg(feature = "audio")]
45 use devices::virtio::vhost::user::snd::sys::windows::product::SndVmmConfig as SndVmmConfigProduct;
46 #[cfg(feature = "audio")]
47 use devices::virtio::vhost::user::snd::sys::windows::SndVmmConfig;
48 #[cfg(feature = "gpu")]
49 use devices::virtio::DisplayBackend;
50 #[cfg(feature = "gpu")]
51 use devices::virtio::Gpu;
52 #[cfg(feature = "gpu")]
53 use devices::virtio::GpuParameters;
54 #[cfg(feature = "gpu")]
55 use gpu_display::WindowProcedureThread;
56 #[cfg(feature = "gpu")]
57 use gpu_display::WindowProcedureThreadBuilder;
58 pub(crate) use metrics::log_descriptor;
59 pub(crate) use metrics::MetricEventType;
60 use sync::Mutex;
61 #[cfg(feature = "balloon")]
62 use vm_control::BalloonTube;
63 use vm_control::PvClockCommand;
64 use vm_control::VmRequest;
65 use vm_control::VmResponse;
66 use vm_control::VmRunMode;
67
68 use super::run_vcpu::VcpuRunMode;
69 use crate::crosvm::config::Config;
70 use crate::crosvm::sys::cmdline::RunMetricsCommand;
71 use crate::sys::windows::TaggedControlTube as SharedTaggedControlTube;
72
73 pub struct MessageFromService {}
74
75 pub struct ServiceVmState {}
76
77 impl ServiceVmState {
set_memory_size(&mut self, _size: u64)78 pub fn set_memory_size(&mut self, _size: u64) {}
generate_send_state_message(&self)79 pub fn generate_send_state_message(&self) {}
80 }
81
82 pub(super) struct RunControlArgs {}
83
84 #[derive(Debug)]
85 pub(super) enum TaggedControlTube {
86 Unused,
87 }
88
89 impl ReadNotifier for TaggedControlTube {
get_read_notifier(&self) -> &dyn AsRawDescriptor90 fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
91 panic!(
92 "get_read_notifier called on generic tagged control: {:?}",
93 self
94 )
95 }
96 }
97
98 impl CloseNotifier for TaggedControlTube {
get_close_notifier(&self) -> &dyn AsRawDescriptor99 fn get_close_notifier(&self) -> &dyn AsRawDescriptor {
100 panic!(
101 "get_read_notifier called on generic tagged control: {:?}",
102 self
103 )
104 }
105 }
106
107 #[derive(EventToken, Debug)]
108 pub(super) enum Token {
109 VmEvent,
110 BrokerShutdown,
111 VmControlServer,
112 VmControl { id: usize },
113 BalloonTube,
114 }
115
handle_hungup_event(token: &Token)116 pub(super) fn handle_hungup_event(token: &Token) {
117 panic!(
118 "Unable to handle hungup on a shared token in product specific handler: {:?}",
119 token
120 )
121 }
122
setup_common_metric_invariants(cfg: &Config)123 pub(super) fn setup_common_metric_invariants(cfg: &Config) {}
124
125 // Sets package name to the name contained in `msg`.
set_package_name(msg: &MessageFromService)126 pub(super) fn set_package_name(msg: &MessageFromService) {}
127
get_run_control_args(cfg: &mut Config) -> RunControlArgs128 pub(super) fn get_run_control_args(cfg: &mut Config) -> RunControlArgs {
129 RunControlArgs {}
130 }
131 // Merges session invariants.
merge_session_invariants(serialized_session_invariants: &[u8])132 pub(super) fn merge_session_invariants(serialized_session_invariants: &[u8]) {}
133
134 // Handles sending command to pvclock device.
handle_pvclock_request(tube: &Option<Tube>, command: PvClockCommand) -> Result<()>135 pub(super) fn handle_pvclock_request(tube: &Option<Tube>, command: PvClockCommand) -> Result<()> {
136 Ok(())
137 }
138
139 // Run ime thread.
run_ime_thread( product_args: &mut RunControlArgs, exit_evt: &Event, ) -> Result<Option<JoinHandle<Result<()>>>>140 pub(super) fn run_ime_thread(
141 product_args: &mut RunControlArgs,
142 exit_evt: &Event,
143 ) -> Result<Option<JoinHandle<Result<()>>>> {
144 Ok(None)
145 }
146
create_snd_state_tube( control_tubes: &mut [SharedTaggedControlTube], ) -> Result<Option<Tube>>147 pub(super) fn create_snd_state_tube(
148 control_tubes: &mut [SharedTaggedControlTube],
149 ) -> Result<Option<Tube>> {
150 Ok(None)
151 }
152
create_snd_mute_tube_pair() -> Result<(Option<Tube>, Option<Tube>)>153 pub(super) fn create_snd_mute_tube_pair() -> Result<(Option<Tube>, Option<Tube>)> {
154 Ok((None, None))
155 }
156
157 // Returns two tubes and a handle to service_ipc. One for ipc_main_loop and another
158 // for proto_main_loop.
start_service_ipc_listener( service_pipe_name: Option<String>, ) -> Result<(Option<Tube>, Option<ProtoTube>, Option<()>)>159 pub(super) fn start_service_ipc_listener(
160 service_pipe_name: Option<String>,
161 ) -> Result<(Option<Tube>, Option<ProtoTube>, Option<()>)> {
162 Ok((None, None, None))
163 }
164
handle_tagged_control_tube_event( product_tube: &TaggedControlTube, virtio_snd_host_mute_tube: &mut Option<Tube>, service_vm_state: &mut ServiceVmState, ipc_main_loop_tube: Option<&Tube>, )165 pub(super) fn handle_tagged_control_tube_event(
166 product_tube: &TaggedControlTube,
167 virtio_snd_host_mute_tube: &mut Option<Tube>,
168 service_vm_state: &mut ServiceVmState,
169 ipc_main_loop_tube: Option<&Tube>,
170 ) {
171 }
172
push_triggers<'a>( _triggers: &mut [(&'a dyn AsRawDescriptor, Token)], ipc_tube: &'a Option<Tube>, proto_tube: &'a Option<ProtoTube>, )173 pub(super) fn push_triggers<'a>(
174 _triggers: &mut [(&'a dyn AsRawDescriptor, Token)],
175 ipc_tube: &'a Option<Tube>,
176 proto_tube: &'a Option<ProtoTube>,
177 ) {
178 if ipc_tube.is_some() {
179 panic!("trying to push non-none ipc tube in generic product");
180 }
181 if proto_tube.is_some() {
182 panic!("trying to push non-none proto tube in generic product");
183 }
184 }
185
handle_received_token<'a, V: VmArch + 'static, Vcpu: VcpuArch + 'static, F>( token: &Token, _anti_tamper_main_thread_tube: &Option<ProtoTube>, #[cfg(feature = "balloon")] _balloon_tube: Option<&mut BalloonTube>, _control_tubes: &BTreeMap<usize, SharedTaggedControlTube>, _guest_os: &mut RunnableLinuxVm<V, Vcpu>, _ipc_main_loop_tube: Option<&Tube>, _memory_size_mb: u64, _proto_main_loop_tube: Option<&ProtoTube>, _pvclock_host_tube: &Option<Tube>, _run_mode_arc: &VcpuRunMode, _service_vm_state: &mut ServiceVmState, _vcpu_boxes: &Mutex<Vec<Box<dyn VcpuArch>>>, _virtio_snd_host_mute_tube: &mut Option<Tube>, _execute_vm_request: F, ) -> Option<VmRunMode> where F: FnMut(VmRequest, &'a mut RunnableLinuxVm<V, Vcpu>) -> (VmResponse, Option<VmRunMode>),186 pub(super) fn handle_received_token<'a, V: VmArch + 'static, Vcpu: VcpuArch + 'static, F>(
187 token: &Token,
188 _anti_tamper_main_thread_tube: &Option<ProtoTube>,
189 #[cfg(feature = "balloon")] _balloon_tube: Option<&mut BalloonTube>,
190 _control_tubes: &BTreeMap<usize, SharedTaggedControlTube>,
191 _guest_os: &mut RunnableLinuxVm<V, Vcpu>,
192 _ipc_main_loop_tube: Option<&Tube>,
193 _memory_size_mb: u64,
194 _proto_main_loop_tube: Option<&ProtoTube>,
195 _pvclock_host_tube: &Option<Tube>,
196 _run_mode_arc: &VcpuRunMode,
197 _service_vm_state: &mut ServiceVmState,
198 _vcpu_boxes: &Mutex<Vec<Box<dyn VcpuArch>>>,
199 _virtio_snd_host_mute_tube: &mut Option<Tube>,
200 _execute_vm_request: F,
201 ) -> Option<VmRunMode>
202 where
203 F: FnMut(VmRequest, &'a mut RunnableLinuxVm<V, Vcpu>) -> (VmResponse, Option<VmRunMode>),
204 {
205 panic!(
206 "Received an unrecognized shared token to product specific handler: {:?}",
207 token
208 )
209 }
210
spawn_anti_tamper_thread(wait_ctx: &WaitContext<Token>) -> Option<ProtoTube>211 pub(super) fn spawn_anti_tamper_thread(wait_ctx: &WaitContext<Token>) -> Option<ProtoTube> {
212 None
213 }
214
create_service_vm_state(_memory_size_mb: u64) -> ServiceVmState215 pub(super) fn create_service_vm_state(_memory_size_mb: u64) -> ServiceVmState {
216 ServiceVmState {}
217 }
218
219 #[cfg(feature = "gpu")]
create_gpu( vm_evt_wrtube: &SendTube, gpu_control_tube: Tube, resource_bridges: Vec<Tube>, display_backends: Vec<DisplayBackend>, gpu_parameters: &GpuParameters, event_devices: Vec<EventDevice>, features: u64, _product_args: GpuBackendConfigProduct, wndproc_thread: WindowProcedureThread, ) -> Result<Gpu>220 pub(super) fn create_gpu(
221 vm_evt_wrtube: &SendTube,
222 gpu_control_tube: Tube,
223 resource_bridges: Vec<Tube>,
224 display_backends: Vec<DisplayBackend>,
225 gpu_parameters: &GpuParameters,
226 event_devices: Vec<EventDevice>,
227 features: u64,
228 _product_args: GpuBackendConfigProduct,
229 wndproc_thread: WindowProcedureThread,
230 ) -> Result<Gpu> {
231 Ok(Gpu::new(
232 vm_evt_wrtube
233 .try_clone()
234 .exit_context(Exit::CloneTube, "failed to clone tube")?,
235 gpu_control_tube,
236 resource_bridges,
237 display_backends,
238 gpu_parameters,
239 None,
240 event_devices,
241 features,
242 &BTreeMap::new(),
243 wndproc_thread,
244 ))
245 }
246
247 #[cfg(feature = "gpu")]
push_window_procedure_thread_control_tubes( #[allow(clippy::ptr_arg)] _control_tubes: &mut Vec<SharedTaggedControlTube>, _: &mut WindowProcedureThreadVmmConfig, )248 pub(super) fn push_window_procedure_thread_control_tubes(
249 #[allow(clippy::ptr_arg)]
250 // The implementor can extend the size of this argument, so mutable slice is not enough.
251 _control_tubes: &mut Vec<SharedTaggedControlTube>,
252 _: &mut WindowProcedureThreadVmmConfig,
253 ) {
254 }
255
256 #[cfg(feature = "gpu")]
push_gpu_control_tubes( _control_tubes: &mut [SharedTaggedControlTube], _gpu_vmm_config: &mut GpuVmmConfig, )257 pub(super) fn push_gpu_control_tubes(
258 _control_tubes: &mut [SharedTaggedControlTube],
259 _gpu_vmm_config: &mut GpuVmmConfig,
260 ) {
261 }
262
263 #[cfg(feature = "audio")]
push_snd_control_tubes( _control_tubes: &mut [SharedTaggedControlTube], _snd_vmm_config: &mut SndVmmConfig, )264 pub(super) fn push_snd_control_tubes(
265 _control_tubes: &mut [SharedTaggedControlTube],
266 _snd_vmm_config: &mut SndVmmConfig,
267 ) {
268 }
269
270 #[cfg(feature = "audio")]
num_input_sound_devices(_cfg: &Config) -> u32271 pub(crate) fn num_input_sound_devices(_cfg: &Config) -> u32 {
272 0
273 }
274
275 #[cfg(feature = "audio")]
num_input_sound_streams(_cfg: &Config) -> u32276 pub(crate) fn num_input_sound_streams(_cfg: &Config) -> u32 {
277 0
278 }
279
280 #[cfg(feature = "gpu")]
get_gpu_product_configs( cfg: &Config, alias_pid: u32, ) -> Result<(GpuBackendConfigProduct, GpuVmmConfigProduct)>281 pub(crate) fn get_gpu_product_configs(
282 cfg: &Config,
283 alias_pid: u32,
284 ) -> Result<(GpuBackendConfigProduct, GpuVmmConfigProduct)> {
285 Ok((GpuBackendConfigProduct {}, GpuVmmConfigProduct {}))
286 }
287
288 #[cfg(feature = "audio")]
get_snd_product_configs( _cfg: &Config, _alias_pid: u32, ) -> Result<(SndBackendConfigProduct, SndVmmConfigProduct)>289 pub(crate) fn get_snd_product_configs(
290 _cfg: &Config,
291 _alias_pid: u32,
292 ) -> Result<(SndBackendConfigProduct, SndVmmConfigProduct)> {
293 Ok((SndBackendConfigProduct {}, SndVmmConfigProduct {}))
294 }
295
296 #[cfg(feature = "audio")]
virtio_sound_enabled() -> bool297 pub(super) fn virtio_sound_enabled() -> bool {
298 false
299 }
300
run_metrics(_args: RunMetricsCommand) -> Result<()>301 pub(crate) fn run_metrics(_args: RunMetricsCommand) -> Result<()> {
302 info!("sleep forever. We will get killed by broker");
303 thread::sleep(Duration::MAX);
304 Ok(())
305 }
306
setup_metrics_reporting() -> Result<()>307 pub(crate) fn setup_metrics_reporting() -> Result<()> {
308 Ok(())
309 }
310
push_mouse_device( cfg: &Config, #[cfg(feature = "gpu")] _input_event_vmm_config: &mut InputEventVmmConfig, _devs: &mut [VirtioDeviceStub], ) -> Result<()>311 pub(super) fn push_mouse_device(
312 cfg: &Config,
313 #[cfg(feature = "gpu")] _input_event_vmm_config: &mut InputEventVmmConfig,
314 _devs: &mut [VirtioDeviceStub],
315 ) -> Result<()> {
316 Ok(())
317 }
318
push_pvclock_device( cfg: &Config, devs: &mut [VirtioDeviceStub], tsc_frequency: u64, tube: Tube, )319 pub(super) fn push_pvclock_device(
320 cfg: &Config,
321 devs: &mut [VirtioDeviceStub],
322 tsc_frequency: u64,
323 tube: Tube,
324 ) {
325 }
326
327 #[cfg(feature = "gpu")]
get_window_procedure_thread_product_configs( _: &Config, _: &mut WindowProcedureThreadBuilder, _main_alias_pid: u32, _device_alias_pid: u32, ) -> Result<WindowProcedureThreadVmmConfigProduct>328 pub(crate) fn get_window_procedure_thread_product_configs(
329 _: &Config,
330 _: &mut WindowProcedureThreadBuilder,
331 _main_alias_pid: u32,
332 _device_alias_pid: u32,
333 ) -> Result<WindowProcedureThreadVmmConfigProduct> {
334 Ok(WindowProcedureThreadVmmConfigProduct {})
335 }
336