Eduardo Habkost <ehabkost@xxxxxxxxxx> writes: > This adds a new command to QMP: query-device-slots. It will allow > management software to query possible slots where devices can be > plugged. > > This implementation of the command will return: > > * Multiple PCI slots per bus, in the case of PCI buses; > * One slot per bus for the other buses (that don't > implement slot enumeration yet); > * One slot for each entry from query-hotpluggable-cpus. > > Git tree > -------- > > This patch needs the previous query-machines series I am working > on. The full tree can be found on the git tree at: > > git://github.com/ehabkost/qemu-hacks.git work/query-machines-bus-info > > Example output > -------------- > > The following output was returned by QEMU when running it as: > > $ qemu-system-x86_64 -machine q35 \ > -readconfig docs/q35-chipset.cfg \ > -smp 4,maxcpus=8,sockets=2,cores=2,threads=2 > > { > "return": [ > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "i2c" Missing: bus "i2c-bus" device address, property name "address", value 0..255. > }, > "type": "non-slot", I guess "non-slot" means "props" is incomplete, but the rest should be okay. > "accepted-device-types": [ > "i2c-slave" > ] > }, > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "ide.4" Bus "IDE" device address property "unit", value 0 (because this is SATA, for PATA it would be 0..1). > }, > "type": "non-slot", > "accepted-device-types": [ > "ide-device" > ] > }, [...] > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "main-system-bus" > }, > "type": "non-slot", > "accepted-device-types": [ > "sys-bus-device" > ] > }, Can't give guidance on this one, I'm afraid. > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "isa.0" > }, > "type": "non-slot", > "accepted-device-types": [ > "isa-device" > ] > }, Bus "ISA" is iffy, too. > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "pcie.0", > "device-number": 0 Really? "device_add e1000e,help" shows now property "device-number". Oh, I see, you're adding it in this patch, along with "function". > }, > "type": "pci", > "accepted-device-types": [ > "legacy-pci-device", > "pci-express-device" > ] > }, > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "pcie.0", > "device-number": 1 > }, > "type": "pci", > "accepted-device-types": [ > "legacy-pci-device", > "pci-express-device" > ] > }, [...] > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "pcie.0", > "device-number": 31 > }, > "type": "pci", > "accepted-device-types": [ > "legacy-pci-device", > "pci-express-device" > ] > }, Design question: do we need to describe the bus with 32 separate objects, or would a single object do? The objects only differ in the value of props.device-number... For a hypothetical bus with uint32_t device addresses, separate objects would be impossible. So we probably need to describe slot sets, anyway. > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-pcie-port-1", > "device-number": 0 > }, > "type": "pci", > "accepted-device-types": [ > "pci-express-device" > ] > }, > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-pcie-port-2", > "device-number": 0 > }, > "type": "pci", > "accepted-device-types": [ > "pci-express-device" > ] > }, > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-pcie-port-3", > "device-number": 0 > }, > "type": "pci", > "accepted-device-types": [ > "pci-express-device" > ] > }, > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-pcie-port-4", > "device-number": 0 > }, > "type": "pci", > "accepted-device-types": [ > "pci-express-device" > ] > }, > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "ich9-pci-bridge", > "device-number": 0 > }, > "type": "pci", > "accepted-device-types": [ > "legacy-pci-device" > ] > }, [...] > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "ich9-pci-bridge", > "device-number": 31 > }, > "type": "pci", > "accepted-device-types": [ > "legacy-pci-device" > ] > }, Likewise. > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-ehci-1.0" > }, > "type": "non-slot", > "accepted-device-types": [ > "usb-device" > ] > }, Okay, more bad news: bus "usb-bus" device address property is "port", value is a sequence of port numbers separated by '.'. The reason is "convenience" A real USB host controller has a fixed number of ports, numbered 1..N. This one has six. A real USB hub device plugs into a port and in turn provides a fixed number of ports, numbered 1..N. The USB hub device we model provides eight. An obvious way to model this would be to have the host controller provide a bus with a fixed number of slots, and the usb-hub provide a separate bus with eight. This is how we do PCI bridges. But it's not how we do USB hubs. Host software can treat the tree formed by USB host controller, hubs and other devices as a single bus, and that's how we model it. A "port" value that is a single number addresses that port on the host controller. A value containing '.' addresses something behind a hub. The leftmost number addresses a host controller port. A hub must be plugged in there. Recurse for the rest of the port string. If you device_add an USB device without specifying a port, it picks an unused one. When it has to pick the last port, it tries to add a usb-hub device there, which provides eight ports, then picks a port for your device. If adding the usb-hub succeeds, it'll get the new hub's port 1. Else, it gets the last port. There's a hard-coded limit of five on the depth of the hub chain. So, if you keep adding USB devices to the bus provided by ich9-ehci, the first five go into ports "1", ..., "5", the sixth goes into "6.1" (with usb-hub in port "6"), and so forth, until the 41st goes into "6.8.8.8.8.8". Adding hubs manually permits more devices. If you do specify "port", then that port must already exist. I think the sanest way to represent the existing ports is enumerating them, like this: { "available": true, "hotpluggable": true, "props": { "bus": "ich9-ehci-1.0", "port": "1" }, "type": "usb", "accepted-device-types": [ "usb-device" ] }, [...] { "available": true, "hotpluggable": true, "props": { "bus": "ich9-ehci-1.0", "port": "6" }, "type": "usb", "accepted-device-types": [ "usb-device" ] }, Plugging usb-hub into a port with port: "P" then flips that port's "available" to false, and adds eight new ports with "port": "P.1", ... "P.8". So, plugging a device can not only add buses provided by the device, but also, and less obviously, add slots to the bus it plugs into! Likewise for unplug. Perhaps we should emit events when slots come and go. > { > "available": true, > "hotpluggable": true, > "props": { > "bus": "ich9-ehci-2.0" > }, > "type": "non-slot", > "accepted-device-types": [ > "usb-device" > ] > }, > { > "available": false, > "hotpluggable": false, > "props": { > "bus": "ich9-hda-audio.0" Bus "HDA" device address property is "cad", value 0..14. > }, > "type": "non-slot", > "accepted-device-types": [ > "hda-codec" > ] > }, > { > "available": true, > "hotpluggable": true, > "props": { > "socket-id": 1, > "core-id": 1, > "thread-id": 1 > }, > "type": "cpu", > "accepted-device-types": [ > "qemu64-x86_64-cpu" > ] > }, You know CPUs better than me. [More of them...] > ] > } There's still more... Bus "SCSI" device address property is "scsi-id", value 0..N, where N depends on the SCSI HBA. Bus "virtio-serial-bus" device address property is "nr", value 0..N, where N is configurable, currenrly up to 511. ccid-bus device address property is "slot", value 0..N, where N depends on the device providing the bus (I think). Buses not yet covered by docs/qdev-device-use.txt: "floppy-bus", "apple-desktop-bus", "IndustryPack", "aux-bus", "spapr-vio-bus", "virtual-css-bus", "s390-sclp-events-bus", "s390-pcibus", "sd-bus", "SSI", "virtio-bus", "xen-sysbus". Grep for ".parent = TYPE_BUS". To find all buses in a certain build, use: { "execute": "qom-list-types", "arguments": { "implements": "bus" } } [No code review, yet] -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list