Skip to content

Conversation

@seijikun
Copy link
Contributor

@seijikun seijikun commented Nov 21, 2025

  • Refactored return type from standard BTreeSet<PciIoAddress> to custom PciTree struct with tree topology information
  • Removed special FullPciIoAddress type, since segment number is fixed per PciRoot
  • During enumeration, skip branches we have already seen
  • During enumeration, collect tree topology information (which child bus linked from where)
  • Add complicated pci structure in integration test vm
  • Print child busses for every device entry in integration test

Previously, we iterated over the bus range from the ACPI descriptor. I changed this in my last MR to only visit the first in the range. I changed this back to iterate over all of the entries, but skip the ones we have seen previously - now that that's easily possible. I decided that better safe than sorry is the best way. The iteration over all child busses already saved our ass once - let's not willingly take this safety net away. Sorry for the back and forth here.

The plan for device paths is now to add something like: PciTree::device_path(&self, addr: PciIoAddress) -> PoolDevicePath.

Checklist

  • Sensible git history (for example, squash "typo" or "fix" commits). See the Rewriting History guide for help.
  • Update the changelog (if necessary)

Copy link
Member

@phip1611 phip1611 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! My main concern is my lack of domain knowledge of PCIe. Please elaborate a little more to help me understand what's going on :)

// test is more interesting.
cmd.args([
"-device",
"ioh3420,id=root_port1,bus=pcie.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not that familiar with PCI. Could you please elaborate a little?

  • why adding a root port? Is this equivalent to adding a new PCI bus?
  • what is x3130-upstream and why are you using it here?
  • what is x3130-downstream and why are you using it here?
  • virtio-scsi-pci is just a random PCI device without serving a functionality here except for appearing on the PCIe bus?
  • why are you specifying chassis=9|10?

Copy link
Contributor Author

@seijikun seijikun Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much of this is qemu specific syntax:
ioh3420 reserves a port in pcie.0 - the pcie root port, also called pcie root complex. I imagine this like soldering a PCIe socket on your mainboard, where you can plug stuff in.
Into this socket, we then plug a x3130-upstream. That's a PCIe switch.
x3130-downstream is the other side of the swich, where you can plug child devices in.
I have no idea what chassis is, the way I understood it, it can be any number as long as they are unique. All bridges/switches have this obligatory parameter.
The scsi devices are just for testing, like you said.

Difference PCIe switches and PCIe bridges:
Both allocate a new subordinate bus. Both allow connecting devices to them, which they "pass through" to the port where they are connected upstream. The key difference is, that for you to pass 2 lanes through a bridge, it needs to be connected with 2 lanes to its upstream. Whereas PCIe switches can do switching. They can tunnel y downstream lanes through x upstream lanes - sacrificing speed if y > x (like with network switches). They are rather seldom, which is why I wanted to test it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image https://blogs.oracle.com/linux/a-study-of-the-linux-kernel-pci-subsystem-with-qemu

"PCI Device: [{bus}, {dev}, {fun}]: vendor={vendor_id:04X}, device={device_id:04X}, class={class_code:02X}, subclass={subclass_code:02X}"
"PCI Device: [{bus:02x}, {dev:02x}, {fun:02x}]: vendor={vendor_id:04X}, device={device_id:04X}, class={class_code:02X}, subclass={subclass_code:02X}"
);
for child_bus in pci_tree.iter_subsequent_busses_for(addr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of just iterating, would it make sense to explictely check for the expected PCIe devices?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bus numbers are dynamically allocated and thus might vary.
But I've done something like you suggest in the follow-up MR here, based on device paths: 582714a

…ation

- Refactored return type from standard BTreeSet to custom PciTree struct
- Removed special FullPciIoAddress type, since segment number is PciRoot dependent
- During enumeration, skip branches we have already seen
- During enumeration, collect tree topology information (which child bus linked from where)
- Add complicated pci structure in integration test vm
- Print child busses for every device entry in integration test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants