Skip to content

Commit e4efed3

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 a20df69 commit e4efed3

File tree

1 file changed

+48
-40
lines changed
  • src/vmm/src/devices/virtio/transport/pci

1 file changed

+48
-40
lines changed

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

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -740,67 +740,75 @@ impl PciDevice for VirtioPciDevice {
740740
offset: u8,
741741
data: &[u8],
742742
) -> Option<Arc<Barrier>> {
743-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
743+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
744+
let in_msix_config = reg_idx * 4 == self.msix_config_cap_offset;
745+
let in_pci_cfg = {
746+
let base = reg_idx * 4;
747+
let cap_start = self.cap_pci_cfg_info.offset;
748+
let cap_end =
749+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
750+
let write_start = base + u16::from(offset);
751+
let write_end = (base + u16::from(offset)) as usize + data.len();
752+
cap_start <= write_start && write_end <= cap_end
753+
};
754+
if in_bars {
744755
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
745756
#[allow(clippy::cast_possible_truncation)]
746757
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
747758
self.bars.write(bar_idx, offset, data);
748759
None
760+
} else if in_msix_config {
761+
self.msix_config
762+
.lock()
763+
.unwrap()
764+
.write_msg_ctl_register(offset, data);
765+
self.configuration
766+
.write_config_register(reg_idx, offset, data);
767+
None
768+
} else if in_pci_cfg {
769+
let offset = (reg_idx * 4 + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
770+
self.write_cap_pci_cfg(offset, data)
749771
} else {
750-
// Handle access to the header of the MsixCapability. The rest of the
751-
// capability is handled by the PciConfiguration.
752-
let base = reg_idx * 4;
753-
if base == self.msix_config_cap_offset {
754-
self.msix_config
755-
.lock()
756-
.unwrap()
757-
.write_msg_ctl_register(offset, data);
758-
}
759-
if base + u16::from(offset) >= self.cap_pci_cfg_info.offset
760-
&& (base + u16::from(offset)) as usize + data.len()
761-
<= self.cap_pci_cfg_info.offset as usize
762-
+ self.cap_pci_cfg_info.cap.bytes().len()
763-
{
764-
let offset = (base + u16::from(offset) - self.cap_pci_cfg_info.offset) as usize;
765-
self.write_cap_pci_cfg(offset, data)
766-
} else {
767-
self.configuration
768-
.write_config_register(reg_idx, offset, data);
769-
None
770-
}
772+
self.configuration
773+
.write_config_register(reg_idx, offset, data);
774+
None
771775
}
772776
}
773777

774778
fn read_config_register(&mut self, reg_idx: u16) -> u32 {
775-
if BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS) {
779+
let in_bars = BAR0_REG_IDX <= reg_idx && reg_idx < BAR0_REG_IDX + u16::from(NUM_BAR_REGS);
780+
let in_pci_cfg = {
781+
let base = reg_idx * 4;
782+
let cap_start = self.cap_pci_cfg_info.offset;
783+
let cap_end =
784+
self.cap_pci_cfg_info.offset as usize + self.cap_pci_cfg_info.cap.bytes().len();
785+
let write_start = base;
786+
let write_end = (base + 4) as usize;
787+
cap_start <= write_start && write_end <= cap_end
788+
};
789+
790+
if in_bars {
776791
// reg_idx is in [BAR0_REG_IDX, BAR0_REG_IDX+NUM_BAR_REGS), so the difference is 0..5.
777792
#[allow(clippy::cast_possible_truncation)]
778793
let bar_idx = (reg_idx - BAR0_REG_IDX) as u8;
779794
let mut value: u32 = 0;
780795
self.bars.read(bar_idx, 0, value.as_mut_bytes());
781796
value
782-
} else {
797+
} else if in_pci_cfg {
783798
// Handle the special case where the capability VIRTIO_PCI_CAP_PCI_CFG
784799
// is accessed. This capability has a special meaning as it allows the
785800
// guest to access other capabilities without mapping the PCI BAR.
786-
let base = reg_idx as usize * 4;
787-
if base >= self.cap_pci_cfg_info.offset as usize
788-
&& base + 4
789-
<= self.cap_pci_cfg_info.offset as usize
790-
+ self.cap_pci_cfg_info.cap.bytes().len()
791-
{
792-
let offset = base - 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)
798-
} else {
799-
0
800-
}
801+
let offset = (reg_idx * 4 - self.cap_pci_cfg_info.offset) as usize;
802+
let mut data = [0u8; 4];
803+
let len = u32::from(self.cap_pci_cfg_info.cap.cap.length) as usize;
804+
if len <= 4 {
805+
self.read_cap_pci_cfg(offset, &mut data[..len]);
806+
u32::from_le_bytes(data)
801807
} else {
802-
self.configuration.read_reg(reg_idx)
808+
0
803809
}
810+
} else {
811+
self.configuration.read_reg(reg_idx)
804812
}
805813
}
806814

0 commit comments

Comments
 (0)