Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #117 from devimc/vfio/hotplug
Browse files Browse the repository at this point in the history
virtcontainers: vfio: add support for hot plugging VFIO devices
  • Loading branch information
jodh-intel authored Mar 27, 2018
2 parents 1846624 + 249945f commit 7b0c2d1
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 34 deletions.
8 changes: 7 additions & 1 deletion virtcontainers/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,13 @@ func (device *VFIODevice) attach(h hypervisor, c *Container) error {

device.BDF = deviceBDF

if err := h.addDevice(*device, vfioDev); err != nil {
randBytes, err := generateRandomBytes(8)
if err != nil {
return err
}
device.DeviceInfo.ID = hex.EncodeToString(randBytes)

if err := h.hotplugAddDevice(*device, vfioDev); err != nil {
deviceLogger().WithError(err).Error("Failed to add device")
return err
}
Expand Down
25 changes: 0 additions & 25 deletions virtcontainers/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,6 @@ func createPod(podConfig PodConfig) (*Pod, error) {
return nil, err
}

// Passthrough devices
if err := p.attachDevices(); err != nil {
return nil, err
}

// Set pod state
if err := p.setPodState(StateReady); err != nil {
return nil, err
Expand Down Expand Up @@ -1070,23 +1065,3 @@ func togglePausePod(podID string, pause bool) (*Pod, error) {

return p, nil
}

func (p *Pod) attachDevices() error {
for _, container := range p.containers {
if err := container.attachDevices(); err != nil {
return err
}
}

return nil
}

func (p *Pod) detachDevices() error {
for _, container := range p.containers {
if err := container.detachDevices(); err != nil {
return err
}
}

return nil
}
4 changes: 2 additions & 2 deletions virtcontainers/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1171,10 +1171,10 @@ func TestPodAttachDevicesVFIO(t *testing.T) {

containers[0].pod = &pod

err = pod.attachDevices()
err = containers[0].attachDevices()
assert.Nil(t, err, "Error while attaching devices %s", err)

err = pod.detachDevices()
err = containers[0].detachDevices()
assert.Nil(t, err, "Error while detaching devices %s", err)
}

Expand Down
53 changes: 47 additions & 6 deletions virtcontainers/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,12 +346,12 @@ func (q *qemu) createPod(podConfig PodConfig) error {
return err
}

if q.config.BlockDeviceDriver == VirtioBlock {
devices = q.arch.appendBridges(devices, q.state.Bridges)
if err != nil {
return err
}
} else {
devices = q.arch.appendBridges(devices, q.state.Bridges)
if err != nil {
return err
}

if q.config.BlockDeviceDriver == VirtioSCSI {
devices = q.arch.appendSCSIController(devices)
}

Expand Down Expand Up @@ -638,6 +638,44 @@ func (q *qemu) hotplugBlockDevice(drive Drive, op operation) error {
return nil
}

func (q *qemu) hotplugVFIODevice(device VFIODevice, op operation) error {
defer func(qemu *qemu) {
if q.qmpMonitorCh.qmp != nil {
q.qmpMonitorCh.qmp.Shutdown()
}
}(q)

qmp, err := q.qmpSetup()
if err != nil {
return err
}

q.qmpMonitorCh.qmp = qmp

devID := "vfio-" + device.DeviceInfo.ID

if op == addDevice {
addr, bus, err := q.addDeviceToBridge(devID)
if err != nil {
return err
}

if err := q.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, addr, bus); err != nil {
return err
}
} else {
if err := q.removeDeviceFromBridge(devID); err != nil {
return err
}

if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, devID); err != nil {
return err
}
}

return nil
}

func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operation) error {
switch devType {
case blockDev:
Expand All @@ -646,6 +684,9 @@ func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operati
case cpuDev:
vcpus := devInfo.(uint32)
return q.hotplugCPUs(vcpus, op)
case vfioDev:
device := devInfo.(VFIODevice)
return q.hotplugVFIODevice(device, op)
default:
return fmt.Errorf("cannot hotplug device: unsupported device type '%v'", devType)
}
Expand Down

0 comments on commit 7b0c2d1

Please sign in to comment.