MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / bind_device_to_vfio

Function bind_device_to_vfio

crates/openshell-vfio/src/bind.rs:141–201  ·  view source on GitHub ↗

Bind a single PCI device to `vfio-pci`. Skips devices already bound.

(sysfs: &SysfsRoot, bdf: &str)

Source from the content-addressed store, hash-verified

139
140/// Bind a single PCI device to `vfio-pci`. Skips devices already bound.
141pub(crate) fn bind_device_to_vfio(sysfs: &SysfsRoot, bdf: &str) -> Result<bool, VfioError> {
142 if let Some(drv) = current_driver_name(sysfs, bdf) {
143 if drv == "vfio-pci" {
144 return Ok(false);
145 }
146 let unbind_path = sysfs.pci_device_ref(bdf).driver_unbind_path();
147 write_sysfs(&unbind_path, bdf).map_err(|e| VfioError::BindFailed {
148 bdf: bdf.to_string(),
149 reason: format!("unbind from {drv}: {e}"),
150 })?;
151 tracing::info!(bdf, driver = %drv, "unbound device from current driver");
152 }
153
154 register_vfio_new_id(sysfs, bdf);
155
156 let override_path = sysfs.pci_device_ref(bdf).driver_override_path();
157 if let Err(e) = write_sysfs(&override_path, "vfio-pci") {
158 deregister_vfio_new_id(sysfs, bdf);
159 return Err(VfioError::BindFailed {
160 bdf: bdf.to_string(),
161 reason: format!("driver_override: {e}"),
162 });
163 }
164
165 if let Err(e) = write_sysfs(&sysfs.drivers_probe(), bdf) {
166 deregister_vfio_new_id(sysfs, bdf);
167 cleanup_partial_bind(sysfs, bdf);
168 return Err(VfioError::BindFailed {
169 bdf: bdf.to_string(),
170 reason: format!("drivers_probe: {e}"),
171 });
172 }
173
174 if matches!(current_driver_name(sysfs, bdf).as_deref(), Some("vfio-pci")) {
175 return Ok(true);
176 }
177
178 // The kernel processes drivers_probe asynchronously on some systems; poll
179 // briefly to let the driver attach before declaring failure.
180 for _ in 0..VFIO_BIND_MAX_POLL_ATTEMPTS {
181 std::thread::sleep(VFIO_BIND_POLL_INTERVAL);
182 if matches!(current_driver_name(sysfs, bdf).as_deref(), Some("vfio-pci")) {
183 tracing::debug!(bdf, "vfio-pci binding confirmed after polling");
184 return Ok(true);
185 }
186 }
187
188 deregister_vfio_new_id(sysfs, bdf);
189 cleanup_partial_bind(sysfs, bdf);
190 Err(VfioError::BindFailed {
191 bdf: bdf.to_string(),
192 reason: format!(
193 "after drivers_probe with {}ms polling, driver is {:?} instead of vfio-pci",
194 u64::from(VFIO_BIND_MAX_POLL_ATTEMPTS)
195 * u64::try_from(VFIO_BIND_POLL_INTERVAL.as_millis()).unwrap_or(u64::MAX),
196 current_driver_name(sysfs, bdf)
197 .as_deref()
198 .unwrap_or("<none>")

Calls 9

current_driver_nameFunction · 0.85
write_sysfsFunction · 0.85
register_vfio_new_idFunction · 0.85
deregister_vfio_new_idFunction · 0.85
cleanup_partial_bindFunction · 0.85
driver_unbind_pathMethod · 0.80
pci_device_refMethod · 0.80
driver_override_pathMethod · 0.80
drivers_probeMethod · 0.80