Skip to content

Commit

Permalink
vfio-hook: Rebind devices based on passed in device info
Browse files Browse the repository at this point in the history
Instead of searching all devices and using a hard coded supported
vendor:device table.

Signed-off-by: David Gibson <[email protected]>
  • Loading branch information
dgibson committed Aug 26, 2020
1 parent 88c068c commit 4ddd775
Showing 1 changed file with 30 additions and 54 deletions.
84 changes: 30 additions & 54 deletions vfio-hook/vfio-hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,7 @@ import (
"github.com/sirupsen/logrus"
)

var (
log = logrus.New()

//List taken from
// https://docs.openshift.com/container-platform/4.2/networking/multiple_networks/configuring-sr-iov.html#supported-devices_configuring-sr-iov
// 0x17a0:0x9750 added for testing on my laptop (it's an SD
// card reader which is interesting solely because I'm not
// generally using it on the host) -dgibson
supportedPciDevices = map[string]bool{
"0x8086:0x1521": true,
"0x8086:0x1520": true,
"0x8086:0x158b": true,
"0x8086:0x154c": true,
"0x15b3:0x1015": true,
"0x15b3:0x1017": true,
"0x17a0:0x9750": true,
}
)
var log = logrus.New()

const (
pciDeviceFile = "/sys/bus/pci/devices"
Expand All @@ -55,6 +38,7 @@ type GuestPciPath struct {
type vfioDevInfo struct {
HostAddress string `json:"host-address"`
GuestPath GuestPciPath `json:"guest-path"`
GuestBDF string
}
type vfioGroupInfo struct {
HostGroup string `json:"host-group"`
Expand Down Expand Up @@ -117,7 +101,11 @@ func main() {
return
}

scanDevices()
err = rebindDevices(info)
if err != nil {
log.Fatal(err)
return
}
}

func parseState() (string, error) {
Expand Down Expand Up @@ -242,59 +230,36 @@ func waitForPciPath(pciPath GuestPciPath) (string, error) {
}

func waitForDevices(info *vfioInfo) error {
for _, group := range *info {
for i, group := range *info {
log.Debugf("waitForDevice: Host Group %s", group.HostGroup)

for _, dev := range group.Devices {
for j, dev := range group.Devices {
guestBDF, err := waitForPciPath(dev.GuestPath)
if err != nil {
return err
}
log.Infof("Host device %s is guest device %s",
dev.HostAddress, guestBDF)
(*info)[i].Devices[j].GuestBDF = guestBDF
}
}

return nil
}

func scanDevices() {
bdfList, err := ioutil.ReadDir(pciDeviceFile)
if err != nil {
log.Errorf("Failed to readdir %s: %s", pciDeviceFile, err)
return
}

for _, bdf := range bdfList {
log.Debugf("bdf = ", bdf)
vendorPath := filepath.Join(pciDeviceFile, bdf.Name(), "vendor")
devicePath := filepath.Join(pciDeviceFile, bdf.Name(), "device")
vendor, err := ioutil.ReadFile(vendorPath)
if err != nil {
log.Errorf("Failed to read %s: %s", vendorPath, err)
continue
}
device, err := ioutil.ReadFile(devicePath)
if err != nil {
log.Errorf("Failed to read %s: %s", devicePath, err)
continue
}
vd := fmt.Sprintf("%s:%s", strings.TrimSuffix(string(vendor), "\n"), strings.TrimSuffix(string(device), "\n"))
log.Debugf("vd = ", vd)

if supportedPciDevices[vd] {
err = rebindOne(bdf.Name(), vd)
func rebindDevices(info *vfioInfo) error {
for _, group := range *info {
for _, dev := range group.Devices {
err := rebindOne(dev.GuestBDF)
if err != nil {
log.Errorf("%s", err)
continue
return err
}
}
}

return
return nil
}

func rebindOne(bdf string, vd string) error {
func rebindOne(bdf string) error {
log.Debugf("Attempting to rebind device %s to vfio", bdf)

driverPath := filepath.Join(pciDeviceFile, bdf, "driver")
Expand All @@ -316,9 +281,20 @@ func rebindOne(bdf string, vd string) error {
}
}

vendorPath := filepath.Join(pciDeviceFile, bdf, "vendor")
devicePath := filepath.Join(pciDeviceFile, bdf, "device")
vendor, err := ioutil.ReadFile(vendorPath)
if err != nil {
return err
}
device, err := ioutil.ReadFile(devicePath)
if err != nil {
return err
}
newid := fmt.Sprintf("%s %s", strings.TrimSuffix(string(vendor), "\n"), strings.TrimSuffix(string(device), "\n"))

newidPath := filepath.Join(vfioDeviceFile, "new_id")
newid := strings.Replace(vd, ":", " ", 1)
err := ioutil.WriteFile(newidPath, []byte(newid), 0200)
err = ioutil.WriteFile(newidPath, []byte(newid), 0200)
if err != nil {
return fmt.Errorf("Failed to write %s: %s", vfioDeviceFile, err)
}
Expand Down

0 comments on commit 4ddd775

Please sign in to comment.