mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-04 14:37:25 +00:00
Merge pull request #10751 from ryansavino/snp-upstream-host-kernel-support
snp: update kata to use latest upstream packages for snp
This commit is contained in:
commit
122ad95da6
@ -10,7 +10,19 @@ To run Kata Containers in SNP-VMs, the following software stack is used.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
The host BIOS and kernel must be capable of supporting AMD SEV-SNP and configured accordingly. For Kata Containers, the host kernel with branch [`sev-snp-iommu-avic_5.19-rc6_v3`](https://github.com/AMDESE/linux/tree/sev-snp-iommu-avic_5.19-rc6_v3) and commit [`3a88547`](https://github.com/AMDESE/linux/commit/3a885471cf89156ea555341f3b737ad2a8d9d3d0) is known to work in conjunction with SEV Firmware version 1.51.3 (0xh\_1.33.03) available on AMD's [SEV developer website](https://developer.amd.com/sev/). See [AMD's guide](https://github.com/AMDESE/AMDSEV/tree/sev-snp-devel) to configure the host accordingly. Verify that you are able to run SEV-SNP encrypted VMs first. The guest components required for Kata Containers are built as described below.
|
The host BIOS and kernel must be capable of supporting AMD SEV-SNP and the host must be configured accordingly.
|
||||||
|
|
||||||
|
The latest SEV Firmware version is available on AMD's [SEV Developer Webpage](https://www.amd.com/en/developer/sev.html). It can also be updated via a platform OEM BIOS update.
|
||||||
|
|
||||||
|
The host kernel must be equal to or later than upstream version [6.11](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.tar.xz).
|
||||||
|
|
||||||
|
[`sev-utils`](https://github.com/amd/sev-utils/blob/coco-202501150000/docs/snp.md) is an easy way to install the required host kernel with the `setup-host` command. However, it will also build compatible guest kernel, OVMF, and QEMU components which are not necessary as these components are packaged with kata. The `sev-utils` script utility can be used with these additional components to test the memory encrypted launch and attestation of a base QEMU SNP guest.
|
||||||
|
|
||||||
|
For a simplified way to build just the upstream compatible host kernel, use the Confidential Containers fork of [AMDESE AMDSEV](https://github.com/confidential-containers/amdese-amdsev/tree/amd-snp-202501150000). Individual components can be built by running the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
./build.sh kernel host --install
|
||||||
|
```
|
||||||
|
|
||||||
**Tip**: It is easiest to first have Kata Containers running on your system and then modify it to run containers in SNP-VMs. Follow the [Developer guide](../Developer-Guide.md#warning) and then follow the below steps. Nonetheless, you can just follow this guide from the start.
|
**Tip**: It is easiest to first have Kata Containers running on your system and then modify it to run containers in SNP-VMs. Follow the [Developer guide](../Developer-Guide.md#warning) and then follow the below steps. Nonetheless, you can just follow this guide from the start.
|
||||||
|
|
||||||
|
@ -148,7 +148,6 @@ FIRMWARETDVFVOLUMEPATH :=
|
|||||||
|
|
||||||
FIRMWARESEVPATH := $(PREFIXDEPS)/share/ovmf/OVMF.fd
|
FIRMWARESEVPATH := $(PREFIXDEPS)/share/ovmf/OVMF.fd
|
||||||
FIRMWARESNPPATH := $(PREFIXDEPS)/share/ovmf/AMDSEV.fd
|
FIRMWARESNPPATH := $(PREFIXDEPS)/share/ovmf/AMDSEV.fd
|
||||||
SNPCERTSPATH := /opt/snp/cert_chain.cert
|
|
||||||
|
|
||||||
ROOTMEASURECONFIG ?= ""
|
ROOTMEASURECONFIG ?= ""
|
||||||
KERNELTDXPARAMS += $(ROOTMEASURECONFIG)
|
KERNELTDXPARAMS += $(ROOTMEASURECONFIG)
|
||||||
@ -638,7 +637,6 @@ USER_VARS += FIRMWARETDVFPATH
|
|||||||
USER_VARS += FIRMWAREVOLUMEPATH
|
USER_VARS += FIRMWAREVOLUMEPATH
|
||||||
USER_VARS += FIRMWARETDVFVOLUMEPATH
|
USER_VARS += FIRMWARETDVFVOLUMEPATH
|
||||||
USER_VARS += FIRMWARESNPPATH
|
USER_VARS += FIRMWARESNPPATH
|
||||||
USER_VARS += SNPCERTSPATH
|
|
||||||
USER_VARS += MACHINEACCELERATORS
|
USER_VARS += MACHINEACCELERATORS
|
||||||
USER_VARS += CPUFEATURES
|
USER_VARS += CPUFEATURES
|
||||||
USER_VARS += TDXCPUFEATURES
|
USER_VARS += TDXCPUFEATURES
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# XXX: Type: @PROJECT_TYPE@
|
# XXX: Type: @PROJECT_TYPE@
|
||||||
|
|
||||||
[hypervisor.qemu]
|
[hypervisor.qemu]
|
||||||
path = "@QEMUSNPPATH@"
|
path = "@QEMUPATH@"
|
||||||
kernel = "@KERNELCONFIDENTIALPATH@"
|
kernel = "@KERNELCONFIDENTIALPATH@"
|
||||||
#image = "@IMAGEPATH@"
|
#image = "@IMAGEPATH@"
|
||||||
initrd = "@INITRDCONFIDENTIALPATH@"
|
initrd = "@INITRDCONFIDENTIALPATH@"
|
||||||
@ -44,11 +44,6 @@ confidential_guest = true
|
|||||||
# enable SEV SNP VMs
|
# enable SEV SNP VMs
|
||||||
sev_snp_guest = true
|
sev_snp_guest = true
|
||||||
|
|
||||||
# The path to the file containing the SNP certificate chain (including
|
|
||||||
# VCEK/VLEK certificates). This wil be used to get the extended attestation
|
|
||||||
# report from the guest. The default path is @SNPCERTSPATH@.
|
|
||||||
snp_certs_path = "@SNPCERTSPATH@"
|
|
||||||
|
|
||||||
# Enable running QEMU VMM as a non-root user.
|
# Enable running QEMU VMM as a non-root user.
|
||||||
# By default QEMU VMM run as root. When this is set to true, QEMU VMM process runs as
|
# By default QEMU VMM run as root. When this is set to true, QEMU VMM process runs as
|
||||||
# a non-root random user. See documentation for the limitations of this mode.
|
# a non-root random user. See documentation for the limitations of this mode.
|
||||||
@ -63,7 +58,7 @@ enable_annotations = @DEFENABLEANNOTATIONS@
|
|||||||
# Each member of the list is a path pattern as described by glob(3).
|
# Each member of the list is a path pattern as described by glob(3).
|
||||||
# The default if not set is empty (all annotations rejected.)
|
# The default if not set is empty (all annotations rejected.)
|
||||||
# Your distribution recommends: @QEMUVALIDHYPERVISORPATHS@
|
# Your distribution recommends: @QEMUVALIDHYPERVISORPATHS@
|
||||||
valid_hypervisor_paths = @QEMUSNPVALIDHYPERVISORPATHS@
|
valid_hypervisor_paths = @QEMUVALIDHYPERVISORPATHS@
|
||||||
|
|
||||||
# Optional space-separated list of options to pass to the guest kernel.
|
# Optional space-separated list of options to pass to the guest kernel.
|
||||||
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
|
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
|
||||||
|
@ -300,10 +300,6 @@ type Object struct {
|
|||||||
// and UEFI program image.
|
// and UEFI program image.
|
||||||
FirmwareVolume string
|
FirmwareVolume string
|
||||||
|
|
||||||
// The path to the file containing the AMD SEV-SNP certificate chain
|
|
||||||
// (including VCEK/VLEK certificates).
|
|
||||||
SnpCertsPath string
|
|
||||||
|
|
||||||
// CBitPos is the location of the C-bit in a guest page table entry
|
// CBitPos is the location of the C-bit in a guest page table entry
|
||||||
// This is only relevant for sev-guest objects
|
// This is only relevant for sev-guest objects
|
||||||
CBitPos uint32
|
CBitPos uint32
|
||||||
@ -383,7 +379,6 @@ func (object Object) QemuParams(config *Config) []string {
|
|||||||
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))
|
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))
|
||||||
objectParams = append(objectParams, fmt.Sprintf("cbitpos=%d", object.CBitPos))
|
objectParams = append(objectParams, fmt.Sprintf("cbitpos=%d", object.CBitPos))
|
||||||
objectParams = append(objectParams, fmt.Sprintf("reduced-phys-bits=%d", object.ReducedPhysBits))
|
objectParams = append(objectParams, fmt.Sprintf("reduced-phys-bits=%d", object.ReducedPhysBits))
|
||||||
|
|
||||||
driveParams = append(driveParams, "if=pflash,format=raw,readonly=on")
|
driveParams = append(driveParams, "if=pflash,format=raw,readonly=on")
|
||||||
driveParams = append(driveParams, fmt.Sprintf("file=%s", object.File))
|
driveParams = append(driveParams, fmt.Sprintf("file=%s", object.File))
|
||||||
case SNPGuest:
|
case SNPGuest:
|
||||||
@ -392,12 +387,7 @@ func (object Object) QemuParams(config *Config) []string {
|
|||||||
objectParams = append(objectParams, fmt.Sprintf("cbitpos=%d", object.CBitPos))
|
objectParams = append(objectParams, fmt.Sprintf("cbitpos=%d", object.CBitPos))
|
||||||
objectParams = append(objectParams, fmt.Sprintf("reduced-phys-bits=%d", object.ReducedPhysBits))
|
objectParams = append(objectParams, fmt.Sprintf("reduced-phys-bits=%d", object.ReducedPhysBits))
|
||||||
objectParams = append(objectParams, "kernel-hashes=on")
|
objectParams = append(objectParams, "kernel-hashes=on")
|
||||||
if object.SnpCertsPath != "" {
|
config.Bios = object.File
|
||||||
objectParams = append(objectParams, fmt.Sprintf("certs-path=%s", object.SnpCertsPath))
|
|
||||||
}
|
|
||||||
|
|
||||||
driveParams = append(driveParams, "if=pflash,format=raw,readonly=on")
|
|
||||||
driveParams = append(driveParams, fmt.Sprintf("file=%s", object.File))
|
|
||||||
case SecExecGuest:
|
case SecExecGuest:
|
||||||
objectParams = append(objectParams, string(object.Type))
|
objectParams = append(objectParams, string(object.Type))
|
||||||
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))
|
objectParams = append(objectParams, fmt.Sprintf("id=%s", object.ID))
|
||||||
|
@ -116,5 +116,3 @@ const defaultPCIeSwitchPort = 0
|
|||||||
|
|
||||||
const defaultRemoteHypervisorSocket = "/run/peerpod/hypervisor.sock"
|
const defaultRemoteHypervisorSocket = "/run/peerpod/hypervisor.sock"
|
||||||
const defaultRemoteHypervisorTimeout = 600
|
const defaultRemoteHypervisorTimeout = 600
|
||||||
|
|
||||||
const defaultSnpCertsPath = "/opt/snp/cert_chain.cert"
|
|
||||||
|
@ -104,7 +104,6 @@ type hypervisor struct {
|
|||||||
SeccompSandbox string `toml:"seccompsandbox"`
|
SeccompSandbox string `toml:"seccompsandbox"`
|
||||||
BlockDeviceAIO string `toml:"block_device_aio"`
|
BlockDeviceAIO string `toml:"block_device_aio"`
|
||||||
RemoteHypervisorSocket string `toml:"remote_hypervisor_socket"`
|
RemoteHypervisorSocket string `toml:"remote_hypervisor_socket"`
|
||||||
SnpCertsPath string `toml:"snp_certs_path"`
|
|
||||||
HypervisorPathList []string `toml:"valid_hypervisor_paths"`
|
HypervisorPathList []string `toml:"valid_hypervisor_paths"`
|
||||||
JailerPathList []string `toml:"valid_jailer_paths"`
|
JailerPathList []string `toml:"valid_jailer_paths"`
|
||||||
VirtioFSDaemonList []string `toml:"valid_virtio_fs_daemon_paths"`
|
VirtioFSDaemonList []string `toml:"valid_virtio_fs_daemon_paths"`
|
||||||
@ -285,34 +284,6 @@ func (h hypervisor) firmware() (string, error) {
|
|||||||
return ResolvePath(p)
|
return ResolvePath(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h hypervisor) snpCertsPath() (string, error) {
|
|
||||||
// snpCertsPath only matter when using Confidential Guests
|
|
||||||
if !h.ConfidentialGuest {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// snpCertsPath only matter for SNP guests
|
|
||||||
if !h.SevSnpGuest {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
p := h.SnpCertsPath
|
|
||||||
|
|
||||||
if p == "" {
|
|
||||||
p = defaultSnpCertsPath
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := ResolvePath(p)
|
|
||||||
if err != nil {
|
|
||||||
if p == defaultSnpCertsPath {
|
|
||||||
msg := fmt.Sprintf("failed to resolve SNP certificates path: %s", defaultSnpCertsPath)
|
|
||||||
kataUtilsLogger.Warn(msg)
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return path, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h hypervisor) coldPlugVFIO() config.PCIePort {
|
func (h hypervisor) coldPlugVFIO() config.PCIePort {
|
||||||
if h.ColdPlugVFIO == "" {
|
if h.ColdPlugVFIO == "" {
|
||||||
return defaultColdPlugVFIO
|
return defaultColdPlugVFIO
|
||||||
@ -872,11 +843,6 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
|||||||
return vc.HypervisorConfig{}, err
|
return vc.HypervisorConfig{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
snpCertsPath, err := h.snpCertsPath()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
machineAccelerators := h.machineAccelerators()
|
machineAccelerators := h.machineAccelerators()
|
||||||
cpuFeatures := h.cpuFeatures()
|
cpuFeatures := h.cpuFeatures()
|
||||||
kernelParams := h.kernelParams()
|
kernelParams := h.kernelParams()
|
||||||
@ -941,7 +907,6 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
|||||||
RootfsType: rootfsType,
|
RootfsType: rootfsType,
|
||||||
FirmwarePath: firmware,
|
FirmwarePath: firmware,
|
||||||
FirmwareVolumePath: firmwareVolume,
|
FirmwareVolumePath: firmwareVolume,
|
||||||
SnpCertsPath: snpCertsPath,
|
|
||||||
PFlash: pflashes,
|
PFlash: pflashes,
|
||||||
MachineAccelerators: machineAccelerators,
|
MachineAccelerators: machineAccelerators,
|
||||||
CPUFeatures: cpuFeatures,
|
CPUFeatures: cpuFeatures,
|
||||||
|
@ -461,10 +461,6 @@ type HypervisorConfig struct {
|
|||||||
// The user maps to the uid.
|
// The user maps to the uid.
|
||||||
User string
|
User string
|
||||||
|
|
||||||
// The path to the file containing the AMD SEV-SNP certificate chain
|
|
||||||
// (including VCEK/VLEK certificates).
|
|
||||||
SnpCertsPath string
|
|
||||||
|
|
||||||
// KernelParams are additional guest kernel parameters.
|
// KernelParams are additional guest kernel parameters.
|
||||||
KernelParams []Param
|
KernelParams []Param
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ type qemuAmd64 struct {
|
|||||||
sgxEPCSize int64
|
sgxEPCSize int64
|
||||||
|
|
||||||
qgsPort uint32
|
qgsPort uint32
|
||||||
|
|
||||||
snpCertsPath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -127,10 +125,9 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
|||||||
protection: noneProtection,
|
protection: noneProtection,
|
||||||
legacySerial: config.LegacySerial,
|
legacySerial: config.LegacySerial,
|
||||||
},
|
},
|
||||||
vmFactory: factory,
|
vmFactory: factory,
|
||||||
snpGuest: config.SevSnpGuest,
|
snpGuest: config.SevSnpGuest,
|
||||||
qgsPort: config.QgsPort,
|
qgsPort: config.QgsPort,
|
||||||
snpCertsPath: config.SnpCertsPath,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ConfidentialGuest {
|
if config.ConfidentialGuest {
|
||||||
@ -314,7 +311,6 @@ func (q *qemuAmd64) appendProtectionDevice(devices []govmmQemu.Device, firmware,
|
|||||||
File: firmware,
|
File: firmware,
|
||||||
CBitPos: cpuid.AMDMemEncrypt.CBitPosition,
|
CBitPos: cpuid.AMDMemEncrypt.CBitPosition,
|
||||||
ReducedPhysBits: 1,
|
ReducedPhysBits: 1,
|
||||||
SnpCertsPath: q.snpCertsPath,
|
|
||||||
}), "", nil
|
}), "", nil
|
||||||
case noneProtection:
|
case noneProtection:
|
||||||
|
|
||||||
|
@ -38,9 +38,6 @@ build_root=$(mktemp -d)
|
|||||||
pushd $build_root
|
pushd $build_root
|
||||||
git clone --single-branch --depth 1 -b "${ovmf_version}" "${ovmf_repo}"
|
git clone --single-branch --depth 1 -b "${ovmf_version}" "${ovmf_repo}"
|
||||||
cd "${ovmf_dir}"
|
cd "${ovmf_dir}"
|
||||||
# TODO: Remove this line after bumping to a newer release of OVMF.
|
|
||||||
# Reference: https://github.com/tianocore/edk2/pull/6402
|
|
||||||
sed -i -e "s|https://github.com/Zeex/subhook.git|https://github.com/tianocore/edk2-subhook.git|g" .gitmodules
|
|
||||||
git submodule init
|
git submodule init
|
||||||
git submodule update
|
git submodule update
|
||||||
|
|
||||||
|
@ -339,12 +339,12 @@ externals:
|
|||||||
url: "https://github.com/tianocore/edk2"
|
url: "https://github.com/tianocore/edk2"
|
||||||
x86_64:
|
x86_64:
|
||||||
description: "Vanilla firmware build"
|
description: "Vanilla firmware build"
|
||||||
version: "edk2-stable202402"
|
version: "edk2-stable202411"
|
||||||
package: "OvmfPkg/OvmfPkgX64.dsc"
|
package: "OvmfPkg/OvmfPkgX64.dsc"
|
||||||
package_output_dir: "OvmfX64"
|
package_output_dir: "OvmfX64"
|
||||||
sev:
|
sev:
|
||||||
description: "AmdSev build needed for SEV measured direct boot."
|
description: "AmdSev build needed for SEV measured direct boot."
|
||||||
version: "edk2-stable202402"
|
version: "edk2-stable202411"
|
||||||
package: "OvmfPkg/AmdSev/AmdSevX64.dsc"
|
package: "OvmfPkg/AmdSev/AmdSevX64.dsc"
|
||||||
package_output_dir: "AmdSev"
|
package_output_dir: "AmdSev"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user