Skip to content

Commit f492283

Browse files
committed
pci: refactor: make read/write_config_register a bit easier to read
Move the comparisons into boolean vars to make dispatch code a bit more readable. Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
1 parent 1dbff80 commit f492283

1 file changed

Lines changed: 48 additions & 40 deletions

File tree

  • src/vmm/src/devices/virtio/transport/pci

src/vmm/src/devices/virtio/transport/pci/device.rs

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -731,67 +731,75 @@ impl PciDevice for VirtioPciDevice {
731731
offset: u8,
732732
data: &[u8],
733733
) -> Option<Arc<Barrier>> {
734-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
734+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
735+
let in_msix_config = reg_idx * 4 == self.msix_config_cap_offset;
736+
let in_pci_cfg = {
737+
let base = reg_idx * 4;
738+
let cap_start = self.cap_pci_cfg_info.offset;
739+
let cap_end =
740+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
741+
let write_start = base + u16::from(offset);
742+
let write_end = (base + u16::from(offset)) as usize + data.len();
743+
cap_start <= write_start && write_end <= cap_end
744+
};
745+
if in_bars {
735746
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
736747
#[allow(clippy::cast_possible_truncation)]
737748
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
738749
self.bars.write(bar_idx, offset, data);
739750
None
751+
} else if in_msix_config {
752+
self.msix_config
753+
.lock()
754+
.unwrap()
755+
.write_msg_ctl_register(offset, data);
756+
self.configuration
757+
.write_config_register(reg_idx, offset, data);
758+
None
759+
} else if in_pci_cfg {
760+
let offset = (reg_idx * 4 + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
761+
self.write_cap_pci_cfg(offset, data)
740762
} else {
741-
// Handle access to the header of the MsixCapability. The rest of the
742-
// capability is handled by the PciConfiguration.
743-
let base = reg_idx * 4;
744-
if base == self.msix_config_cap_offset {
745-
self.msix_config
746-
.lock()
747-
.unwrap()
748-
.write_msg_ctl_register(offset, data);
749-
}
750-
if base + u16::from(offset) >= self.cap_pci_cfg_info.offset
751-
&& (base + u16::from(offset)) as usize + data.len()
752-
<= self.cap_pci_cfg_info.offset as usize
753-
+ self.cap_pci_cfg_info.cap.bytes().len()
754-
{
755-
let offset = (base + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
756-
self.write_cap_pci_cfg(offset, data)
757-
} else {
758-
self.configuration
759-
.write_config_register(reg_idx, offset, data);
760-
None
761-
}
763+
self.configuration
764+
.write_config_register(reg_idx, offset, data);
765+
None
762766
}
763767
}
764768

765769
fn read_config_register(&mut self, reg_idx: u16) -> u32 {
766-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
770+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
771+
let in_pci_cfg = {
772+
let base = reg_idx * 4;
773+
let cap_start = self.cap_pci_cfg_info.offset;
774+
let cap_end =
775+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
776+
let write_start = base;
777+
let write_end = (base + 4) as usize;
778+
cap_start <= write_start && write_end <= cap_end
779+
};
780+
781+
if in_bars {
767782
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
768783
#[allow(clippy::cast_possible_truncation)]
769784
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
770785
let mut value: u32 = 0;
771786
self.bars.read(bar_idx, 0, value.as_mut_bytes());
772787
value
773-
} else {
788+
} else if in_pci_cfg {
774789
// Handle the special case where the capability VIRTIO_PCI_CAP_PCI_CFG
775790
// is accessed. This capability has a special meaning as it allows the
776791
// guest to access other capabilities without mapping the PCI BAR.
777-
let base = reg_idx as usize * 4;
778-
if base >= self.cap_pci_cfg_info.offset as usize
779-
&& base + 4
780-
<= self.cap_pci_cfg_info.offset as usize
781-
+ self.cap_pci_cfg_info.cap.bytes().len()
782-
{
783-
let offset = base - self.cap_pci_cfg_info.offset as usize;
784-
let mut data = [0u8; 4];
785-
let len = u32::from(self.cap_pci_cfg_info.cap.cap.length) as usize;
786-
if len <= 4 {
787-
self.read_cap_pci_cfg(offset, &mut data[..len]);
788-
u32::from_le_bytes(data)
789-
} else {
790-
0
791-
}
792+
let offset = (reg_idx * 4 - self.cap_pci_cfg_info.offset) as usize;
793+
let mut data = [0u8; 4];
794+
let len = u32::from(self.cap_pci_cfg_info.cap.cap.length) as usize;
795+
if len <= 4 {
796+
self.read_cap_pci_cfg(offset, &mut data[..len]);
797+
u32::from_le_bytes(data)
792798
} else {
793-
self.configuration.read_reg(reg_idx)
799+
0
794800
}
801+
} else {
802+
self.configuration.read_reg(reg_idx)
795803
}
796804
}
797805

0 commit comments

Comments
 (0)