virtcontainers: vfio: add support for hot plugging VFIO devices

With this patch VFIO devices are hot plugged in the VM, that means
no more cold plug in kata containers.

fixes #85

Signed-off-by: Julio Montes <julio.montes@intel.com>
This commit is contained in:
Julio Montes 2018-03-20 12:21:46 -06:00
parent 184662416d
commit 47edcb3fec
2 changed files with 54 additions and 7 deletions

View File

@ -132,7 +132,13 @@ func (device *VFIODevice) attach(h hypervisor, c *Container) error {
device.BDF = deviceBDF
if err := h.addDevice(*device, vfioDev); err != nil {
randBytes, err := generateRandomBytes(8)
if err != nil {
return err
}
device.DeviceInfo.ID = hex.EncodeToString(randBytes)
if err := h.hotplugAddDevice(*device, vfioDev); err != nil {
deviceLogger().WithError(err).Error("Failed to add device")
return err
}

View File

@ -346,12 +346,12 @@ func (q *qemu) createPod(podConfig PodConfig) error {
return err
}
if q.config.BlockDeviceDriver == VirtioBlock {
devices = q.arch.appendBridges(devices, q.state.Bridges)
if err != nil {
return err
}
} else {
if q.config.BlockDeviceDriver == VirtioSCSI {
devices = q.arch.appendSCSIController(devices)
}
@ -638,6 +638,44 @@ func (q *qemu) hotplugBlockDevice(drive Drive, op operation) error {
return nil
}
func (q *qemu) hotplugVFIODevice(device VFIODevice, op operation) error {
defer func(qemu *qemu) {
if q.qmpMonitorCh.qmp != nil {
q.qmpMonitorCh.qmp.Shutdown()
}
}(q)
qmp, err := q.qmpSetup()
if err != nil {
return err
}
q.qmpMonitorCh.qmp = qmp
devID := "vfio-" + device.DeviceInfo.ID
if op == addDevice {
addr, bus, err := q.addDeviceToBridge(devID)
if err != nil {
return err
}
if err := q.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, addr, bus); err != nil {
return err
}
} else {
if err := q.removeDeviceFromBridge(devID); err != nil {
return err
}
if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, devID); err != nil {
return err
}
}
return nil
}
func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operation) error {
switch devType {
case blockDev:
@ -646,6 +684,9 @@ func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operati
case cpuDev:
vcpus := devInfo.(uint32)
return q.hotplugCPUs(vcpus, op)
case vfioDev:
device := devInfo.(VFIODevice)
return q.hotplugVFIODevice(device, op)
default:
return fmt.Errorf("cannot hotplug device: unsupported device type '%v'", devType)
}