runtime/device: Give the agent information about VFIO devices

We send information about several kinds of devices to the agent so
that it can apply specific handling.  We don't currently do this with
VFIO devices.  However we need to do that so that the agent can
properly wait for VFIO devices to be ready (previously it did that
using a PCI rescan which may not be reliable and has some very bad
side effects).

This patch collates and sends the relevant information.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
David Gibson 2021-04-13 15:00:19 +10:00
parent ebd7b61884
commit aad1a8734f

View File

@ -92,6 +92,7 @@ var (
kataNvdimmDevType = "nvdimm"
kataVirtioFSDevType = "virtio-fs"
kataWatchableBindDevType = "watchable-bind"
kataVfioGuestKernelDevType = "vfio-gk" // VFIO device for consumption by the guest kernel
sharedDir9pOptions = []string{"trans=virtio,version=9p2000.L,cache=mmap", "nodev"}
sharedDirVirtioFSOptions = []string{}
sharedDirVirtioFSDaxOptions = "dax"
@ -1201,6 +1202,38 @@ func (k *kataAgent) appendVhostUserBlkDevice(dev ContainerDevice, device api.Dev
return kataDevice
}
func (k *kataAgent) appendVfioDevice(dev ContainerDevice, device api.Device, c *Container) *grpc.Device {
devList, ok := device.GetDeviceInfo().([]*config.VFIODev)
if !ok || devList == nil {
k.Logger().WithField("device", device).Error("malformed vfio device")
return nil
}
groupNum := filepath.Base(dev.ContainerPath)
// Each /dev/vfio/NN device represents a VFIO group, which
// could include several PCI devices. So we give group
// information in the main structure, then list each
// individual PCI device in the Options array.
//
// Each option is formatted as "DDDD:BB:DD.F=<pcipath>"
// DDDD:BB:DD.F is the device's PCI address on the
// *host*. <pcipath> is the device's PCI path in the guest
// (see qomGetPciPath() for details).
kataDevice := &grpc.Device{
ContainerPath: dev.ContainerPath,
Type: kataVfioGuestKernelDevType,
Id: groupNum,
Options: make([]string, len(devList)),
}
for i, pciDev := range devList {
kataDevice.Options[i] = fmt.Sprintf("0000:%s=%s", pciDev.BDF, pciDev.GuestPciPath)
}
return kataDevice
}
func (k *kataAgent) appendDevices(deviceList []*grpc.Device, c *Container) []*grpc.Device {
var kataDevice *grpc.Device
@ -1216,6 +1249,8 @@ func (k *kataAgent) appendDevices(deviceList []*grpc.Device, c *Container) []*gr
kataDevice = k.appendBlockDevice(dev, device, c)
case config.VhostUserBlk:
kataDevice = k.appendVhostUserBlkDevice(dev, device, c)
case config.DeviceVFIO:
kataDevice = k.appendVfioDevice(dev, device, c)
}
if kataDevice == nil {