Merge pull request #11640 from rafsal-rahim/bm-initdata-s390x

Feat | Implement initdata for bare-metal/qemu for s390x
This commit is contained in:
Hyounggyu Choi 2025-08-15 10:42:32 +02:00 committed by GitHub
commit 28bd0cf405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 87 additions and 31 deletions

View File

@ -397,23 +397,6 @@ func (q *qemu) createQmpSocket() ([]govmmQemu.QMPSocket, error) {
return sockets, nil 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) { func (q *qemu) buildDevices(ctx context.Context, kernelPath string) ([]govmmQemu.Device, *govmmQemu.IOThread, *govmmQemu.Kernel, error) {
var devices []govmmQemu.Device 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 { 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 // some devices configuration may also change kernel params, make sure this is called afterwards

View File

@ -176,6 +176,9 @@ type qemuArch interface {
// Query QMP to find the PCI slot of a device, given its QOM path or ID // Query QMP to find the PCI slot of a device, given its QOM path or ID
qomGetSlot(qomPath string, qmpCh *qmpChannel) (types.PciSlot, error) 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 { type qemuArchBase struct {
@ -949,6 +952,24 @@ func (q *qemuArchBase) qomGetSlot(qomPath string, qmpCh *qmpChannel) (types.PciS
return types.PciSlotFromInt(slotNum) 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 // 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) { func (q *qemuArchBase) qomGetPciPath(qemuID string, qmpCh *qmpChannel) (types.PciPath, error) {

View File

@ -154,6 +154,11 @@ func (q *qemuArm64) enableProtection() error {
return nil 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) { func (q *qemuArm64) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string, initdataDigest []byte) ([]govmmQemu.Device, string, error) {
err := q.enableProtection() err := q.enableProtection()
if err != nil { if err != nil {

View File

@ -8,6 +8,7 @@
package virtcontainers package virtcontainers
import ( import (
"context"
"fmt" "fmt"
"time" "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 // append protection device
func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string, initdataDigest []byte) ([]govmmQemu.Device, string, error) { func (q *qemuPPC64le) appendProtectionDevice(devices []govmmQemu.Device, firmware, firmwareVolume string, initdataDigest []byte) ([]govmmQemu.Device, string, error) {
switch q.protection { switch q.protection {

View File

@ -351,6 +351,7 @@ func (q *qemuS390x) appendProtectionDevice(devices []govmmQemu.Device, firmware,
govmmQemu.Object{ govmmQemu.Object{
Type: govmmQemu.SecExecGuest, Type: govmmQemu.SecExecGuest,
ID: secExecID, ID: secExecID,
InitdataDigest: initdataDigest,
}), firmware, nil }), firmware, nil
case noneProtection: case noneProtection:
return devices, firmware, nil return devices, firmware, nil
@ -382,6 +383,42 @@ func (q *qemuS390x) appendVFIODevice(devices []govmmQemu.Device, vfioDev config.
return devices 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 // 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) { func (q *qemuS390x) qomGetPciPath(qemuID string, qmpCh *qmpChannel) (types.PciPath, error) {
hvLogger.Warnf("qomGetPciPath not implemented for s390x") hvLogger.Warnf("qomGetPciPath not implemented for s390x")

View File

@ -144,7 +144,7 @@ func TestQemuS390xAppendProtectionDevice(t *testing.T) {
// Secure Execution protection // Secure Execution protection
s390x.(*qemuS390x).protection = seProtection 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.NoError(err)
assert.Empty(bios) assert.Empty(bios)
@ -152,6 +152,7 @@ func TestQemuS390xAppendProtectionDevice(t *testing.T) {
govmmQemu.Object{ govmmQemu.Object{
Type: govmmQemu.SecExecGuest, Type: govmmQemu.SecExecGuest,
ID: secExecID, ID: secExecID,
InitdataDigest: []byte(""),
}, },
} }
assert.Equal(expectedOut, devices) assert.Equal(expectedOut, devices)

View File

@ -45,13 +45,16 @@ function setup_kbs_image_policy_for_initdata() {
fi fi
export CURRENT_ARCH=$(uname -m) export CURRENT_ARCH=$(uname -m)
if [ "${CURRENT_ARCH}" != "x86_64" ]; then case "${CURRENT_ARCH}" in
skip "Test skipped as only x86-64 supports, while current platform is ${CURRENT_ARCH}" "x86_64"|"s390x")
fi ;;
*)
skip "Test skipped as only x86-64 & s390x is supported, while current platform is ${CURRENT_ARCH}"
;;
esac
# TODO: Enable for more archs
case "$KATA_HYPERVISOR" in case "$KATA_HYPERVISOR" in
"qemu-tdx"|"qemu-coco-dev"|"qemu-snp") "qemu-tdx"|"qemu-coco-dev"|"qemu-snp"|"qemu-se")
;; ;;
*) *)
skip "Test not supported for ${KATA_HYPERVISOR}." skip "Test not supported for ${KATA_HYPERVISOR}."