Skip to content

Commit b9deda6

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 2295ebd commit b9deda6

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
@@ -736,67 +736,75 @@ impl PciDevice for VirtioPciDevice {
736736
offset: u8,
737737
data: &[u8],
738738
) -> Option<Arc<Barrier>> {
739-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
739+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
740+
let in_msix_config = reg_idx * 4 == self.msix_config_cap_offset;
741+
let in_pci_cfg = {
742+
let base = reg_idx * 4;
743+
let cap_start = self.cap_pci_cfg_info.offset;
744+
let cap_end =
745+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
746+
let write_start = base + u16::from(offset);
747+
let write_end = (base + u16::from(offset)) as usize + data.len();
748+
cap_start <= write_start && write_end <= cap_end
749+
};
750+
if in_bars {
740751
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
741752
#[allow(clippy::cast_possible_truncation)]
742753
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
743754
self.bars.write(bar_idx, offset, data);
744755
None
756+
} else if in_msix_config {
757+
self.msix_config
758+
.lock()
759+
.unwrap()
760+
.write_msg_ctl_register(offset, data);
761+
self.configuration
762+
.write_config_register(reg_idx, offset, data);
763+
None
764+
} else if in_pci_cfg {
765+
let offset = (reg_idx * 4 + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
766+
self.write_cap_pci_cfg(offset, data)
745767
} else {
746-
// Handle access to the header of the MsixCapability. The rest of the
747-
// capability is handled by the PciConfiguration.
748-
let base = reg_idx * 4;
749-
if base == self.msix_config_cap_offset {
750-
self.msix_config
751-
.lock()
752-
.unwrap()
753-
.write_msg_ctl_register(offset, data);
754-
}
755-
if base + u16::from(offset) >= self.cap_pci_cfg_info.offset
756-
&& (base + u16::from(offset)) as usize + data.len()
757-
<= self.cap_pci_cfg_info.offset as usize
758-
+ self.cap_pci_cfg_info.cap.bytes().len()
759-
{
760-
let offset = (base + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
761-
self.write_cap_pci_cfg(offset, data)
762-
} else {
763-
self.configuration
764-
.write_config_register(reg_idx, offset, data);
765-
None
766-
}
768+
self.configuration
769+
.write_config_register(reg_idx, offset, data);
770+
None
767771
}
768772
}
769773

770774
fn read_config_register(&mut self, reg_idx: u16) -> u32 {
771-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
775+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
776+
let in_pci_cfg = {
777+
let base = reg_idx * 4;
778+
let cap_start = self.cap_pci_cfg_info.offset;
779+
let cap_end =
780+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
781+
let write_start = base;
782+
let write_end = (base + 4) as usize;
783+
cap_start <= write_start && write_end <= cap_end
784+
};
785+
786+
if in_bars {
772787
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
773788
#[allow(clippy::cast_possible_truncation)]
774789
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
775790
let mut value: u32 = 0;
776791
self.bars.read(bar_idx, 0, value.as_mut_bytes());
777792
value
778-
} else {
793+
} else if in_pci_cfg {
779794
// Handle the special case where the capability VIRTIO_PCI_CAP_PCI_CFG
780795
// is accessed. This capability has a special meaning as it allows the
781796
// guest to access other capabilities without mapping the PCI BAR.
782-
let base = reg_idx as usize * 4;
783-
if base >= self.cap_pci_cfg_info.offset as usize
784-
&& base + 4
785-
<= self.cap_pci_cfg_info.offset as usize
786-
+ self.cap_pci_cfg_info.cap.bytes().len()
787-
{
788-
let offset = base - self.cap_pci_cfg_info.offset as usize;
789-
let mut data = [0u8; 4];
790-
let len = u32::from(self.cap_pci_cfg_info.cap.cap.length) as usize;
791-
if len <= 4 {
792-
self.read_cap_pci_cfg(offset, &mut data[..len]);
793-
u32::from_le_bytes(data)
794-
} else {
795-
0
796-
}
797+
let offset = (reg_idx * 4 - self.cap_pci_cfg_info.offset) as usize;
798+
let mut data = [0u8; 4];
799+
let len = u32::from(self.cap_pci_cfg_info.cap.cap.length) as usize;
800+
if len <= 4 {
801+
self.read_cap_pci_cfg(offset, &mut data[..len]);
802+
u32::from_le_bytes(data)
797803
} else {
798-
self.configuration.read_reg(reg_idx)
804+
0
799805
}
806+
} else {
807+
self.configuration.read_reg(reg_idx)
800808
}
801809
}
802810

0 commit comments

Comments
 (0)