I would like to add support for multiple PCI domains to libvirt.  My main 
motivation is bug #360 [1], though it would also make pSeries machine 
configurations more intuitive (they can have multiple pci-root controllers).

Currently, every PCI controller is in PCI domain 0, and the controller's index 
number equals its bus ID.  To support multiple domains, my plan is to map 
domain:bus ID pairs to/from controller index numbers as follows:

  * A root controller with index N establishes domain N, and provides bus 0 in 
that domain.
  * A non-root controller with index N, and plugged in to a PCI controller in 
domain D, provides bus N in domain D.

Furthermore, each non-root controller must have a higher index number than the 
controller it plugs in to, so the controller with index 0 is guaranteed to be a 
root controller.  This means that in the common case of only a single domain, 
the behavior would be the same as it is now (domain == 0, controller index == 
bus ID).

Example domain:bus pairs:

  * 0000:00 would identify the bus provided by the root controller with index 0 
(as it does now).
  * 000f:1b would identify the bus provided by the non-root controller with 
index 27 (0x1b), and that controller is plugged into domain 15 (0xf).

Implications of this scheme:

  * Bus IDs never match any domain IDs (exception: bus 0 in domain 0).
  * Bus IDs never appear in more than one domain (exception: bus 0 appears in 
every domain).
  * There can be gaps between domain IDs.
  * There can be gaps between bus IDs in a domain.
  * Each bus's ID is greater than its domain's ID (except for bus 0 in each 
domain).

The gaps between IDs means that the current PCI address set buses array [2] 
would have to be replaced with a different data structure.  I would probably 
use nested GHashTables, where the first dimension is the domain and the second 
dimension is the bus.

The default names generated for QEMU would continue to be "pci.N" (or "pcie.N") 
where N is the PCI controller's index number.

The PCI specification says that bus IDs are 8 bits, but libvirt bus IDs are 
independent of the bus IDs seen by the guest so this limitation doesn't need to 
exist in libvirt configs.  As long as each domain has no more than 256 buses, 
it should be possible to support arbitrarily large bus IDs.  (I doubt this will 
ever be an issue in practice, but I thought it would be worth mentioning.)

Thoughts?

Thanks,
Richard

[1] https://gitlab.com/libvirt/libvirt/-/issues/360
[2] 
https://gitlab.com/libvirt/libvirt/-/blob/v8.7.0/src/conf/domain_addr.h#L126-127

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to