xref: /aosp_15_r20/external/crosvm/arch/src/sys/linux.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
7*bb4ee6a4SAndroid Build Coastguard Worker 
8*bb4ee6a4SAndroid Build Coastguard Worker use acpi_tables::aml::Aml;
9*bb4ee6a4SAndroid Build Coastguard Worker use base::syslog;
10*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptors;
11*bb4ee6a4SAndroid Build Coastguard Worker use base::Tube;
12*bb4ee6a4SAndroid Build Coastguard Worker use devices::Bus;
13*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusDevice;
14*bb4ee6a4SAndroid Build Coastguard Worker use devices::IommuDevType;
15*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqChip;
16*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqEventSource;
17*bb4ee6a4SAndroid Build Coastguard Worker use devices::ProxyDevice;
18*bb4ee6a4SAndroid Build Coastguard Worker use devices::VfioPlatformDevice;
19*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::ProtectionType;
20*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Vm;
21*bb4ee6a4SAndroid Build Coastguard Worker use minijail::Minijail;
22*bb4ee6a4SAndroid Build Coastguard Worker use resources::AllocOptions;
23*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator;
24*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
25*bb4ee6a4SAndroid Build Coastguard Worker 
26*bb4ee6a4SAndroid Build Coastguard Worker use crate::DeviceRegistrationError;
27*bb4ee6a4SAndroid Build Coastguard Worker 
28*bb4ee6a4SAndroid Build Coastguard Worker /// Adds goldfish battery and returns the platform needed resources including
29*bb4ee6a4SAndroid Build Coastguard Worker /// its AML data and mmio base address
30*bb4ee6a4SAndroid Build Coastguard Worker ///
31*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
32*bb4ee6a4SAndroid Build Coastguard Worker ///
33*bb4ee6a4SAndroid Build Coastguard Worker /// * `amls` - the vector to put the goldfish battery AML
34*bb4ee6a4SAndroid Build Coastguard Worker /// * `battery_jail` - used when sandbox is enabled
35*bb4ee6a4SAndroid Build Coastguard Worker /// * `mmio_bus` - bus to add the devices to
36*bb4ee6a4SAndroid Build Coastguard Worker /// * `irq_chip` - the IrqChip object for registering irq events
37*bb4ee6a4SAndroid Build Coastguard Worker /// * `irq_num` - assigned interrupt to use
38*bb4ee6a4SAndroid Build Coastguard Worker /// * `resources` - the SystemAllocator to allocate IO and MMIO for acpi
add_goldfish_battery( amls: &mut Vec<u8>, battery_jail: Option<Minijail>, mmio_bus: &Bus, irq_chip: &mut dyn IrqChip, irq_num: u32, resources: &mut SystemAllocator, #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>, ) -> Result<(Tube, u64), DeviceRegistrationError>39*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_goldfish_battery(
40*bb4ee6a4SAndroid Build Coastguard Worker     amls: &mut Vec<u8>,
41*bb4ee6a4SAndroid Build Coastguard Worker     battery_jail: Option<Minijail>,
42*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus: &Bus,
43*bb4ee6a4SAndroid Build Coastguard Worker     irq_chip: &mut dyn IrqChip,
44*bb4ee6a4SAndroid Build Coastguard Worker     irq_num: u32,
45*bb4ee6a4SAndroid Build Coastguard Worker     resources: &mut SystemAllocator,
46*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>,
47*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<(Tube, u64), DeviceRegistrationError> {
48*bb4ee6a4SAndroid Build Coastguard Worker     let alloc = resources.get_anon_alloc();
49*bb4ee6a4SAndroid Build Coastguard Worker     let mmio_base = resources
50*bb4ee6a4SAndroid Build Coastguard Worker         .allocate_mmio(
51*bb4ee6a4SAndroid Build Coastguard Worker             devices::bat::GOLDFISHBAT_MMIO_LEN,
52*bb4ee6a4SAndroid Build Coastguard Worker             alloc,
53*bb4ee6a4SAndroid Build Coastguard Worker             "GoldfishBattery".to_string(),
54*bb4ee6a4SAndroid Build Coastguard Worker             AllocOptions::new().align(devices::bat::GOLDFISHBAT_MMIO_LEN),
55*bb4ee6a4SAndroid Build Coastguard Worker         )
56*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(DeviceRegistrationError::AllocateIoResource)?;
57*bb4ee6a4SAndroid Build Coastguard Worker 
58*bb4ee6a4SAndroid Build Coastguard Worker     let (control_tube, response_tube) =
59*bb4ee6a4SAndroid Build Coastguard Worker         Tube::pair().map_err(DeviceRegistrationError::CreateTube)?;
60*bb4ee6a4SAndroid Build Coastguard Worker 
61*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(feature = "power-monitor-powerd")]
62*bb4ee6a4SAndroid Build Coastguard Worker     let (create_monitor, create_client) = (
63*bb4ee6a4SAndroid Build Coastguard Worker         Some(
64*bb4ee6a4SAndroid Build Coastguard Worker             Box::new(power_monitor::powerd::monitor::DBusMonitor::connect)
65*bb4ee6a4SAndroid Build Coastguard Worker                 as Box<dyn power_monitor::CreatePowerMonitorFn>,
66*bb4ee6a4SAndroid Build Coastguard Worker         ),
67*bb4ee6a4SAndroid Build Coastguard Worker         Some(Box::new(power_monitor::powerd::client::DBusClient::connect)
68*bb4ee6a4SAndroid Build Coastguard Worker             as Box<dyn power_monitor::CreatePowerClientFn>),
69*bb4ee6a4SAndroid Build Coastguard Worker     );
70*bb4ee6a4SAndroid Build Coastguard Worker 
71*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(not(feature = "power-monitor-powerd"))]
72*bb4ee6a4SAndroid Build Coastguard Worker     let (create_monitor, create_client) = (None, None);
73*bb4ee6a4SAndroid Build Coastguard Worker 
74*bb4ee6a4SAndroid Build Coastguard Worker     let irq_evt = devices::IrqLevelEvent::new().map_err(DeviceRegistrationError::EventCreate)?;
75*bb4ee6a4SAndroid Build Coastguard Worker 
76*bb4ee6a4SAndroid Build Coastguard Worker     let goldfish_bat = devices::GoldfishBattery::new(
77*bb4ee6a4SAndroid Build Coastguard Worker         mmio_base,
78*bb4ee6a4SAndroid Build Coastguard Worker         irq_num,
79*bb4ee6a4SAndroid Build Coastguard Worker         irq_evt
80*bb4ee6a4SAndroid Build Coastguard Worker             .try_clone()
81*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(DeviceRegistrationError::EventClone)?,
82*bb4ee6a4SAndroid Build Coastguard Worker         response_tube,
83*bb4ee6a4SAndroid Build Coastguard Worker         create_monitor,
84*bb4ee6a4SAndroid Build Coastguard Worker         create_client,
85*bb4ee6a4SAndroid Build Coastguard Worker     )
86*bb4ee6a4SAndroid Build Coastguard Worker     .map_err(DeviceRegistrationError::RegisterBattery)?;
87*bb4ee6a4SAndroid Build Coastguard Worker     goldfish_bat.to_aml_bytes(amls);
88*bb4ee6a4SAndroid Build Coastguard Worker 
89*bb4ee6a4SAndroid Build Coastguard Worker     irq_chip
90*bb4ee6a4SAndroid Build Coastguard Worker         .register_level_irq_event(
91*bb4ee6a4SAndroid Build Coastguard Worker             irq_num,
92*bb4ee6a4SAndroid Build Coastguard Worker             &irq_evt,
93*bb4ee6a4SAndroid Build Coastguard Worker             IrqEventSource::from_device(&goldfish_bat),
94*bb4ee6a4SAndroid Build Coastguard Worker         )
95*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(DeviceRegistrationError::RegisterIrqfd)?;
96*bb4ee6a4SAndroid Build Coastguard Worker 
97*bb4ee6a4SAndroid Build Coastguard Worker     match battery_jail {
98*bb4ee6a4SAndroid Build Coastguard Worker         #[cfg(not(windows))]
99*bb4ee6a4SAndroid Build Coastguard Worker         Some(jail) => {
100*bb4ee6a4SAndroid Build Coastguard Worker             let mut keep_rds = goldfish_bat.keep_rds();
101*bb4ee6a4SAndroid Build Coastguard Worker             syslog::push_descriptors(&mut keep_rds);
102*bb4ee6a4SAndroid Build Coastguard Worker             cros_tracing::push_descriptors!(&mut keep_rds);
103*bb4ee6a4SAndroid Build Coastguard Worker             metrics::push_descriptors(&mut keep_rds);
104*bb4ee6a4SAndroid Build Coastguard Worker             mmio_bus
105*bb4ee6a4SAndroid Build Coastguard Worker                 .insert(
106*bb4ee6a4SAndroid Build Coastguard Worker                     Arc::new(Mutex::new(
107*bb4ee6a4SAndroid Build Coastguard Worker                         ProxyDevice::new(
108*bb4ee6a4SAndroid Build Coastguard Worker                             goldfish_bat,
109*bb4ee6a4SAndroid Build Coastguard Worker                             jail,
110*bb4ee6a4SAndroid Build Coastguard Worker                             keep_rds,
111*bb4ee6a4SAndroid Build Coastguard Worker                             #[cfg(feature = "swap")]
112*bb4ee6a4SAndroid Build Coastguard Worker                             swap_controller,
113*bb4ee6a4SAndroid Build Coastguard Worker                         )
114*bb4ee6a4SAndroid Build Coastguard Worker                         .map_err(DeviceRegistrationError::ProxyDeviceCreation)?,
115*bb4ee6a4SAndroid Build Coastguard Worker                     )),
116*bb4ee6a4SAndroid Build Coastguard Worker                     mmio_base,
117*bb4ee6a4SAndroid Build Coastguard Worker                     devices::bat::GOLDFISHBAT_MMIO_LEN,
118*bb4ee6a4SAndroid Build Coastguard Worker                 )
119*bb4ee6a4SAndroid Build Coastguard Worker                 .map_err(DeviceRegistrationError::MmioInsert)?;
120*bb4ee6a4SAndroid Build Coastguard Worker         }
121*bb4ee6a4SAndroid Build Coastguard Worker         #[cfg(windows)]
122*bb4ee6a4SAndroid Build Coastguard Worker         Some(_) => {}
123*bb4ee6a4SAndroid Build Coastguard Worker         None => {
124*bb4ee6a4SAndroid Build Coastguard Worker             mmio_bus
125*bb4ee6a4SAndroid Build Coastguard Worker                 .insert(
126*bb4ee6a4SAndroid Build Coastguard Worker                     Arc::new(Mutex::new(goldfish_bat)),
127*bb4ee6a4SAndroid Build Coastguard Worker                     mmio_base,
128*bb4ee6a4SAndroid Build Coastguard Worker                     devices::bat::GOLDFISHBAT_MMIO_LEN,
129*bb4ee6a4SAndroid Build Coastguard Worker                 )
130*bb4ee6a4SAndroid Build Coastguard Worker                 .map_err(DeviceRegistrationError::MmioInsert)?;
131*bb4ee6a4SAndroid Build Coastguard Worker         }
132*bb4ee6a4SAndroid Build Coastguard Worker     }
133*bb4ee6a4SAndroid Build Coastguard Worker 
134*bb4ee6a4SAndroid Build Coastguard Worker     Ok((control_tube, mmio_base))
135*bb4ee6a4SAndroid Build Coastguard Worker }
136*bb4ee6a4SAndroid Build Coastguard Worker 
137*bb4ee6a4SAndroid Build Coastguard Worker pub struct PlatformBusResources {
138*bb4ee6a4SAndroid Build Coastguard Worker     pub dt_symbol: String,        // DT symbol (label) assigned to the device
139*bb4ee6a4SAndroid Build Coastguard Worker     pub regions: Vec<(u64, u64)>, // (start address, size)
140*bb4ee6a4SAndroid Build Coastguard Worker     pub irqs: Vec<(u32, u32)>,    // (IRQ number, flags)
141*bb4ee6a4SAndroid Build Coastguard Worker     pub iommus: Vec<(IommuDevType, Option<u32>, Vec<u32>)>, // (IOMMU type, IOMMU identifier, IDs)
142*bb4ee6a4SAndroid Build Coastguard Worker }
143*bb4ee6a4SAndroid Build Coastguard Worker 
144*bb4ee6a4SAndroid Build Coastguard Worker impl PlatformBusResources {
145*bb4ee6a4SAndroid Build Coastguard Worker     const IRQ_TRIGGER_EDGE: u32 = 1;
146*bb4ee6a4SAndroid Build Coastguard Worker     const IRQ_TRIGGER_LEVEL: u32 = 4;
147*bb4ee6a4SAndroid Build Coastguard Worker 
new(symbol: String) -> Self148*bb4ee6a4SAndroid Build Coastguard Worker     fn new(symbol: String) -> Self {
149*bb4ee6a4SAndroid Build Coastguard Worker         Self {
150*bb4ee6a4SAndroid Build Coastguard Worker             dt_symbol: symbol,
151*bb4ee6a4SAndroid Build Coastguard Worker             regions: vec![],
152*bb4ee6a4SAndroid Build Coastguard Worker             irqs: vec![],
153*bb4ee6a4SAndroid Build Coastguard Worker             iommus: vec![],
154*bb4ee6a4SAndroid Build Coastguard Worker         }
155*bb4ee6a4SAndroid Build Coastguard Worker     }
156*bb4ee6a4SAndroid Build Coastguard Worker }
157*bb4ee6a4SAndroid Build Coastguard Worker 
158*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a platform device for use by this Vm.
159*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))]
generate_platform_bus( devices: Vec<(VfioPlatformDevice, Option<Minijail>)>, irq_chip: &mut dyn IrqChip, mmio_bus: &Bus, resources: &mut SystemAllocator, vm: &mut impl Vm, #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>, protection_type: ProtectionType, ) -> Result< ( Vec<Arc<Mutex<dyn BusDevice>>>, BTreeMap<u32, String>, Vec<PlatformBusResources>, ), DeviceRegistrationError, >160*bb4ee6a4SAndroid Build Coastguard Worker pub fn generate_platform_bus(
161*bb4ee6a4SAndroid Build Coastguard Worker     devices: Vec<(VfioPlatformDevice, Option<Minijail>)>,
162*bb4ee6a4SAndroid Build Coastguard Worker     irq_chip: &mut dyn IrqChip,
163*bb4ee6a4SAndroid Build Coastguard Worker     mmio_bus: &Bus,
164*bb4ee6a4SAndroid Build Coastguard Worker     resources: &mut SystemAllocator,
165*bb4ee6a4SAndroid Build Coastguard Worker     vm: &mut impl Vm,
166*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>,
167*bb4ee6a4SAndroid Build Coastguard Worker     protection_type: ProtectionType,
168*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<
169*bb4ee6a4SAndroid Build Coastguard Worker     (
170*bb4ee6a4SAndroid Build Coastguard Worker         Vec<Arc<Mutex<dyn BusDevice>>>,
171*bb4ee6a4SAndroid Build Coastguard Worker         BTreeMap<u32, String>,
172*bb4ee6a4SAndroid Build Coastguard Worker         Vec<PlatformBusResources>,
173*bb4ee6a4SAndroid Build Coastguard Worker     ),
174*bb4ee6a4SAndroid Build Coastguard Worker     DeviceRegistrationError,
175*bb4ee6a4SAndroid Build Coastguard Worker > {
176*bb4ee6a4SAndroid Build Coastguard Worker     let mut platform_devices = Vec::new();
177*bb4ee6a4SAndroid Build Coastguard Worker     let mut pid_labels = BTreeMap::new();
178*bb4ee6a4SAndroid Build Coastguard Worker     let mut bus_dev_resources = vec![];
179*bb4ee6a4SAndroid Build Coastguard Worker 
180*bb4ee6a4SAndroid Build Coastguard Worker     // Allocate ranges that may need to be in the Platform MMIO region (MmioType::Platform).
181*bb4ee6a4SAndroid Build Coastguard Worker     for (mut device, jail) in devices.into_iter() {
182*bb4ee6a4SAndroid Build Coastguard Worker         let dt_symbol = device
183*bb4ee6a4SAndroid Build Coastguard Worker             .dt_symbol()
184*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or(DeviceRegistrationError::MissingDeviceTreeSymbol)?
185*bb4ee6a4SAndroid Build Coastguard Worker             .to_owned();
186*bb4ee6a4SAndroid Build Coastguard Worker         let mut device_resources = PlatformBusResources::new(dt_symbol);
187*bb4ee6a4SAndroid Build Coastguard Worker         let ranges = device
188*bb4ee6a4SAndroid Build Coastguard Worker             .allocate_regions(resources)
189*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(DeviceRegistrationError::AllocateIoResource)?;
190*bb4ee6a4SAndroid Build Coastguard Worker 
191*bb4ee6a4SAndroid Build Coastguard Worker         // If guest memory is private, don't wait for the first access to mmap the device.
192*bb4ee6a4SAndroid Build Coastguard Worker         if protection_type.isolates_memory() {
193*bb4ee6a4SAndroid Build Coastguard Worker             device.regions_mmap_early(vm);
194*bb4ee6a4SAndroid Build Coastguard Worker         }
195*bb4ee6a4SAndroid Build Coastguard Worker 
196*bb4ee6a4SAndroid Build Coastguard Worker         let mut keep_rds = device.keep_rds();
197*bb4ee6a4SAndroid Build Coastguard Worker         syslog::push_descriptors(&mut keep_rds);
198*bb4ee6a4SAndroid Build Coastguard Worker         cros_tracing::push_descriptors!(&mut keep_rds);
199*bb4ee6a4SAndroid Build Coastguard Worker         metrics::push_descriptors(&mut keep_rds);
200*bb4ee6a4SAndroid Build Coastguard Worker 
201*bb4ee6a4SAndroid Build Coastguard Worker         let irqs = device
202*bb4ee6a4SAndroid Build Coastguard Worker             .get_platform_irqs()
203*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(DeviceRegistrationError::AllocateIrqResource)?;
204*bb4ee6a4SAndroid Build Coastguard Worker         for irq in irqs.into_iter() {
205*bb4ee6a4SAndroid Build Coastguard Worker             let irq_num = resources
206*bb4ee6a4SAndroid Build Coastguard Worker                 .allocate_irq()
207*bb4ee6a4SAndroid Build Coastguard Worker                 .ok_or(DeviceRegistrationError::AllocateIrq)?;
208*bb4ee6a4SAndroid Build Coastguard Worker 
209*bb4ee6a4SAndroid Build Coastguard Worker             if device.irq_is_automask(&irq) {
210*bb4ee6a4SAndroid Build Coastguard Worker                 let irq_evt =
211*bb4ee6a4SAndroid Build Coastguard Worker                     devices::IrqLevelEvent::new().map_err(DeviceRegistrationError::EventCreate)?;
212*bb4ee6a4SAndroid Build Coastguard Worker                 irq_chip
213*bb4ee6a4SAndroid Build Coastguard Worker                     .register_level_irq_event(
214*bb4ee6a4SAndroid Build Coastguard Worker                         irq_num,
215*bb4ee6a4SAndroid Build Coastguard Worker                         &irq_evt,
216*bb4ee6a4SAndroid Build Coastguard Worker                         IrqEventSource::from_device(&device),
217*bb4ee6a4SAndroid Build Coastguard Worker                     )
218*bb4ee6a4SAndroid Build Coastguard Worker                     .map_err(DeviceRegistrationError::RegisterIrqfd)?;
219*bb4ee6a4SAndroid Build Coastguard Worker                 device
220*bb4ee6a4SAndroid Build Coastguard Worker                     .assign_level_platform_irq(&irq_evt, irq.index)
221*bb4ee6a4SAndroid Build Coastguard Worker                     .map_err(DeviceRegistrationError::SetupVfioPlatformIrq)?;
222*bb4ee6a4SAndroid Build Coastguard Worker                 keep_rds.extend(irq_evt.as_raw_descriptors());
223*bb4ee6a4SAndroid Build Coastguard Worker                 device_resources
224*bb4ee6a4SAndroid Build Coastguard Worker                     .irqs
225*bb4ee6a4SAndroid Build Coastguard Worker                     .push((irq_num, PlatformBusResources::IRQ_TRIGGER_LEVEL));
226*bb4ee6a4SAndroid Build Coastguard Worker             } else {
227*bb4ee6a4SAndroid Build Coastguard Worker                 let irq_evt =
228*bb4ee6a4SAndroid Build Coastguard Worker                     devices::IrqEdgeEvent::new().map_err(DeviceRegistrationError::EventCreate)?;
229*bb4ee6a4SAndroid Build Coastguard Worker                 irq_chip
230*bb4ee6a4SAndroid Build Coastguard Worker                     .register_edge_irq_event(
231*bb4ee6a4SAndroid Build Coastguard Worker                         irq_num,
232*bb4ee6a4SAndroid Build Coastguard Worker                         &irq_evt,
233*bb4ee6a4SAndroid Build Coastguard Worker                         IrqEventSource::from_device(&device),
234*bb4ee6a4SAndroid Build Coastguard Worker                     )
235*bb4ee6a4SAndroid Build Coastguard Worker                     .map_err(DeviceRegistrationError::RegisterIrqfd)?;
236*bb4ee6a4SAndroid Build Coastguard Worker                 device
237*bb4ee6a4SAndroid Build Coastguard Worker                     .assign_edge_platform_irq(&irq_evt, irq.index)
238*bb4ee6a4SAndroid Build Coastguard Worker                     .map_err(DeviceRegistrationError::SetupVfioPlatformIrq)?;
239*bb4ee6a4SAndroid Build Coastguard Worker                 keep_rds.extend(irq_evt.as_raw_descriptors());
240*bb4ee6a4SAndroid Build Coastguard Worker                 device_resources
241*bb4ee6a4SAndroid Build Coastguard Worker                     .irqs
242*bb4ee6a4SAndroid Build Coastguard Worker                     .push((irq_num, PlatformBusResources::IRQ_TRIGGER_EDGE));
243*bb4ee6a4SAndroid Build Coastguard Worker             }
244*bb4ee6a4SAndroid Build Coastguard Worker         }
245*bb4ee6a4SAndroid Build Coastguard Worker 
246*bb4ee6a4SAndroid Build Coastguard Worker         if let Some((iommu_type, id, vsids)) = device.iommu() {
247*bb4ee6a4SAndroid Build Coastguard Worker             // We currently only support one IOMMU per VFIO device.
248*bb4ee6a4SAndroid Build Coastguard Worker             device_resources
249*bb4ee6a4SAndroid Build Coastguard Worker                 .iommus
250*bb4ee6a4SAndroid Build Coastguard Worker                 .push((iommu_type, id, vsids.to_vec()));
251*bb4ee6a4SAndroid Build Coastguard Worker         }
252*bb4ee6a4SAndroid Build Coastguard Worker 
253*bb4ee6a4SAndroid Build Coastguard Worker         let arced_dev: Arc<Mutex<dyn BusDevice>> = if let Some(jail) = jail {
254*bb4ee6a4SAndroid Build Coastguard Worker             let proxy = ProxyDevice::new(
255*bb4ee6a4SAndroid Build Coastguard Worker                 device,
256*bb4ee6a4SAndroid Build Coastguard Worker                 jail,
257*bb4ee6a4SAndroid Build Coastguard Worker                 keep_rds,
258*bb4ee6a4SAndroid Build Coastguard Worker                 #[cfg(feature = "swap")]
259*bb4ee6a4SAndroid Build Coastguard Worker                 swap_controller,
260*bb4ee6a4SAndroid Build Coastguard Worker             )
261*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(DeviceRegistrationError::ProxyDeviceCreation)?;
262*bb4ee6a4SAndroid Build Coastguard Worker             pid_labels.insert(proxy.pid() as u32, proxy.debug_label());
263*bb4ee6a4SAndroid Build Coastguard Worker             Arc::new(Mutex::new(proxy))
264*bb4ee6a4SAndroid Build Coastguard Worker         } else {
265*bb4ee6a4SAndroid Build Coastguard Worker             device.on_sandboxed();
266*bb4ee6a4SAndroid Build Coastguard Worker             Arc::new(Mutex::new(device))
267*bb4ee6a4SAndroid Build Coastguard Worker         };
268*bb4ee6a4SAndroid Build Coastguard Worker         platform_devices.push(arced_dev.clone());
269*bb4ee6a4SAndroid Build Coastguard Worker         for range in &ranges {
270*bb4ee6a4SAndroid Build Coastguard Worker             mmio_bus
271*bb4ee6a4SAndroid Build Coastguard Worker                 .insert(arced_dev.clone(), range.0, range.1)
272*bb4ee6a4SAndroid Build Coastguard Worker                 .map_err(DeviceRegistrationError::MmioInsert)?;
273*bb4ee6a4SAndroid Build Coastguard Worker             device_resources.regions.push((range.0, range.1));
274*bb4ee6a4SAndroid Build Coastguard Worker         }
275*bb4ee6a4SAndroid Build Coastguard Worker         bus_dev_resources.push(device_resources);
276*bb4ee6a4SAndroid Build Coastguard Worker     }
277*bb4ee6a4SAndroid Build Coastguard Worker     Ok((platform_devices, pid_labels, bus_dev_resources))
278*bb4ee6a4SAndroid Build Coastguard Worker }
279