diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 81c44a9fdb..1c9bbf1aae 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -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=" + // DDDD:BB:DD.F is the device's PCI address on the + // *host*. 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 {