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::InitialAudioSessionState;
64 use vm_control::PvClockCommand;
65 use vm_control::VmRequest;
66 use vm_control::VmResponse;
67 use vm_control::VmRunMode;
68
69 use super::run_vcpu::VcpuRunMode;
70 use crate::crosvm::config::Config;
71 use crate::crosvm::sys::cmdline::RunMetricsCommand;
72 use crate::sys::windows::TaggedControlTube as SharedTaggedControlTube;
73
74 pub struct MessageFromService {}
75
76 pub struct ServiceVmState {}
77
78 impl ServiceVmState {
set_memory_size(&mut self, _size: u64)79 pub fn set_memory_size(&mut self, _size: u64) {}
generate_send_state_message(&self)80 pub fn generate_send_state_message(&self) {}
81 }
82
83 pub struct ServiceAudioStates {}
84
85 pub(super) struct RunControlArgs {}
86
87 #[derive(Debug)]
88 pub(super) enum TaggedControlTube {
89 Unused,
90 }
91
92 impl ReadNotifier for TaggedControlTube {
get_read_notifier(&self) -> &dyn AsRawDescriptor93 fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
94 panic!(
95 "get_read_notifier called on generic tagged control: {:?}",
96 self
97 )
98 }
99 }
100
101 impl CloseNotifier for TaggedControlTube {
get_close_notifier(&self) -> &dyn AsRawDescriptor102 fn get_close_notifier(&self) -> &dyn AsRawDescriptor {
103 panic!(
104 "get_read_notifier called on generic tagged control: {:?}",
105 self
106 )
107 }
108 }
109
110 #[derive(EventToken, Debug)]
111 pub(super) enum Token {
112 VmEvent,
113 BrokerShutdown,
114 VmControlServer,
115 VmControl { id: usize },
116 BalloonTube,
117 }
118
handle_hungup_event(token: &Token)119 pub(super) fn handle_hungup_event(token: &Token) {
120 panic!(
121 "Unable to handle hungup on a shared token in product specific handler: {:?}",
122 token
123 )
124 }
125
setup_common_metric_invariants(cfg: &Config)126 pub(super) fn setup_common_metric_invariants(cfg: &Config) {}
127
128 // Sets package name to the name contained in `msg`.
set_package_name(msg: &MessageFromService)129 pub(super) fn set_package_name(msg: &MessageFromService) {}
130
get_run_control_args(cfg: &mut Config) -> RunControlArgs131 pub(super) fn get_run_control_args(cfg: &mut Config) -> RunControlArgs {
132 RunControlArgs {}
133 }
134 // Merges session invariants.
merge_session_invariants(serialized_session_invariants: &[u8])135 pub(super) fn merge_session_invariants(serialized_session_invariants: &[u8]) {}
136
137 // Handles sending command to pvclock device.
138 #[cfg(feature = "pvclock")]
handle_pvclock_request(tube: &Option<Tube>, command: PvClockCommand) -> Result<()>139 pub(super) fn handle_pvclock_request(tube: &Option<Tube>, command: PvClockCommand) -> Result<()> {
140 Ok(())
141 }
142
143 // Run ime thread.
run_ime_thread( product_args: &mut RunControlArgs, exit_evt: &Event, ) -> Result<Option<JoinHandle<Result<()>>>>144 pub(super) fn run_ime_thread(
145 product_args: &mut RunControlArgs,
146 exit_evt: &Event,
147 ) -> Result<Option<JoinHandle<Result<()>>>> {
148 Ok(None)
149 }
150
create_snd_state_tube( control_tubes: &mut [SharedTaggedControlTube], ) -> Result<Option<Tube>>151 pub(super) fn create_snd_state_tube(
152 control_tubes: &mut [SharedTaggedControlTube],
153 ) -> Result<Option<Tube>> {
154 Ok(None)
155 }
156
create_snd_mute_tube_pair() -> Result<(Option<Tube>, Option<Tube>)>157 pub(super) fn create_snd_mute_tube_pair() -> Result<(Option<Tube>, Option<Tube>)> {
158 Ok((None, None))
159 }
160
161 // Returns two tubes and a handle to service_ipc. One for ipc_main_loop and another
162 // for proto_main_loop.
start_service_ipc_listener( service_pipe_name: Option<String>, ) -> Result<(Option<Tube>, Option<ProtoTube>, Option<()>)>163 pub(super) fn start_service_ipc_listener(
164 service_pipe_name: Option<String>,
165 ) -> Result<(Option<Tube>, Option<ProtoTube>, Option<()>)> {
166 Ok((None, None, None))
167 }
168
handle_tagged_control_tube_event( product_tube: &TaggedControlTube, virtio_snd_host_mute_tubes: &mut [Tube], service_vm_state: &mut ServiceVmState, ipc_main_loop_tube: Option<&Tube>, )169 pub(super) fn handle_tagged_control_tube_event(
170 product_tube: &TaggedControlTube,
171 virtio_snd_host_mute_tubes: &mut [Tube],
172 service_vm_state: &mut ServiceVmState,
173 ipc_main_loop_tube: Option<&Tube>,
174 ) {
175 }
176
push_triggers<'a>( _triggers: &mut [(&'a dyn AsRawDescriptor, Token)], ipc_tube: &'a Option<Tube>, proto_tube: &'a Option<ProtoTube>, )177 pub(super) fn push_triggers<'a>(
178 _triggers: &mut [(&'a dyn AsRawDescriptor, Token)],
179 ipc_tube: &'a Option<Tube>,
180 proto_tube: &'a Option<ProtoTube>,
181 ) {
182 if ipc_tube.is_some() {
183 panic!("trying to push non-none ipc tube in generic product");
184 }
185 if proto_tube.is_some() {
186 panic!("trying to push non-none proto tube in generic product");
187 }
188 }
189
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>, #[cfg(feature = "pvclock")] _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 [Tube], _execute_vm_request: F, ) -> Option<VmRunMode> where F: FnMut(VmRequest, &'a mut RunnableLinuxVm<V, Vcpu>) -> (VmResponse, Option<VmRunMode>),190 pub(super) fn handle_received_token<'a, V: VmArch + 'static, Vcpu: VcpuArch + 'static, F>(
191 token: &Token,
192 _anti_tamper_main_thread_tube: &Option<ProtoTube>,
193 #[cfg(feature = "balloon")] _balloon_tube: Option<&mut BalloonTube>,
194 _control_tubes: &BTreeMap<usize, SharedTaggedControlTube>,
195 _guest_os: &mut RunnableLinuxVm<V, Vcpu>,
196 _ipc_main_loop_tube: Option<&Tube>,
197 _memory_size_mb: u64,
198 _proto_main_loop_tube: Option<&ProtoTube>,
199 #[cfg(feature = "pvclock")] _pvclock_host_tube: &Option<Tube>,
200 _run_mode_arc: &VcpuRunMode,
201 _service_vm_state: &mut ServiceVmState,
202 _vcpu_boxes: &Mutex<Vec<Box<dyn VcpuArch>>>,
203 _virtio_snd_host_mute_tube: &mut [Tube],
204 _execute_vm_request: F,
205 ) -> Option<VmRunMode>
206 where
207 F: FnMut(VmRequest, &'a mut RunnableLinuxVm<V, Vcpu>) -> (VmResponse, Option<VmRunMode>),
208 {
209 panic!(
210 "Received an unrecognized shared token to product specific handler: {:?}",
211 token
212 )
213 }
214
spawn_anti_tamper_thread(wait_ctx: &WaitContext<Token>) -> Option<ProtoTube>215 pub(super) fn spawn_anti_tamper_thread(wait_ctx: &WaitContext<Token>) -> Option<ProtoTube> {
216 None
217 }
218
create_service_vm_state(_memory_size_mb: u64) -> ServiceVmState219 pub(super) fn create_service_vm_state(_memory_size_mb: u64) -> ServiceVmState {
220 ServiceVmState {}
221 }
222
223 #[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>224 pub(super) fn create_gpu(
225 vm_evt_wrtube: &SendTube,
226 gpu_control_tube: Tube,
227 resource_bridges: Vec<Tube>,
228 display_backends: Vec<DisplayBackend>,
229 gpu_parameters: &GpuParameters,
230 event_devices: Vec<EventDevice>,
231 features: u64,
232 _product_args: GpuBackendConfigProduct,
233 wndproc_thread: WindowProcedureThread,
234 ) -> Result<Gpu> {
235 Ok(Gpu::new(
236 vm_evt_wrtube
237 .try_clone()
238 .exit_context(Exit::CloneTube, "failed to clone tube")?,
239 gpu_control_tube,
240 resource_bridges,
241 display_backends,
242 gpu_parameters,
243 None,
244 event_devices,
245 features,
246 &BTreeMap::new(),
247 wndproc_thread,
248 ))
249 }
250
create_service_audio_states_and_send_to_service( initial_audio_session_states: Vec<InitialAudioSessionState>, ipc_main_loop_tube: &Option<Tube>, ) -> Result<ServiceAudioStates>251 pub(super) fn create_service_audio_states_and_send_to_service(
252 initial_audio_session_states: Vec<InitialAudioSessionState>,
253 ipc_main_loop_tube: &Option<Tube>,
254 ) -> Result<ServiceAudioStates> {
255 Ok(ServiceAudioStates {})
256 }
257
258 #[cfg(feature = "gpu")]
push_window_procedure_thread_control_tubes( #[allow(clippy::ptr_arg)] _control_tubes: &mut Vec<SharedTaggedControlTube>, _: &mut WindowProcedureThreadVmmConfig, )259 pub(super) fn push_window_procedure_thread_control_tubes(
260 #[allow(clippy::ptr_arg)]
261 // The implementor can extend the size of this argument, so mutable slice is not enough.
262 _control_tubes: &mut Vec<SharedTaggedControlTube>,
263 _: &mut WindowProcedureThreadVmmConfig,
264 ) {
265 }
266
267 #[cfg(feature = "gpu")]
push_gpu_control_tubes( _control_tubes: &mut [SharedTaggedControlTube], _gpu_vmm_config: &mut GpuVmmConfig, )268 pub(super) fn push_gpu_control_tubes(
269 _control_tubes: &mut [SharedTaggedControlTube],
270 _gpu_vmm_config: &mut GpuVmmConfig,
271 ) {
272 }
273
274 #[cfg(feature = "audio")]
push_snd_control_tubes( _control_tubes: &mut [SharedTaggedControlTube], _snd_vmm_config: &mut SndVmmConfig, )275 pub(super) fn push_snd_control_tubes(
276 _control_tubes: &mut [SharedTaggedControlTube],
277 _snd_vmm_config: &mut SndVmmConfig,
278 ) {
279 }
280
281 #[cfg(feature = "audio")]
num_input_sound_devices(_cfg: &Config) -> u32282 pub(crate) fn num_input_sound_devices(_cfg: &Config) -> u32 {
283 0
284 }
285
286 #[cfg(feature = "audio")]
num_input_sound_streams(_cfg: &Config) -> u32287 pub(crate) fn num_input_sound_streams(_cfg: &Config) -> u32 {
288 0
289 }
290
291 #[cfg(feature = "gpu")]
get_gpu_product_configs( cfg: &Config, alias_pid: u32, ) -> Result<(GpuBackendConfigProduct, GpuVmmConfigProduct)>292 pub(crate) fn get_gpu_product_configs(
293 cfg: &Config,
294 alias_pid: u32,
295 ) -> Result<(GpuBackendConfigProduct, GpuVmmConfigProduct)> {
296 Ok((GpuBackendConfigProduct {}, GpuVmmConfigProduct {}))
297 }
298
299 #[cfg(feature = "audio")]
get_snd_product_configs() -> Result<(SndBackendConfigProduct, SndVmmConfigProduct)>300 pub(crate) fn get_snd_product_configs() -> Result<(SndBackendConfigProduct, SndVmmConfigProduct)> {
301 Ok((SndBackendConfigProduct {}, SndVmmConfigProduct {}))
302 }
303
run_metrics(_args: RunMetricsCommand) -> Result<()>304 pub(crate) fn run_metrics(_args: RunMetricsCommand) -> Result<()> {
305 info!("sleep forever. We will get killed by broker");
306 thread::sleep(Duration::MAX);
307 Ok(())
308 }
309
setup_metrics_reporting() -> Result<()>310 pub(crate) fn setup_metrics_reporting() -> Result<()> {
311 Ok(())
312 }
313
push_mouse_device( cfg: &Config, #[cfg(feature = "gpu")] _input_event_vmm_config: &mut InputEventVmmConfig, _devs: &mut [VirtioDeviceStub], ) -> Result<()>314 pub(super) fn push_mouse_device(
315 cfg: &Config,
316 #[cfg(feature = "gpu")] _input_event_vmm_config: &mut InputEventVmmConfig,
317 _devs: &mut [VirtioDeviceStub],
318 ) -> Result<()> {
319 Ok(())
320 }
321
322 #[cfg(feature = "pvclock")]
push_pvclock_device( cfg: &Config, devs: &mut [VirtioDeviceStub], tsc_frequency: u64, tube: Tube, )323 pub(super) fn push_pvclock_device(
324 cfg: &Config,
325 devs: &mut [VirtioDeviceStub],
326 tsc_frequency: u64,
327 tube: Tube,
328 ) {
329 }
330
331 #[cfg(feature = "gpu")]
get_window_procedure_thread_product_configs( _: &Config, _: &mut WindowProcedureThreadBuilder, _main_alias_pid: u32, _device_alias_pid: u32, ) -> Result<WindowProcedureThreadVmmConfigProduct>332 pub(crate) fn get_window_procedure_thread_product_configs(
333 _: &Config,
334 _: &mut WindowProcedureThreadBuilder,
335 _main_alias_pid: u32,
336 _device_alias_pid: u32,
337 ) -> Result<WindowProcedureThreadVmmConfigProduct> {
338 Ok(WindowProcedureThreadVmmConfigProduct {})
339 }
340