mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 20:24:31 +00:00
drivers: Correct isPCIeDevice logic
Currently, isPCIeDevice() attempts to determine if a (host) device is PCI-Express capable by looking up its link speed via the PCI slots information in sysfs. This is a) complicated and b) wrong. PCI-e devices don't have to have slots information, so this frequently fails. Instead determine if devices are PCI-e by checking for the presence of PCIe extended configuration space by looking at the size of the "config" file in sysfs. Forward ported from 6bf93b23 in the Kata 1.x runtime repository. Fixes: #611 Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
c422d061cb
commit
92dfa4634b
@ -89,9 +89,6 @@ var SysIOMMUPath = "/sys/kernel/iommu_groups"
|
|||||||
// SysBusPciDevicesPath is static string of /sys/bus/pci/devices
|
// SysBusPciDevicesPath is static string of /sys/bus/pci/devices
|
||||||
var SysBusPciDevicesPath = "/sys/bus/pci/devices"
|
var SysBusPciDevicesPath = "/sys/bus/pci/devices"
|
||||||
|
|
||||||
// SysBusPciSlotsPath is static string of /sys/bus/pci/slots
|
|
||||||
var SysBusPciSlotsPath = "/sys/bus/pci/slots"
|
|
||||||
|
|
||||||
var getSysDevPath = getSysDevPathImpl
|
var getSysDevPath = getSysDevPathImpl
|
||||||
|
|
||||||
// DeviceInfo is an embedded type that contains device data common to all types of devices.
|
// DeviceInfo is an embedded type that contains device data common to all types of devices.
|
||||||
|
@ -9,6 +9,7 @@ package drivers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -22,6 +23,8 @@ const (
|
|||||||
|
|
||||||
PCIDomain = "0000"
|
PCIDomain = "0000"
|
||||||
PCIeKeyword = "PCIe"
|
PCIeKeyword = "PCIe"
|
||||||
|
|
||||||
|
PCIConfigSpaceSize = 256
|
||||||
)
|
)
|
||||||
|
|
||||||
type PCISysFsType string
|
type PCISysFsType string
|
||||||
@ -52,23 +55,17 @@ func isPCIeDevice(bdf string) bool {
|
|||||||
if len(strings.Split(bdf, ":")) == 2 {
|
if len(strings.Split(bdf, ":")) == 2 {
|
||||||
bdf = PCIDomain + ":" + bdf
|
bdf = PCIDomain + ":" + bdf
|
||||||
}
|
}
|
||||||
slots, err := ioutil.ReadDir(config.SysBusPciSlotsPath)
|
|
||||||
|
configPath := filepath.Join(config.SysBusPciDevicesPath, bdf, "config")
|
||||||
|
fi, err := os.Stat(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
deviceLogger().WithError(err).WithField("path", config.SysBusPciSlotsPath).Warn("failed to list pci slots")
|
deviceLogger().WithField("dev-bdf", bdf).WithField("error", err).Warning("Couldn't stat() configuration space file")
|
||||||
return false
|
return false //Who knows?
|
||||||
}
|
}
|
||||||
b := strings.Split(bdf, ".")[0]
|
|
||||||
for _, slot := range slots {
|
// Plain PCI devices hav 256 bytes of configuration space,
|
||||||
address := getPCISlotProperty(slot.Name(), PCISysFsSlotsAddress)
|
// PCI-Express devices have 4096 bytes
|
||||||
if b == address {
|
return fi.Size() > PCIConfigSpaceSize
|
||||||
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
|
// read from /sys/bus/pci/devices/xxx/property
|
||||||
@ -85,17 +82,6 @@ func getPCIDeviceProperty(bdf string, property PCISysFsProperty) string {
|
|||||||
return rlt
|
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) {
|
func readPCIProperty(propertyPath string) (string, error) {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
|
Loading…
Reference in New Issue
Block a user