mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-27 19:14:21 +01:00
- support attach large bar space vfio devices after create container fixes #2460 Signed-off-by: Jimmy Xu <junming.xjm@antfin.com>
125 lines
3.5 KiB
Go
125 lines
3.5 KiB
Go
// Copyright (c) 2017-2018 Intel Corporation
|
|
// Copyright (c) 2018 Huawei Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package drivers
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
|
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
intMax = ^uint(0)
|
|
|
|
PCIDomain = "0000"
|
|
PCIeKeyword = "PCIe"
|
|
)
|
|
|
|
type PCISysFsType string
|
|
|
|
var (
|
|
PCISysFsDevices PCISysFsType = "devices" // /sys/bus/pci/devices
|
|
PCISysFsSlots PCISysFsType = "slots" // /sys/bus/pci/slots
|
|
)
|
|
|
|
type PCISysFsProperty string
|
|
|
|
var (
|
|
PCISysFsDevicesClass PCISysFsProperty = "class" // /sys/bus/pci/devices/xxx/class
|
|
PCISysFsSlotsAddress PCISysFsProperty = "address" // /sys/bus/pci/slots/xxx/address
|
|
PCISysFsSlotsMaxBusSpeed PCISysFsProperty = "max_bus_speed" // /sys/bus/pci/slots/xxx/max_bus_speed
|
|
)
|
|
|
|
func deviceLogger() *logrus.Entry {
|
|
return api.DeviceLogger()
|
|
}
|
|
|
|
/*
|
|
Identify PCIe device by /sys/bus/pci/slots/xx/max_bus_speed, sample content "8.0 GT/s PCIe"
|
|
The /sys/bus/pci/slots/xx/address contains bdf, sample content "0000:04:00"
|
|
bdf format: bus:slot.function
|
|
*/
|
|
func isPCIeDevice(bdf string) bool {
|
|
if len(strings.Split(bdf, ":")) == 2 {
|
|
bdf = PCIDomain + ":" + bdf
|
|
}
|
|
slots, err := ioutil.ReadDir(config.SysBusPciSlotsPath)
|
|
if err != nil {
|
|
deviceLogger().WithError(err).WithField("path", config.SysBusPciSlotsPath).Warn("failed to list pci slots")
|
|
return false
|
|
}
|
|
b := strings.Split(bdf, ".")[0]
|
|
for _, slot := range slots {
|
|
address := getPCISlotProperty(slot.Name(), PCISysFsSlotsAddress)
|
|
if b == address {
|
|
maxBusSpeed := getPCISlotProperty(slot.Name(), PCISysFsSlotsMaxBusSpeed)
|
|
if strings.Contains(maxBusSpeed, PCIeKeyword) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
deviceLogger().WithField("dev-bdf", bdf).Debug("can not find slot for bdf of pci device")
|
|
return false
|
|
}
|
|
|
|
// read from /sys/bus/pci/devices/xxx/property
|
|
func getPCIDeviceProperty(bdf string, property PCISysFsProperty) string {
|
|
if len(strings.Split(bdf, ":")) == 2 {
|
|
bdf = PCIDomain + ":" + bdf
|
|
}
|
|
propertyPath := filepath.Join(config.SysBusPciDevicesPath, bdf, string(property))
|
|
rlt, err := readPCIProperty(propertyPath)
|
|
if err != nil {
|
|
deviceLogger().WithError(err).WithField("path", propertyPath).Warn("failed to read pci device property")
|
|
return ""
|
|
}
|
|
return rlt
|
|
}
|
|
|
|
// read from /sys/bus/pci/slots/xxx/property
|
|
func getPCISlotProperty(slot string, property PCISysFsProperty) string {
|
|
propertyPath := filepath.Join(config.SysBusPciSlotsPath, slot, string(property))
|
|
rlt, err := readPCIProperty(propertyPath)
|
|
if err != nil {
|
|
deviceLogger().WithError(err).WithField("path", propertyPath).Warn("failed to read pci slot property")
|
|
return ""
|
|
}
|
|
return rlt
|
|
}
|
|
|
|
func readPCIProperty(propertyPath string) (string, error) {
|
|
var (
|
|
buf []byte
|
|
err error
|
|
)
|
|
if buf, err = ioutil.ReadFile(propertyPath); err != nil {
|
|
return "", fmt.Errorf("failed to read pci sysfs %v, error:%v", propertyPath, err)
|
|
}
|
|
return strings.Split(string(buf), "\n")[0], nil
|
|
}
|
|
|
|
func GetVFIODeviceType(deviceFileName string) config.VFIODeviceType {
|
|
//For example, 0000:04:00.0
|
|
tokens := strings.Split(deviceFileName, ":")
|
|
vfioDeviceType := config.VFIODeviceErrorType
|
|
if len(tokens) == 3 {
|
|
vfioDeviceType = config.VFIODeviceNormalType
|
|
} else {
|
|
//For example, 83b8f4f2-509f-382f-3c1e-e6bfe0fa1001
|
|
tokens = strings.Split(deviceFileName, "-")
|
|
if len(tokens) == 5 {
|
|
vfioDeviceType = config.VFIODeviceMediatedType
|
|
}
|
|
}
|
|
return vfioDeviceType
|
|
}
|