diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 0de579c870..e7d00f7ea3 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -397,23 +397,6 @@ func (q *qemu) createQmpSocket() ([]govmmQemu.QMPSocket, error) { return sockets, nil } -func (q *qemu) buildInitdataDevice(devices []govmmQemu.Device, InitdataImage string) []govmmQemu.Device { - device := govmmQemu.BlockDevice{ - Driver: govmmQemu.VirtioBlock, - Transport: govmmQemu.TransportPCI, - ID: "initdata", - File: InitdataImage, - SCSI: false, - WCE: false, - AIO: govmmQemu.Threads, - Interface: "none", - Format: "raw", - } - - devices = append(devices, device) - return devices -} - func (q *qemu) buildDevices(ctx context.Context, kernelPath string) ([]govmmQemu.Device, *govmmQemu.IOThread, *govmmQemu.Kernel, error) { var devices []govmmQemu.Device @@ -763,7 +746,7 @@ func (q *qemu) CreateVM(ctx context.Context, id string, network Network, hypervi } if len(hypervisorConfig.Initdata) > 0 { - devices = q.buildInitdataDevice(devices, hypervisorConfig.InitdataImage) + devices = q.arch.buildInitdataDevice(ctx, devices, hypervisorConfig.InitdataImage) } // some devices configuration may also change kernel params, make sure this is called afterwards diff --git a/src/runtime/virtcontainers/qemu_arch_base.go b/src/runtime/virtcontainers/qemu_arch_base.go index aa41445916..18c193628c 100644 --- a/src/runtime/virtcontainers/qemu_arch_base.go +++ b/src/runtime/virtcontainers/qemu_arch_base.go @@ -176,6 +176,9 @@ type qemuArch interface { // Query QMP to find the PCI slot of a device, given its QOM path or ID qomGetSlot(qomPath string, qmpCh *qmpChannel) (types.PciSlot, error) + + // buildInitdataDevice creates an initdata device for the given architecture. + buildInitdataDevice(ctx context.Context, devices []govmmQemu.Device, initdataImage string) []govmmQemu.Device } type qemuArchBase struct { @@ -949,6 +952,24 @@ func (q *qemuArchBase) qomGetSlot(qomPath string, qmpCh *qmpChannel) (types.PciS return types.PciSlotFromInt(slotNum) } +// build initdata device +func (q *qemuArchBase) buildInitdataDevice(ctx context.Context, devices []govmmQemu.Device, initdataImage string) []govmmQemu.Device { + device := govmmQemu.BlockDevice{ + Driver: govmmQemu.VirtioBlock, + Transport: govmmQemu.TransportPCI, + ID: "initdata", + File: initdataImage, + SCSI: false, + WCE: false, + AIO: govmmQemu.Threads, + Interface: "none", + Format: "raw", + } + + devices = append(devices, device) + return devices +} + // Query QMP to find a device's PCI path given its QOM path or ID func (q *qemuArchBase) qomGetPciPath(qemuID string, qmpCh *qmpChannel) (types.PciPath, error) { diff --git a/src/runtime/virtcontainers/qemu_arm64.go b/src/runtime/virtcontainers/qemu_arm64.go index bfe6e2d405..2f3885835d 100644 --- a/src/runtime/virtcontainers/qemu_arm64.go +++ b/src/runtime/virtcontainers/qemu_arm64.go @@ -154,6 +154,11 @@ func (q *qemuArm64) enableProtection() error { return nil } +func (q *qemuArm64) buildInitdataDevice(ctx context.Context, devices []govmmQemu.Device, initdataImage string) []govmmQemu.Device { + hvLogger.Warnf("buildInitdataDevice not implemented for arm64; ignoring initdata image: %s", initdataImage) + return devices +} + func (q *qemuArm64) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string, initdataDigest []byte) ([]govmmQemu.Device, string, error) { err := q.enableProtection() if err != nil { diff --git a/src/runtime/virtcontainers/qemu_ppc64le.go b/src/runtime/virtcontainers/qemu_ppc64le.go index 87c2139b2b..51b014010b 100644 --- a/src/runtime/virtcontainers/qemu_ppc64le.go +++ b/src/runtime/virtcontainers/qemu_ppc64le.go @@ -8,6 +8,7 @@ package virtcontainers import ( + "context" "fmt" "time" @@ -156,6 +157,11 @@ func (q *qemuPPC64le) enableProtection() error { } } +func (q *qemuPPC64le) buildInitdataDevice(ctx context.Context, devices []govmmQemu.Device, initdataImage string) []govmmQemu.Device { + hvLogger.Warnf("buildInitdataDevice not implemented for PPC64le; ignoring initdata image: %s", initdataImage) + return devices +} + // append protection device func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string, initdataDigest []byte) ([]govmmQemu.Device, string, error) { switch q.protection { diff --git a/src/runtime/virtcontainers/qemu_s390x.go b/src/runtime/virtcontainers/qemu_s390x.go index 5f00e9ea76..9a10510d13 100644 --- a/src/runtime/virtcontainers/qemu_s390x.go +++ b/src/runtime/virtcontainers/qemu_s390x.go @@ -349,8 +349,9 @@ func (q *qemuS390x) appendProtectionDevice(devices []govmmQemu.Device, firmware, case seProtection: return append(devices, govmmQemu.Object{ - Type: govmmQemu.SecExecGuest, - ID: secExecID, + Type: govmmQemu.SecExecGuest, + ID: secExecID, + InitdataDigest: initdataDigest, }), firmware, nil case noneProtection: return devices, firmware, nil @@ -382,6 +383,42 @@ func (q *qemuS390x) appendVFIODevice(devices []govmmQemu.Device, vfioDev config. return devices } +func (q *qemuS390x) buildInitdataDevice(ctx context.Context, devices []govmmQemu.Device, initdataImage string) []govmmQemu.Device { + + var transport govmmQemu.VirtioTransport + var devNo string + + transport = govmmQemu.TransportCCW + id := "initdata" + addr, bridge, err := q.addDeviceToBridge(ctx, id, types.CCW) + if err != nil { + hvLogger.WithError(err).Error("Failed to allocate CCW address for initdata") + return nil + } + devNo, err = bridge.AddressFormatCCW(addr) + if err != nil { + hvLogger.WithError(err).Error("Failed to format CCW address for initdata") + return nil + } + hvLogger.WithField("devno", devNo).Info("Using dynamic CCW DevNo for initdata") + + device := govmmQemu.BlockDevice{ + Driver: govmmQemu.VirtioBlock, + Transport: transport, + ID: id, + File: initdataImage, + SCSI: false, + WCE: false, + AIO: govmmQemu.Threads, + Interface: "none", + Format: "raw", + DevNo: devNo, + } + + devices = append(devices, device) + return devices +} + // Query QMP to find a device's PCI path given its QOM path or ID func (q *qemuS390x) qomGetPciPath(qemuID string, qmpCh *qmpChannel) (types.PciPath, error) { hvLogger.Warnf("qomGetPciPath not implemented for s390x") diff --git a/src/runtime/virtcontainers/qemu_s390x_test.go b/src/runtime/virtcontainers/qemu_s390x_test.go index db88b4690f..f04c8cbf40 100644 --- a/src/runtime/virtcontainers/qemu_s390x_test.go +++ b/src/runtime/virtcontainers/qemu_s390x_test.go @@ -144,14 +144,15 @@ func TestQemuS390xAppendProtectionDevice(t *testing.T) { // Secure Execution protection s390x.(*qemuS390x).protection = seProtection - devices, bios, err = s390x.appendProtectionDevice(devices, firmware, "", []byte(nil)) + devices, bios, err = s390x.appendProtectionDevice(devices, firmware, "", []byte("")) assert.NoError(err) assert.Empty(bios) expectedOut := []govmmQemu.Device{ govmmQemu.Object{ - Type: govmmQemu.SecExecGuest, - ID: secExecID, + Type: govmmQemu.SecExecGuest, + ID: secExecID, + InitdataDigest: []byte(""), }, } assert.Equal(expectedOut, devices)