diff --git a/src/runtime/pkg/govmm/qemu/qemu.go b/src/runtime/pkg/govmm/qemu/qemu.go index f121696c9..8bf17967b 100644 --- a/src/runtime/pkg/govmm/qemu/qemu.go +++ b/src/runtime/pkg/govmm/qemu/qemu.go @@ -141,16 +141,9 @@ const ( func isDimmSupported(config *Config) bool { switch runtime.GOARCH { case "amd64", "386", "ppc64le", "arm64": - if config != nil { - if config.Machine.Type == MachineTypeMicrovm { - // microvm does not support NUMA - return false - } - if config.Knobs.MemFDPrivate { - // TDX guests rely on MemFD Private, which - // does not have NUMA support yet - return false - } + if config != nil && config.Machine.Type == MachineTypeMicrovm { + // microvm does not support NUMA + return false } return true default: @@ -2649,9 +2642,6 @@ type Knobs struct { // MemPrealloc will allocate all the RAM upfront MemPrealloc bool - // Private Memory FD meant for private memory map/unmap. - MemFDPrivate bool - // FileBackedMem requires Memory.Size and Memory.Path of the VM to // be set. FileBackedMem bool @@ -2674,6 +2664,10 @@ type Knobs struct { // IOMMUPlatform will enable IOMMU for supported devices IOMMUPlatform bool + + // Whether private memory should be used or not + // This is required by TDX, at least. + Private bool } // IOThread allows IO to be performed on a separate thread. @@ -3017,13 +3011,10 @@ func (config *Config) appendMemoryKnobs() { return } var objMemParam, numaMemParam string - dimmName := "dimm1" if config.Knobs.HugePages { objMemParam = "memory-backend-file,id=" + dimmName + ",size=" + config.Memory.Size + ",mem-path=/dev/hugepages" numaMemParam = "node,memdev=" + dimmName - } else if config.Knobs.MemFDPrivate { - objMemParam = "memory-backend-memfd-private,id=" + dimmName + ",size=" + config.Memory.Size } else if config.Knobs.FileBackedMem && config.Memory.Path != "" { objMemParam = "memory-backend-file,id=" + dimmName + ",size=" + config.Memory.Size + ",mem-path=" + config.Memory.Path numaMemParam = "node,memdev=" + dimmName @@ -3032,6 +3023,9 @@ func (config *Config) appendMemoryKnobs() { numaMemParam = "node,memdev=" + dimmName } + if config.Knobs.Private { + objMemParam += ",private=on" + } if config.Knobs.MemShared { objMemParam += ",share=on" } diff --git a/src/runtime/pkg/govmm/qemu/qemu_test.go b/src/runtime/pkg/govmm/qemu/qemu_test.go index e1cb2a2d1..3fcdbe0d6 100644 --- a/src/runtime/pkg/govmm/qemu/qemu_test.go +++ b/src/runtime/pkg/govmm/qemu/qemu_test.go @@ -586,6 +586,7 @@ func TestAppendMemoryFileBackedMem(t *testing.T) { knobs := Knobs{ FileBackedMem: true, MemShared: false, + Private: false, } objMemString := "-object memory-backend-file,id=dimm1,size=1G,mem-path=foobar" numaMemString := "-numa node,memdev=dimm1" @@ -599,6 +600,36 @@ func TestAppendMemoryFileBackedMem(t *testing.T) { } testConfigAppend(conf, knobs, memString+" "+knobsString, t) + + // Reset the conf and memString values + conf = &Config{ + Memory: Memory{ + Size: "1G", + Slots: 8, + MaxMem: "3G", + Path: "foobar", + }, + } + memString = "-m 1G,slots=8,maxmem=3G" + testConfigAppend(conf, conf.Memory, memString, t) + + knobs = Knobs{ + FileBackedMem: true, + MemShared: false, + Private: true, + } + objMemString = "-object memory-backend-file,id=dimm1,size=1G,mem-path=foobar,private=on" + numaMemString = "-numa node,memdev=dimm1" + memBackendString = "-machine memory-backend=dimm1" + + knobsString = objMemString + " " + if isDimmSupported(nil) { + knobsString += numaMemString + } else { + knobsString += memBackendString + } + + testConfigAppend(conf, knobs, memString+" "+knobsString, t) } func TestAppendMemoryFileBackedMemPrealloc(t *testing.T) { @@ -632,29 +663,6 @@ func TestAppendMemoryFileBackedMemPrealloc(t *testing.T) { testConfigAppend(conf, knobs, memString+" "+knobsString, t) } -func TestAppendMemoryBackedMemFdPrivate(t *testing.T) { - conf := &Config{ - Memory: Memory{ - Size: "1G", - Slots: 8, - }, - } - memString := "-m 1G,slots=8" - testConfigAppend(conf, conf.Memory, memString, t) - - knobs := Knobs{ - MemFDPrivate: true, - MemShared: false, - } - objMemString := "-object memory-backend-memfd-private,id=dimm1,size=1G" - memBackendString := "-machine memory-backend=dimm1" - - knobsString := objMemString + " " - knobsString += memBackendString - - testConfigAppend(conf, knobs, memString+" "+knobsString, t) -} - func TestNoRebootKnob(t *testing.T) { conf := &Config{} diff --git a/src/runtime/virtcontainers/hypervisor_linux_amd64.go b/src/runtime/virtcontainers/hypervisor_linux_amd64.go index 043b36c9f..ac8454016 100644 --- a/src/runtime/virtcontainers/hypervisor_linux_amd64.go +++ b/src/runtime/virtcontainers/hypervisor_linux_amd64.go @@ -8,39 +8,21 @@ package virtcontainers import "os" const ( - tdxSeamSysFirmwareDir = "/sys/firmware/tdx_seam/" - - tdxSysFirmwareDir = "/sys/firmware/tdx/" + tdxKvmParameterPath = "/sys/module/kvm_intel/parameters/tdx" sevKvmParameterPath = "/sys/module/kvm_amd/parameters/sev" snpKvmParameterPath = "/sys/module/kvm_amd/parameters/sev_snp" ) -// TDX is supported and properly loaded when the firmware directory (either tdx or tdx_seam) exists or `tdx` is part of the CPU flag -func checkTdxGuestProtection(flags map[string]bool) bool { - if d, err := os.Stat(tdxSysFirmwareDir); err == nil && d.IsDir() { - return true - } - - if d, err := os.Stat(tdxSeamSysFirmwareDir); err == nil && d.IsDir() { - return true - } - - return false -} - // Implementation of this function is architecture specific func availableGuestProtection() (guestProtection, error) { - flags, err := CPUFlags(procCPUInfo) - if err != nil { - return noneProtection, err + // TDX is supported and enabled when the kvm module 'tdx' parameter is set to 'Y' + if _, err := os.Stat(tdxKvmParameterPath); err == nil { + if c, err := os.ReadFile(tdxKvmParameterPath); err == nil && len(c) > 0 && (c[0] == 'Y') { + return tdxProtection, nil + } } - - if checkTdxGuestProtection(flags) { - return tdxProtection, nil - } - // SEV-SNP is supported and enabled when the kvm module `sev_snp` parameter is set to `Y` // SEV-SNP support infers SEV (-ES) support if _, err := os.Stat(snpKvmParameterPath); err == nil { diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 96b004533..e8a6e1511 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -620,22 +620,9 @@ func (q *qemu) CreateVM(ctx context.Context, id string, network Network, hypervi // on the hypervisor specific code, as availableGuestProtection() // has been called earlier and we know we have the value stored. if q.arch.getProtection() == tdxProtection { - knobs.MemFDPrivate = true - // In case Nydus or VirtioFS is used, which may become a reality - // in the future, whenever we get those hardened for TDX, those - // knobs below would be automatically set. Let's make sure we - // pre-emptively disable them, and with that we can avoid some - // headaches in the future. - knobs.FileBackedMem = false - knobs.MemShared = false - - // SMP is currently broken with TDX 1.5, and - // we must ensure we use something like: - // `...,sockets=1,cores=numvcpus,threads=1,...` - smp.Sockets = 1 - smp.Cores = q.config.NumVCPUs() - smp.Threads = 1 + // TDX relies on ",private=on" passed to the memory object. + knobs.Private = true } } diff --git a/tools/packaging/qemu/patches/tag_patches/tdx-qemu-next-2023.9.21-v8.1.0/no_patches.txt b/tools/packaging/qemu/patches/tag_patches/tdx-qemu-next-2023.9.21-v8.1.0/no_patches.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tools/packaging/static-build/ovmf/build-ovmf.sh b/tools/packaging/static-build/ovmf/build-ovmf.sh index c0e7d26e2..b87307458 100755 --- a/tools/packaging/static-build/ovmf/build-ovmf.sh +++ b/tools/packaging/static-build/ovmf/build-ovmf.sh @@ -56,7 +56,7 @@ fi info "Building ovmf" build_cmd="build -b ${build_target} -t ${toolchain} -a ${architecture} -p ${ovmf_package}" if [ "${ovmf_build}" == "tdx" ]; then - build_cmd+=" -D DEBUG_ON_SERIAL_PORT=FALSE -D TDX_MEM_PARTIAL_ACCEPT=512 -D TDX_EMULATION_ENABLE=FALSE -D SECURE_BOOT_ENABLE=TRUE -D TDX_ACCEPT_PAGE_SIZE=2M" + build_cmd+=" -D SECURE_BOOT_ENABLE=TRUE" fi eval "${build_cmd}" diff --git a/tools/packaging/static-build/qemu/Dockerfile b/tools/packaging/static-build/qemu/Dockerfile index 7ed1b8995..1c4fd45d1 100644 --- a/tools/packaging/static-build/qemu/Dockerfile +++ b/tools/packaging/static-build/qemu/Dockerfile @@ -58,8 +58,8 @@ RUN apt-get update && apt-get upgrade -y && \ libseccomp-dev${DPKG_ARCH} \ libseccomp2${DPKG_ARCH} \ patch \ - python \ - python-dev \ + python3 \ + python3-dev \ python3-venv \ rsync \ zlib1g-dev${DPKG_ARCH} && \ diff --git a/versions.yaml b/versions.yaml index 36b817bdd..bc3a77bc1 100644 --- a/versions.yaml +++ b/versions.yaml @@ -100,10 +100,9 @@ assets: .*/v?(\d\S+)\.tar\.gz qemu-tdx-experimental: - # yamllint disable-line rule:line-length - description: "QEMU with TDX support - based on https://github.com/intel/tdx-tools/releases/tag/2023ww15" - url: "https://github.com/kata-containers/qemu" - tag: "b67b00e6b4c7831a3f5bc684bc0df7a9bfd1bd56-plus-TDX-v1.10" + description: ¨QEMU with TDX support" + url: "https://github.com/intel/qemu-tdx" + tag: "tdx-qemu-next-2023.9.21-v8.1.0" qemu-snp-experimental: description: "QEMU with SNP support"