MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / write_config_register

Method write_config_register

pci/src/vfio.rs:1277–1351  ·  view source on GitHub ↗
(
        &mut self,
        reg_idx: usize,
        offset: u64,
        data: &[u8],
    )

Source from the content-addressed store, hash-verified

1275 }
1276
1277 pub(crate) fn write_config_register(
1278 &mut self,
1279 reg_idx: usize,
1280 offset: u64,
1281 data: &[u8],
1282 ) -> (Vec<BarReprogrammingParams>, Option<Arc<Barrier>>) {
1283 // When the guest wants to write to a BAR, we trap it into
1284 // our local configuration space. We're not reprogramming
1285 // VFIO device.
1286 if (PCI_CONFIG_BAR0_INDEX..PCI_CONFIG_BAR0_INDEX + BAR_NUMS).contains(&reg_idx)
1287 || reg_idx == PCI_ROM_EXP_BAR_INDEX
1288 {
1289 // We keep our local cache updated with the BARs.
1290 // We'll read it back from there when the guest is asking
1291 // for BARs (see read_config_register()).
1292 return (
1293 self.configuration
1294 .write_config_register(reg_idx, offset, data),
1295 None,
1296 );
1297 }
1298
1299 let reg = (reg_idx * PCI_CONFIG_REGISTER_SIZE) as u64;
1300
1301 // If the MSI or MSI-X capabilities are accessed, we need to
1302 // update our local cache accordingly.
1303 // Depending on how the capabilities are modified, this could
1304 // trigger a VFIO MSI or MSI-X toggle.
1305 if let Some((cap_id, cap_base)) = self.interrupt.accessed(reg) {
1306 let cap_offset: u64 = reg - cap_base + offset;
1307 match cap_id {
1308 PciCapabilityId::MessageSignalledInterrupts => {
1309 if let Err(e) = self.update_msi_capabilities(cap_offset, data) {
1310 error!("Could not update MSI capabilities: {e}");
1311 }
1312 }
1313 PciCapabilityId::MsiX => {
1314 if let Err(e) = self.update_msix_capabilities(cap_offset, data) {
1315 error!("Could not update MSI-X capabilities: {e}");
1316 }
1317 }
1318 _ => {}
1319 }
1320 }
1321
1322 // Make sure to write to the device's PCI config space after MSI/MSI-X
1323 // interrupts have been enabled/disabled. In case of MSI, when the
1324 // interrupts are enabled through VFIO (using VFIO_DEVICE_SET_IRQS),
1325 // the MSI Enable bit in the MSI capability structure found in the PCI
1326 // config space is disabled by default. That's why when the guest is
1327 // enabling this bit, we first need to enable the MSI interrupts with
1328 // VFIO through VFIO_DEVICE_SET_IRQS ioctl, and only after we can write
1329 // to the device region to update the MSI Enable bit.
1330 self.vfio_wrapper.write_config((reg + offset) as u32, data);
1331
1332 // Return pending BAR repgrogramming if MSE bit is set
1333 let mut ret_param = self.configuration.pending_bar_reprogram();
1334 if !ret_param.is_empty() {

Callers

nothing calls this directly

Calls 10

newFunction · 0.85
containsMethod · 0.80
accessedMethod · 0.80
pending_bar_reprogramMethod · 0.80
write_configMethod · 0.45
is_emptyMethod · 0.45
read_config_registerMethod · 0.45

Tested by

no test coverage detected