Skip to content

Commit

Permalink
PCI: disable I/O and memory decode during BAR sizing
Browse files Browse the repository at this point in the history
Reprogramming the BAR address to an all-1s value when attempting to
decipher which bits are writable can result in the PCI device actually
intercepting memory or I/O accesses to the resulting address. To avoid
this, disable the I/O and memory bits in the control register during the
BAR sizing process, as recommended by the PCI specification.

Fixes GitHub issue #176.
  • Loading branch information
danielverkamp committed Mar 4, 2025
1 parent cf692ed commit 22e4746
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/transport/pci/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ impl<C: ConfigurationAccess> PciRoot<C> {
device_function: DeviceFunction,
bar_index: u8,
) -> Result<BarInfo, PciError> {
// Disable address decoding while sizing the BAR.
let (_status, command_orig) = self.get_status_command(device_function);
let command_disable_decode = command_orig & !(Command::IO_SPACE | Command::MEMORY_SPACE);
if command_disable_decode != command_orig {
self.set_command(device_function, command_disable_decode);
}

let bar_orig = self
.configuration_access
.read_word(device_function, BAR0_OFFSET + 4 * bar_index);
Expand Down Expand Up @@ -265,6 +272,10 @@ impl<C: ConfigurationAccess> PciRoot<C> {
bar_orig,
);

if command_disable_decode != command_orig {
self.set_command(device_function, command_orig);
}

if bar_orig & 0x00000001 == 0x00000001 {
// I/O space
let address = bar_orig & 0xfffffffc;
Expand Down

0 comments on commit 22e4746

Please sign in to comment.