diff --git a/Gopkg.lock b/Gopkg.lock index 5aa0c164a6..d194e4d53b 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -412,11 +412,12 @@ revision = "2f1d1f20f75d5404f53b9edf6b53ed5505508675" [[projects]] - digest = "1:f0e85729c00a427cef8de798b33b9a35b3117ee8760f6f00fc3cf3a5bb98f844" + branch = "master" + digest = "1:2ee402700d1a01bc9b09a41eea4823431685445f9aaf77fe4ba3fcea92ae952b" name = "github.com/intel/govmm" packages = ["qemu"] pruneopts = "NUT" - revision = "ee21903287393441c7bb53a0b0d39b8fa4075221" + revision = "cab47093760f36ef5a5da880bb70c4bf128abbbf" [[projects]] digest = "1:903bfb87f41dc18a533d327b5b03fd2f562f34deafcbd0db93d4be3fa8d6099c" diff --git a/Gopkg.toml b/Gopkg.toml index 1d6c77521b..5967fb605d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -48,7 +48,7 @@ [[constraint]] name = "github.com/intel/govmm" - revision = "ee21903287393441c7bb53a0b0d39b8fa4075221" + revision = "cab47093760f36ef5a5da880bb70c4bf128abbbf" [[constraint]] name = "github.com/kata-containers/agent" diff --git a/vendor/github.com/intel/govmm/qemu/qemu.go b/vendor/github.com/intel/govmm/qemu/qemu.go index f2b80ccd16..c9e0eb1517 100644 --- a/vendor/github.com/intel/govmm/qemu/qemu.go +++ b/vendor/github.com/intel/govmm/qemu/qemu.go @@ -106,6 +106,9 @@ const ( // VirtioBlockCCW is the CCW block device driver VirtioBlockCCW DeviceDriver = "virtio-blk-ccw" + + // PCIeRootPort is a PCIe Root Port, the PCIe device should be hotplugged to this port. + PCIeRootPort DeviceDriver = "pcie-root-port" ) // disableModern returns the parameters with the disable-modern option. @@ -898,6 +901,102 @@ func (vhostuserDev VhostUserDevice) QemuParams(config *Config) []string { return qemuParams } +// PCIeRootPortDevice represents a memory balloon device. +type PCIeRootPortDevice struct { + ID string // format: rp{n}, n>=0 + + Bus string // default is pcie.0 + Chassis string // (slot, chassis) pair is mandatory and must be unique for each pcie-root-port, >=0, default is 0x00 + Slot string // >=0, default is 0x00 + + Multifunction bool // true => "on", false => "off", default is off + Addr string // >=0, default is 0x00 + + // The PCIE-PCI bridge can be hot-plugged only into pcie-root-port that has 'bus-reserve' property value to + // provide secondary bus for the hot-plugged bridge. + BusReserve string + Pref64Reserve string // reserve prefetched MMIO aperture, 64-bit + Pref32Reserve string // reserve prefetched MMIO aperture, 32-bit + MemReserve string // reserve non-prefetched MMIO aperture, 32-bit *only* + IOReserve string // IO reservation + + ROMFile string // ROMFile specifies the ROM file being used for this device. +} + +// QemuParams returns the qemu parameters built out of the PCIeRootPortDevice. +func (b PCIeRootPortDevice) QemuParams(_ *Config) []string { + var qemuParams []string + var deviceParams []string + driver := PCIeRootPort + + deviceParams = append(deviceParams, fmt.Sprintf("%s,id=%s", driver, b.ID)) + + if b.Bus == "" { + b.Bus = "pcie.0" + } + deviceParams = append(deviceParams, fmt.Sprintf("bus=%s", b.Bus)) + + if b.Chassis == "" { + b.Chassis = "0x00" + } + deviceParams = append(deviceParams, fmt.Sprintf("chassis=%s", b.Chassis)) + + if b.Slot == "" { + b.Slot = "0x00" + } + deviceParams = append(deviceParams, fmt.Sprintf("slot=%s", b.Slot)) + + multifunction := "off" + if b.Multifunction { + multifunction = "on" + if b.Addr == "" { + b.Addr = "0x00" + } + deviceParams = append(deviceParams, fmt.Sprintf("addr=%s", b.Addr)) + } + deviceParams = append(deviceParams, fmt.Sprintf("multifunction=%v", multifunction)) + + if b.BusReserve != "" { + deviceParams = append(deviceParams, fmt.Sprintf("bus-reserve=%s", b.BusReserve)) + } + + if b.Pref64Reserve != "" { + deviceParams = append(deviceParams, fmt.Sprintf("pref64-reserve=%s", b.Pref64Reserve)) + } + + if b.Pref32Reserve != "" { + deviceParams = append(deviceParams, fmt.Sprintf("pref32-reserve=%s", b.Pref32Reserve)) + } + + if b.MemReserve != "" { + deviceParams = append(deviceParams, fmt.Sprintf("mem-reserve=%s", b.MemReserve)) + } + + if b.IOReserve != "" { + deviceParams = append(deviceParams, fmt.Sprintf("io-reserve=%s", b.IOReserve)) + } + + if isVirtioPCI[driver] && b.ROMFile != "" { + deviceParams = append(deviceParams, fmt.Sprintf("romfile=%s", b.ROMFile)) + } + + qemuParams = append(qemuParams, "-device") + qemuParams = append(qemuParams, strings.Join(deviceParams, ",")) + return qemuParams +} + +// Valid returns true if the PCIeRootPortDevice structure is valid and complete. +func (b PCIeRootPortDevice) Valid() bool { + // the "pref32-reserve" and "pref64-reserve" hints are mutually exclusive. + if b.Pref64Reserve != "" && b.Pref32Reserve != "" { + return false + } + if b.ID == "" { + return false + } + return true +} + // VFIODevice represents a qemu vfio device meant for direct access by guest OS. type VFIODevice struct { // Bus-Device-Function of device @@ -914,6 +1013,9 @@ type VFIODevice struct { // DeviceID specifies device id DeviceID string + + // Bus specifies device bus + Bus string } // Valid returns true if the VFIODevice structure is valid and complete. @@ -939,6 +1041,10 @@ func (vfioDev VFIODevice) QemuParams(config *Config) []string { deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", vfioDev.ROMFile)) } + if vfioDev.Bus != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", vfioDev.Bus)) + } + if isVirtioCCW[driver] { deviceParams = append(deviceParams, fmt.Sprintf(",devno=%s", vfioDev.DevNo)) } diff --git a/vendor/github.com/intel/govmm/qemu/qemu_arch_base.go b/vendor/github.com/intel/govmm/qemu/qemu_arch_base.go index d73c34f9a0..3e2e03d003 100644 --- a/vendor/github.com/intel/govmm/qemu/qemu_arch_base.go +++ b/vendor/github.com/intel/govmm/qemu/qemu_arch_base.go @@ -59,6 +59,7 @@ var isVirtioPCI = map[DeviceDriver]bool{ VirtioScsi: true, PCIBridgeDriver: true, PCIePCIBridgeDriver: true, + PCIeRootPort: true, } // isVirtioCCW is a dummy map to return always false on no-s390x arch diff --git a/vendor/github.com/intel/govmm/qemu/qmp.go b/vendor/github.com/intel/govmm/qemu/qmp.go index 00e9fed279..ae56266981 100644 --- a/vendor/github.com/intel/govmm/qemu/qmp.go +++ b/vendor/github.com/intel/govmm/qemu/qmp.go @@ -1156,17 +1156,20 @@ func (q *QMP) ExecutePCIVhostUserDevAdd(ctx context.Context, driver, devID, char return q.executeCommand(ctx, "device_add", args, nil) } -// ExecuteVFIODeviceAdd adds a VFIO device to a QEMU instance -// using the device_add command. devID is the id of the device to add. -// Must be valid QMP identifier. bdf is the PCI bus-device-function -// of the pci device. -func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, romfile string) error { +// ExecuteVFIODeviceAdd adds a VFIO device to a QEMU instance using the device_add command. +// devID is the id of the device to add. Must be valid QMP identifier. +// bdf is the PCI bus-device-function of the pci device. +// bus is optional. When hot plugging a PCIe device, the bus can be the ID of the pcie-root-port. +func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, bus, romfile string) error { args := map[string]interface{}{ "id": devID, "driver": Vfio, "host": bdf, "romfile": romfile, } + if bus != "" { + args["bus"] = bus + } return q.executeCommand(ctx, "device_add", args, nil) } diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 7ae543a068..66b7b71783 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -1157,7 +1157,7 @@ func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) (err erro if q.state.HotplugVFIOOnRootBus { switch device.Type { case config.VFIODeviceNormalType: - return q.qmpMonitorCh.qmp.ExecuteVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, romFile) + return q.qmpMonitorCh.qmp.ExecuteVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, "", romFile) case config.VFIODeviceMediatedType: return q.qmpMonitorCh.qmp.ExecutePCIVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, devID, device.SysfsDev, "", "", romFile) default: