qemu/qmp: add vfio mediated device support

In addition to normal VFIO device, this patch adds VFIO mediated device
as a supplement to do hot plug on PCI(E) bridges.

Signed-off-by: Zhao Xinda <xinda.zhao@intel.com>
This commit is contained in:
Zhao Xinda 2018-08-10 12:43:22 +08:00
parent 79e74d936b
commit fcaf61dcb1
2 changed files with 42 additions and 0 deletions

View File

@ -837,6 +837,24 @@ func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus
return q.executeCommand(ctx, "device_add", args, nil)
}
// ExecutePCIVFIOMediatedDeviceAdd adds a VFIO mediated device to a QEMU instance using the device_add command.
// This function can be used to hot plug VFIO mediated devices on PCI(E) bridges, unlike
// ExecuteVFIODeviceAdd this function receives the bus and the device address on its parent bus.
// bus is optional. devID is the id of the device to add. Must be valid QMP identifier. sysfsdev is the VFIO
// mediated device.
func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus string) error {
args := map[string]interface{}{
"id": devID,
"driver": "vfio-pci",
"sysfsdev": sysfsdev,
"addr": addr,
}
if bus != "" {
args["bus"] = bus
}
return q.executeCommand(ctx, "device_add", args, nil)
}
// ExecuteCPUDeviceAdd adds a CPU to a QEMU instance using the device_add command.
// driver is the CPU model, cpuID must be a unique ID to identify the CPU, socketID is the socket number within
// node/board the CPU belongs to, coreID is the core number within socket the CPU belongs to, threadID is the

View File

@ -892,6 +892,30 @@ func TestQMPPCIDeviceAdd(t *testing.T) {
<-disconnectedCh
}
// Checks that PCI VFIO mediated devices are correctly added using device_add.
//
// We start a QMPLoop, send the device_add command and stop the loop.
//
// The device_add command should be correctly sent and the QMP loop should
// exit gracefully.
func TestQMPPCIVFIOMediatedDeviceAdd(t *testing.T) {
connectedCh := make(chan *QMPVersion)
disconnectedCh := make(chan struct{})
buf := newQMPTestCommandBuffer(t)
buf.AddCommand("device_add", nil, "return", nil)
cfg := QMPConfig{Logger: qmpTestLogger{}}
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
checkVersion(t, connectedCh)
sysfsDev := "/sys/bus/pci/devices/0000:00:02.0/a297db4a-f4c2-11e6-90f6-d3b88d6c9525"
devID := fmt.Sprintf("device_%s", volumeUUID)
err := q.ExecutePCIVFIOMediatedDeviceAdd(context.Background(), devID, sysfsDev, "0x1", "")
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
q.Shutdown()
<-disconnectedCh
}
// Checks that CPU are correctly added using device_add
func TestQMPCPUDeviceAdd(t *testing.T) {
connectedCh := make(chan *QMPVersion)