diff --git a/src/runtime/virtcontainers/qemu_arch_base.go b/src/runtime/virtcontainers/qemu_arch_base.go index d38ea7b052..f790a36ee6 100644 --- a/src/runtime/virtcontainers/qemu_arch_base.go +++ b/src/runtime/virtcontainers/qemu_arch_base.go @@ -130,6 +130,9 @@ type qemuArch interface { // appendPCIeRootPortDevice appends a pcie-root-port device to pcie.0 bus appendPCIeRootPortDevice(devices []govmmQemu.Device, number uint32) []govmmQemu.Device + + // append vIOMMU device + appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) } type qemuArchBase struct { @@ -765,4 +768,22 @@ func (q *qemuArchBase) addBridge(b types.Bridge) { // appendPCIeRootPortDevice appends to devices the given pcie-root-port func (q *qemuArchBase) appendPCIeRootPortDevice(devices []govmmQemu.Device, number uint32) []govmmQemu.Device { return genericAppendPCIeRootPort(devices, number, q.machineType) + +} + +// appendIOMMU appends a virtual IOMMU device +func (q *qemuArchBase) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { + switch q.machineType { + case QemuQ35: + iommu := govmmQemu.IommuDev{ + Intremap: true, + DeviceIotlb: true, + CachingMode: true, + } + + devices = append(devices, iommu) + return devices, nil + default: + return devices, fmt.Errorf("Machine Type %s does not support vIOMMU", q.machineType) + } } diff --git a/src/runtime/virtcontainers/qemu_arch_base_test.go b/src/runtime/virtcontainers/qemu_arch_base_test.go index dec0fe6e24..8eacb085ac 100644 --- a/src/runtime/virtcontainers/qemu_arch_base_test.go +++ b/src/runtime/virtcontainers/qemu_arch_base_test.go @@ -566,3 +566,27 @@ func TestQemuArchBaseAppendNetwork(t *testing.T) { assert.NoError(err) assert.Equal(expectedOut, devices) } + +func TestQemuArchBaseAppendIOMMU(t *testing.T) { + var devices []govmmQemu.Device + var err error + assert := assert.New(t) + qemuArchBase := newQemuArchBase() + + expectedOut := []govmmQemu.Device{ + govmmQemu.IommuDev{ + Intremap: true, + DeviceIotlb: true, + CachingMode: true, + }, + } + // Test IOMMU is not appended to PC machine type + qemuArchBase.machineType = QemuPC + devices, err = qemuArchBase.appendIOMMU(devices) + assert.Error(err) + + qemuArchBase.machineType = QemuQ35 + devices, err = qemuArchBase.appendIOMMU(devices) + assert.NoError(err) + assert.Equal(expectedOut, devices) +} diff --git a/src/runtime/virtcontainers/qemu_arm64.go b/src/runtime/virtcontainers/qemu_arm64.go index 6d089cf010..9d1964c1c6 100644 --- a/src/runtime/virtcontainers/qemu_arm64.go +++ b/src/runtime/virtcontainers/qemu_arm64.go @@ -7,6 +7,7 @@ package virtcontainers import ( "context" + "fmt" "io/ioutil" "runtime" "strings" @@ -168,3 +169,7 @@ func (q *qemuArm64) setIgnoreSharedMemoryMigrationCaps(_ context.Context, _ *gov // x-ignore-shared not support in arm64 for now return nil } + +func (q *qemuArm64) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { + return devices, fmt.Errorf("Arm64 architecture does not support vIOMMU") +} diff --git a/src/runtime/virtcontainers/qemu_ppc64le.go b/src/runtime/virtcontainers/qemu_ppc64le.go index fdddadcf26..ce037c52e8 100644 --- a/src/runtime/virtcontainers/qemu_ppc64le.go +++ b/src/runtime/virtcontainers/qemu_ppc64le.go @@ -6,6 +6,7 @@ package virtcontainers import ( + "fmt" "time" govmmQemu "github.com/intel/govmm/qemu" @@ -129,3 +130,7 @@ func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { return genericAppendBridges(devices, q.Bridges, q.machineType) } + +func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { + return devices, fmt.Errorf("PPC64le does not support appending a vIOMMU") +} diff --git a/src/runtime/virtcontainers/qemu_s390x.go b/src/runtime/virtcontainers/qemu_s390x.go index 8480ff6957..d6e449ff38 100644 --- a/src/runtime/virtcontainers/qemu_s390x.go +++ b/src/runtime/virtcontainers/qemu_s390x.go @@ -268,3 +268,7 @@ func (q *qemuS390x) appendVSock(devices []govmmQemu.Device, vsock types.VSock) ( return devices, nil } + +func (q *qemuS390x) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { + return devices, fmt.Errorf("S390x does not support appending a vIOMMU") +}