runtime: suppport split firmware

firmware can be split into FIRMWARE_VARS.fd (UEFI variables as
configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI
variables can be customized per each user while UEFI code is kept same.

fixes #3583

Signed-off-by: Julio Montes <julio.montes@intel.com>
This commit is contained in:
Julio Montes
2022-02-01 11:19:21 -06:00
parent 732c45de94
commit 1f29478b09
22 changed files with 140 additions and 42 deletions

View File

@@ -266,6 +266,11 @@ type Object struct {
// File is the device file
File string
// FirmwareVolume is the configuration volume for the firmware
// it can be used to split the TDVF/OVMF UEFI firmware in UEFI variables
// and UEFI program image.
FirmwareVolume string
// CBitPos is the location of the C-bit in a guest page table entry
// This is only relevant for sev-guest objects
CBitPos uint32
@@ -341,6 +346,9 @@ func (object Object) QemuParams(config *Config) []string {
deviceParams = append(deviceParams, string(object.Driver))
deviceParams = append(deviceParams, fmt.Sprintf("id=%s", object.DeviceID))
deviceParams = append(deviceParams, fmt.Sprintf("file=%s", object.File))
if object.FirmwareVolume != "" {
deviceParams = append(deviceParams, fmt.Sprintf("config-firmware-volume=%s", object.FirmwareVolume))
}
case SEVGuest:
objectParams = append(objectParams, string(object.Type))
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))

View File

@@ -45,6 +45,7 @@ var defaultImagePath = "/usr/share/kata-containers/kata-containers.img"
var defaultKernelPath = "/usr/share/kata-containers/vmlinuz.container"
var defaultInitrdPath = "/usr/share/kata-containers/kata-containers-initrd.img"
var defaultFirmwarePath = ""
var defaultFirmwareVolumePath = ""
var defaultMachineAccelerators = ""
var defaultCPUFeatures = ""
var systemdUnitName = "kata-containers.target"

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2018-2021 Intel Corporation
// Copyright (c) 2018-2022 Intel Corporation
// Copyright (c) 2018 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
@@ -79,6 +79,7 @@ type hypervisor struct {
Initrd string `toml:"initrd"`
Image string `toml:"image"`
Firmware string `toml:"firmware"`
FirmwareVolume string `toml:"firmware_volume"`
MachineAccelerators string `toml:"machine_accelerators"`
CPUFeatures string `toml:"cpu_features"`
KernelParams string `toml:"kernel_params"`
@@ -234,6 +235,19 @@ func (h hypervisor) firmware() (string, error) {
return ResolvePath(p)
}
func (h hypervisor) firmwareVolume() (string, error) {
p := h.FirmwareVolume
if p == "" {
if defaultFirmwareVolumePath == "" {
return "", nil
}
p = defaultFirmwareVolumePath
}
return ResolvePath(p)
}
func (h hypervisor) PFlash() ([]string, error) {
pflashes := h.PFlashList
@@ -602,6 +616,11 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
return vc.HypervisorConfig{}, err
}
firmwareVolume, err := h.firmwareVolume()
if err != nil {
return vc.HypervisorConfig{}, err
}
machineAccelerators := h.machineAccelerators()
cpuFeatures := h.cpuFeatures()
kernelParams := h.kernelParams()
@@ -644,6 +663,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
InitrdPath: initrd,
ImagePath: image,
FirmwarePath: firmware,
FirmwareVolumePath: firmwareVolume,
PFlash: pflashes,
MachineAccelerators: machineAccelerators,
CPUFeatures: cpuFeatures,
@@ -998,6 +1018,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig {
ImagePath: defaultImagePath,
InitrdPath: defaultInitrdPath,
FirmwarePath: defaultFirmwarePath,
FirmwareVolumePath: defaultFirmwareVolumePath,
MachineAccelerators: defaultMachineAccelerators,
CPUFeatures: defaultCPUFeatures,
HypervisorMachineType: defaultMachineType,

View File

@@ -1249,6 +1249,32 @@ func TestDefaultFirmware(t *testing.T) {
defaultFirmwarePath = oldDefaultFirmwarePath
}
func TestDefaultFirmwareVolume(t *testing.T) {
assert := assert.New(t)
// save default firmware path
oldDefaultFirmwareVolumePath := defaultFirmwareVolumePath
f, err := os.CreateTemp(os.TempDir(), "vol")
assert.NoError(err)
assert.NoError(f.Close())
defer os.RemoveAll(f.Name())
h := hypervisor{}
defaultFirmwareVolumePath = ""
p, err := h.firmwareVolume()
assert.NoError(err)
assert.Empty(p)
defaultFirmwareVolumePath = f.Name()
p, err = h.firmwareVolume()
assert.NoError(err)
assert.NotEmpty(p)
// restore default firmware volume path
defaultFirmwarePath = oldDefaultFirmwareVolumePath
}
func TestDefaultMachineAccelerators(t *testing.T) {
assert := assert.New(t)
machineAccelerators := "abc,123,rgb"
@@ -1355,12 +1381,13 @@ func TestUpdateRuntimeConfigurationVMConfig(t *testing.T) {
tomlConf := tomlConfig{
Hypervisor: map[string]hypervisor{
qemuHypervisorTableType: {
NumVCPUs: int32(vcpus),
MemorySize: mem,
Path: "/",
Kernel: "/",
Image: "/",
Firmware: "/",
NumVCPUs: int32(vcpus),
MemorySize: mem,
Path: "/",
Kernel: "/",
Image: "/",
Firmware: "/",
FirmwareVolume: "/",
},
},
}