* [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP
@ 2025-03-11 15:04 Philipp Giersfeld
2025-03-11 15:04 ` [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP Philipp Giersfeld
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Philipp Giersfeld @ 2025-03-11 15:04 UTC (permalink / raw)
To: pve-devel
This patch series adds support for AMD SEV-SNP.
Where possible it mimics the existing support for AMD SEV(-ES).
Running SEV-SNP VMs requires a more recent version of edk2
and OVMF firmware image. Contrary to other setups, SEV-SNP does not
support loading the firmware via pflash. Instead, the firmware image is
loaded via the -bios option.
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 8+ messages in thread* [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP 2025-03-11 15:04 [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP Philipp Giersfeld @ 2025-03-11 15:04 ` Philipp Giersfeld 2025-03-18 9:40 ` Markus Frank 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 2/4] Convert policy calculation Philipp Giersfeld ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Philipp Giersfeld @ 2025-03-11 15:04 UTC (permalink / raw) To: pve-devel AMD SEV-SNP boots with a single volatile firmware image OVMF.fd via the -bios option. This requires building the `OvmfPkg/OvmfPkgX64.dsc` target. Also, SEV-ES and SEV-SNP do not support SMM [1,2]. Therefore, introduce a new target build-ovmf-cvm that builds OVMF firmware suitable for AMD SEV. [1] https://www.qemu.org/docs/master/system/i386/amd-memory-encryption. [2] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> Tested-by: Markus Frank <m.frank@proxmox.com> --- changes since v3: https://lists.proxmox.com/pipermail/pve-devel/2025-February/068578.html * Build SEV targets with secure boot support since edk2 has been updated debian/pve-edk2-firmware-ovmf.install | 3 +++ debian/rules | 28 +++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/debian/pve-edk2-firmware-ovmf.install b/debian/pve-edk2-firmware-ovmf.install index f4c0602..a51846e 100644 --- a/debian/pve-edk2-firmware-ovmf.install +++ b/debian/pve-edk2-firmware-ovmf.install @@ -1,5 +1,8 @@ debian/ovmf-install/OVMF_CODE*.fd /usr/share/pve-edk2-firmware debian/ovmf-install/OVMF_VARS*.fd /usr/share/pve-edk2-firmware +debian/ovmf-cvm-install/OVMF_CVM_CODE*.fd /usr/share/pve-edk2-firmware +debian/ovmf-cvm-install/OVMF_CVM_VARS*.fd /usr/share/pve-edk2-firmware +debian/ovmf-cvm-install/OVMF_CVM_4M.fd /usr/share/pve-edk2-firmware debian/ovmf32-install/OVMF32_CODE*.fd /usr/share/pve-edk2-firmware debian/ovmf32-install/OVMF32_VARS*.fd /usr/share/pve-edk2-firmware debian/PkKek-1-snakeoil.* /usr/share/pve-edk2-firmware diff --git a/debian/rules b/debian/rules index 2e9365b..c52d4fb 100755 --- a/debian/rules +++ b/debian/rules @@ -37,6 +37,7 @@ OVMF_4M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB OVMF_4M_SMM_FLAGS = $(OVMF_4M_FLAGS) -DSMM_REQUIRE=TRUE OVMF32_4M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB OVMF32_4M_SMM_FLAGS = $(OVMF32_4M_FLAGS) -DSMM_REQUIRE=TRUE +OVMF_CVM_4M_FLAGS = $(OVMF_4M_FLAGS) AAVMF_FLAGS = $(COMMON_FLAGS) AAVMF_FLAGS += -DTPM2_ENABLE=TRUE @@ -56,7 +57,7 @@ undefine CONF_PATH %: dh $@ -override_dh_auto_build: build-qemu-efi-aarch64 build-ovmf build-ovmf32 build-qemu-efi-riscv64 +override_dh_auto_build: build-qemu-efi-aarch64 build-ovmf build-ovmf32 build-ovmf-cvm build-qemu-efi-riscv64 debian/setup-build-stamp: cp -a debian/Logo.bmp MdeModulePkg/Logo/Logo.bmp @@ -79,6 +80,12 @@ OVMF32_SHELL = $(OVMF32_BUILD_DIR)/IA32/Shell.efi OVMF32_BINARIES = $(OVMF32_SHELL) OVMF32_IMAGES := $(addprefix $(OVMF32_INSTALL_DIR)/,OVMF32_CODE_4M.secboot.fd OVMF32_VARS_4M.fd) +OVMF_CVM_INSTALL_DIR = debian/ovmf-cvm-install +OVMF_CVM_BUILD_DIR = Build/OvmfX64/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) +OVMF_CVM_SHELL = $(OVMF_CVM_BUILD_DIR)/X64/Shell.efi +OVMF_CVM_BINARIES = $(OVMF_CVM_SHELL) +OVMF_CVM_IMAGES := $(addprefix $(OVMF_CVM_INSTALL_DIR)/,OVMF_CVM_CODE_4M.fd OVMF_CVM_VARS_4M.fd) + QEMU_EFI_BUILD_DIR = Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) AAVMF_BUILD_DIR = Build/ArmVirtQemu-AARCH64/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) AAVMF_ENROLL = $(AAVMF_BUILD_DIR)/AARCH64/EnrollDefaultKeys.efi @@ -106,6 +113,23 @@ $(OVMF32_BINARIES) $(OVMF32_IMAGES): debian/setup-build-stamp cp $(OVMF32_BUILD_DIR)/FV/OVMF_VARS.fd \ $(OVMF32_INSTALL_DIR)/OVMF32_VARS_4M.fd +build-ovmf-cvm: $(OVMF_CVM_BINARIES) $(OVMF_CVM_IMAGES) +$(OVMF_CVM_BINARIES) $(OVMF_CVM_IMAGES): debian/setup-build-stamp + rm -rf $(OVMF_CVM_INSTALL_DIR) + mkdir $(OVMF_CVM_INSTALL_DIR) + set -e; . ./edksetup.sh; \ + build -a X64 \ + -t $(EDK2_TOOLCHAIN) \ + -p OvmfPkg/OvmfPkgX64.dsc \ + $(OVMF_CVM_4M_FLAGS) -b $(BUILD_TYPE) + #-b $(BUILD_TYPE) + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF_CODE.fd \ + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_CODE_4M.fd + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF_VARS.fd \ + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_VARS_4M.fd + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF.fd \ + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_4M.fd + build-ovmf: $(OVMF_BINARIES) $(OVMF_IMAGES) $(OVMF_PREENROLLED_VARS) $(OVMF_BINARIES) $(OVMF_IMAGES): debian/setup-build-stamp rm -rf $(OVMF_INSTALL_DIR) @@ -250,4 +274,4 @@ get-orig-source: edk2-$(DEB_VERSION_UPSTREAM) rm -rf edk2.tmp edk2-$(DEB_VERSION_UPSTREAM) -.PHONY: build-ovmf build-ovmf32 build-qemu-efi build-qemu-efi-aarch64 build-qemu-efi-riscv64 +.PHONY: build-ovmf build-ovmf32 build-ovmf-cvm build-qemu-efi build-qemu-efi-aarch64 build-qemu-efi-riscv64 \ No newline at end of file -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP 2025-03-11 15:04 ` [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP Philipp Giersfeld @ 2025-03-18 9:40 ` Markus Frank 0 siblings, 0 replies; 8+ messages in thread From: Markus Frank @ 2025-03-18 9:40 UTC (permalink / raw) To: Philipp Giersfeld, pve-devel On 2025-03-11 16:04, Philipp Giersfeld wrote: > AMD SEV-SNP boots with a single volatile firmware image OVMF.fd via the > -bios option. > > This requires building the `OvmfPkg/OvmfPkgX64.dsc` target. > Also, SEV-ES and SEV-SNP do not support SMM [1,2]. > > Therefore, introduce a new target build-ovmf-cvm that builds OVMF > firmware suitable for AMD SEV. > > [1] https://www.qemu.org/docs/master/system/i386/amd-memory-encryption. > [2] https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf > > Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> > Tested-by: Markus Frank <m.frank@proxmox.com> I have not tested this version before (there have been some changes since v3/v2). But now I have. So the "Tested-by" can stay there. > --- > > changes since v3: https://lists.proxmox.com/pipermail/pve-devel/2025-February/068578.html > * Build SEV targets with secure boot support since edk2 has been > updated > > debian/pve-edk2-firmware-ovmf.install | 3 +++ > debian/rules | 28 +++++++++++++++++++++++++-- > 2 files changed, 29 insertions(+), 2 deletions(-) > > diff --git a/debian/pve-edk2-firmware-ovmf.install b/debian/pve-edk2-firmware-ovmf.install > index f4c0602..a51846e 100644 > --- a/debian/pve-edk2-firmware-ovmf.install > +++ b/debian/pve-edk2-firmware-ovmf.install > @@ -1,5 +1,8 @@ > debian/ovmf-install/OVMF_CODE*.fd /usr/share/pve-edk2-firmware > debian/ovmf-install/OVMF_VARS*.fd /usr/share/pve-edk2-firmware > +debian/ovmf-cvm-install/OVMF_CVM_CODE*.fd /usr/share/pve-edk2-firmware > +debian/ovmf-cvm-install/OVMF_CVM_VARS*.fd /usr/share/pve-edk2-firmware > +debian/ovmf-cvm-install/OVMF_CVM_4M.fd /usr/share/pve-edk2-firmware > debian/ovmf32-install/OVMF32_CODE*.fd /usr/share/pve-edk2-firmware > debian/ovmf32-install/OVMF32_VARS*.fd /usr/share/pve-edk2-firmware > debian/PkKek-1-snakeoil.* /usr/share/pve-edk2-firmware > diff --git a/debian/rules b/debian/rules > index 2e9365b..c52d4fb 100755 > --- a/debian/rules > +++ b/debian/rules > @@ -37,6 +37,7 @@ OVMF_4M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB > OVMF_4M_SMM_FLAGS = $(OVMF_4M_FLAGS) -DSMM_REQUIRE=TRUE > OVMF32_4M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB > OVMF32_4M_SMM_FLAGS = $(OVMF32_4M_FLAGS) -DSMM_REQUIRE=TRUE > +OVMF_CVM_4M_FLAGS = $(OVMF_4M_FLAGS) > > AAVMF_FLAGS = $(COMMON_FLAGS) > AAVMF_FLAGS += -DTPM2_ENABLE=TRUE > @@ -56,7 +57,7 @@ undefine CONF_PATH > %: > dh $@ > > -override_dh_auto_build: build-qemu-efi-aarch64 build-ovmf build-ovmf32 build-qemu-efi-riscv64 > +override_dh_auto_build: build-qemu-efi-aarch64 build-ovmf build-ovmf32 build-ovmf-cvm build-qemu-efi-riscv64 > > debian/setup-build-stamp: > cp -a debian/Logo.bmp MdeModulePkg/Logo/Logo.bmp > @@ -79,6 +80,12 @@ OVMF32_SHELL = $(OVMF32_BUILD_DIR)/IA32/Shell.efi > OVMF32_BINARIES = $(OVMF32_SHELL) > OVMF32_IMAGES := $(addprefix $(OVMF32_INSTALL_DIR)/,OVMF32_CODE_4M.secboot.fd OVMF32_VARS_4M.fd) > > +OVMF_CVM_INSTALL_DIR = debian/ovmf-cvm-install > +OVMF_CVM_BUILD_DIR = Build/OvmfX64/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) > +OVMF_CVM_SHELL = $(OVMF_CVM_BUILD_DIR)/X64/Shell.efi > +OVMF_CVM_BINARIES = $(OVMF_CVM_SHELL) > +OVMF_CVM_IMAGES := $(addprefix $(OVMF_CVM_INSTALL_DIR)/,OVMF_CVM_CODE_4M.fd OVMF_CVM_VARS_4M.fd) > + > QEMU_EFI_BUILD_DIR = Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) > AAVMF_BUILD_DIR = Build/ArmVirtQemu-AARCH64/$(BUILD_TYPE)_$(EDK2_TOOLCHAIN) > AAVMF_ENROLL = $(AAVMF_BUILD_DIR)/AARCH64/EnrollDefaultKeys.efi > @@ -106,6 +113,23 @@ $(OVMF32_BINARIES) $(OVMF32_IMAGES): debian/setup-build-stamp > cp $(OVMF32_BUILD_DIR)/FV/OVMF_VARS.fd \ > $(OVMF32_INSTALL_DIR)/OVMF32_VARS_4M.fd > > +build-ovmf-cvm: $(OVMF_CVM_BINARIES) $(OVMF_CVM_IMAGES) > +$(OVMF_CVM_BINARIES) $(OVMF_CVM_IMAGES): debian/setup-build-stamp > + rm -rf $(OVMF_CVM_INSTALL_DIR) > + mkdir $(OVMF_CVM_INSTALL_DIR) > + set -e; . ./edksetup.sh; \ > + build -a X64 \ > + -t $(EDK2_TOOLCHAIN) \ > + -p OvmfPkg/OvmfPkgX64.dsc \ > + $(OVMF_CVM_4M_FLAGS) -b $(BUILD_TYPE) > + #-b $(BUILD_TYPE) > + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF_CODE.fd \ > + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_CODE_4M.fd > + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF_VARS.fd \ > + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_VARS_4M.fd > + cp $(OVMF_CVM_BUILD_DIR)/FV/OVMF.fd \ > + $(OVMF_CVM_INSTALL_DIR)/OVMF_CVM_4M.fd > + > build-ovmf: $(OVMF_BINARIES) $(OVMF_IMAGES) $(OVMF_PREENROLLED_VARS) > $(OVMF_BINARIES) $(OVMF_IMAGES): debian/setup-build-stamp > rm -rf $(OVMF_INSTALL_DIR) > @@ -250,4 +274,4 @@ get-orig-source: > edk2-$(DEB_VERSION_UPSTREAM) > rm -rf edk2.tmp edk2-$(DEB_VERSION_UPSTREAM) > > -.PHONY: build-ovmf build-ovmf32 build-qemu-efi build-qemu-efi-aarch64 build-qemu-efi-riscv64 > +.PHONY: build-ovmf build-ovmf32 build-ovmf-cvm build-qemu-efi build-qemu-efi-aarch64 build-qemu-efi-riscv64 > \ No newline at end of file _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* [pve-devel] [PATCH qemu-server v4 2/4] Convert policy calculation 2025-03-11 15:04 [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP Philipp Giersfeld @ 2025-03-11 15:04 ` Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP Philipp Giersfeld 3 siblings, 0 replies; 8+ messages in thread From: Philipp Giersfeld @ 2025-03-11 15:04 UTC (permalink / raw) To: pve-devel Convert policy calculation to use shift operators and OR operation instead of binary numbers and addition. Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> Reviewed-by: Daniel Kral <d.kral@proxmox.com> Reviewed-by: Fiona Ebner <f.ebner@proxmox.com> Tested-by: Markus Frank <m.frank@proxmox.com> --- changes since v3: https://lists.proxmox.com/pipermail/pve-devel/2025-February/068578.html * Fix typo in commit description PVE/QemuServer/CPUConfig.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm index e65d8c26..ad0be16e 100644 --- a/PVE/QemuServer/CPUConfig.pm +++ b/PVE/QemuServer/CPUConfig.pm @@ -846,12 +846,12 @@ sub get_amd_sev_object { # guest policy bit calculation as described here: # https://documentation.suse.com/sles/15-SP5/html/SLES-amd-sev/article-amd-sev.html#table-guestpolicy - my $policy = 0b0000; - $policy += 0b0001 if $amd_sev_conf->{'no-debug'}; - $policy += 0b0010 if $amd_sev_conf->{'no-key-sharing'}; - $policy += 0b0100 if $amd_sev_conf->{type} eq 'es'; + my $policy = 0; + $policy |= 1 << 0 if $amd_sev_conf->{'no-debug'}; + $policy |= 1 << 1 if $amd_sev_conf->{'no-key-sharing'}; + $policy |= 1 << 2 if $amd_sev_conf->{type} eq 'es'; # disable migration with bit 3 nosend to prevent amd-sev-migration-attack - $policy += 0b1000; + $policy |= 1 << 3; $sev_mem_object .= ',policy='.sprintf("%#x", $policy); $sev_mem_object .= ',kernel-hashes=on' if ($amd_sev_conf->{'kernel-hashes'}); -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support. 2025-03-11 15:04 [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 2/4] Convert policy calculation Philipp Giersfeld @ 2025-03-11 15:04 ` Philipp Giersfeld 2025-03-18 9:41 ` Markus Frank 2025-03-11 15:04 ` [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP Philipp Giersfeld 3 siblings, 1 reply; 8+ messages in thread From: Philipp Giersfeld @ 2025-03-11 15:04 UTC (permalink / raw) To: pve-devel This patch is for enabling AMD SEV-SNP support. Where applicable, it extends support for existing SEV(-ES) variables to SEV-SNP. This means that it retains no-debug and kernel-hashes options, but the no-key-sharing option is removed. The default policy value is identical to QEMU’s, and the therefore required option has been added to configure SMT support. The code was tested by running a VM without SEV, with SEV, SEV-ES, SEV-SNP. Each configuration was tested with and without an EFI disk attached. For SEV-enabled configurations it was also verified that the kernel actually used the respective feature. Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> Reviewed-by: Daniel Kral <d.kral@proxmox.com> Tested-by: Markus Frank <m.frank@proxmox.com> --- changes since v3: https://lists.proxmox.com/pipermail/pve-devel/2025-February/068578.html * Add and clarify logging statements and descriptions * Add additional safeguards PVE/API2/Qemu.pm | 7 +++- PVE/QemuServer.pm | 52 +++++++++++++++++++++-------- PVE/QemuServer/CPUConfig.pm | 66 ++++++++++++++++++++++++++++--------- 3 files changed, 95 insertions(+), 30 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 295260e7..ef3aa8d6 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -548,8 +548,13 @@ my sub create_disks : prototype($$$$$$$$$$$) { my $volid; if ($ds eq 'efidisk0') { my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf); + + my $amd_sev_type = PVE::QemuServer::CPUConfig::get_amd_sev_type($conf); + die "SEV-SNP uses consolidated read-only firmware and does not require an EFI disk\n" + if $amd_sev_type && $amd_sev_type eq 'snp'; + ($volid, $size) = PVE::QemuServer::create_efidisk( - $storecfg, $storeid, $vmid, $fmt, $arch, $disk, $smm); + $storecfg, $storeid, $vmid, $fmt, $arch, $disk, $smm, $amd_sev_type); } elsif ($ds eq 'tpmstate0') { # swtpm can only use raw volumes, and uses a fixed size $size = PVE::Tools::convert_size(PVE::QemuServer::Drive::TPMSTATE_DISK_SIZE, 'b' => 'kb'); diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 808c0e1c..727aad6c 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -52,7 +52,7 @@ use PVE::QemuConfig; use PVE::QemuServer::Helpers qw(config_aware_timeout min_version kvm_user_version windows_version); use PVE::QemuServer::Cloudinit; use PVE::QemuServer::CGroup; -use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object); +use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object get_amd_sev_type); use PVE::QemuServer::Drive qw(is_valid_drivename checked_volume_format drive_is_cloudinit drive_is_cdrom drive_is_read_only parse_drive print_drive); use PVE::QemuServer::Machine; use PVE::QemuServer::Memory qw(get_current_memory); @@ -88,6 +88,13 @@ my $OVMF = { "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd", ], + '4m-sev' => [ + "$EDK2_FW_BASE/OVMF_CVM_CODE_4M.fd", + "$EDK2_FW_BASE/OVMF_CVM_VARS_4M.fd", + ], + '4m-snp' => [ + "$EDK2_FW_BASE/OVMF_CVM_4M.fd", + ], # FIXME: These are legacy 2MB-sized images that modern OVMF doesn't supports to build # anymore. how can we deperacate this sanely without breaking existing instances, or using # older backups and snapshot? @@ -3172,15 +3179,22 @@ sub vga_conf_has_spice { return $1 || 1; } -sub get_ovmf_files($$$) { - my ($arch, $efidisk, $smm) = @_; +sub get_ovmf_files($$$$) { + my ($arch, $efidisk, $smm, $amd_sev_type) = @_; my $types = $OVMF->{$arch} or die "no OVMF images known for architecture '$arch'\n"; my $type = 'default'; if ($arch eq 'x86_64') { - if (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') { + if ($amd_sev_type && $amd_sev_type eq 'snp') { + $type = "4m-snp"; + my ($ovmf) = $types->{$type}->@*; + die "EFI base image '$ovmf' not found\n" if ! -f $ovmf; + return ($ovmf); + } elsif ($amd_sev_type) { + $type = "4m-sev"; + } elsif (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') { $type = $smm ? "4m" : "4m-no-smm"; $type .= '-ms' if $efidisk->{'pre-enrolled-keys'}; } else { @@ -3329,7 +3343,10 @@ my sub print_ovmf_drive_commandlines { my $d = $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef; - my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35); + my $amd_sev_type = get_amd_sev_type($conf); + die "Attempting to configure SEV-SNP with flash devices instead of using `-bios`\n" + if $amd_sev_type && $amd_sev_type eq 'snp'; + my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35, $amd_sev_type); my $var_drive_str = "if=pflash,unit=1,id=drive-efidisk0"; if ($d) { @@ -3526,10 +3543,18 @@ sub config_to_command { die "OVMF (UEFI) BIOS is not supported on 32-bit CPU types\n" if !$forcecpu && get_cpu_bitness($conf->{cpu}, $arch) == 32; - my ($code_drive_str, $var_drive_str) = - print_ovmf_drive_commandlines($conf, $storecfg, $vmid, $arch, $q35, $version_guard); - push $cmd->@*, '-drive', $code_drive_str; - push $cmd->@*, '-drive', $var_drive_str; + my $amd_sev_type = get_amd_sev_type($conf); + if ($amd_sev_type && $amd_sev_type eq 'snp') { + my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf); + print "Existing EFI disk will be ignored for SEV-SNP\n" + if parse_drive('efidisk0', $conf->{efidisk0}); + push $cmd->@*, '-bios', get_ovmf_files($arch, undef, undef, $amd_sev_type); + } else { + my ($code_drive_str, $var_drive_str) = print_ovmf_drive_commandlines( + $conf, $storecfg, $vmid, $arch, $q35, $version_guard); + push $cmd->@*, '-drive', $code_drive_str; + push $cmd->@*, '-drive', $var_drive_str; + } } if ($q35) { # tell QEMU to load q35 config early @@ -8337,7 +8362,8 @@ sub get_efivars_size { my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf); $efidisk //= $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef; my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf); - my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm); + my $amd_sev_type = get_amd_sev_type($conf); + my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type); return -s $ovmf_vars; } @@ -8361,10 +8387,10 @@ sub update_tpmstate_size { $conf->{tpmstate0} = print_drive($disk); } -sub create_efidisk($$$$$$$) { - my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm) = @_; +sub create_efidisk($$$$$$$$) { + my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm, $amd_sev_type) = @_; - my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm); + my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type); my $vars_size_b = -s $ovmf_vars; my $vars_size = PVE::Tools::convert_size($vars_size_b, 'b' => 'kb'); diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm index ad0be16e..9ae1996b 100644 --- a/PVE/QemuServer/CPUConfig.pm +++ b/PVE/QemuServer/CPUConfig.pm @@ -18,6 +18,7 @@ get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object +get_amd_sev_type ); # under certain race-conditions, this module might be loaded before pve-cluster @@ -231,25 +232,32 @@ my $cpu_fmt = { my $sev_fmt = { type => { description => "Enable standard SEV with type='std' or enable" - ." experimental SEV-ES with the 'es' option.", + ." experimental SEV-ES with the 'es' option or enable" + ." experimental SEV-SNP with the 'snp' option.", type => 'string', default_key => 1, format_description => "sev-type", - enum => ['std', 'es'], + enum => ['std', 'es', 'snp'], maxLength => 3, }, 'no-debug' => { - description => "Sets policy bit 0 to 1 to disallow debugging of guest", + description => "Sets policy bit to disallow debugging of guest", type => 'boolean', default => 0, optional => 1, }, 'no-key-sharing' => { - description => "Sets policy bit 1 to 1 to disallow key sharing with other guests", + description => "Sets policy bit to disallow key sharing with other guests (Ignored for SEV-SNP)", type => 'boolean', default => 0, optional => 1, }, + 'allow-smt' => { + description => "Sets policy bit to allow Simultaneous Multi Threading (SMT) (Ignored unless for SEV-SNP)", + type => 'boolean', + default => 1, + optional => 1, + }, "kernel-hashes" => { description => "Add kernel hashes to guest firmware for measured linux kernel launch", type => 'boolean', @@ -823,6 +831,13 @@ sub get_hw_capabilities { } return $hw_capabilities; } +sub get_amd_sev_type { + my ($conf) = @_; + + return undef if !$conf->{'amd-sev'}; + + return PVE::JSONSchema::parse_property_string($sev_fmt, $conf->{'amd-sev'})->{type}; +} sub get_amd_sev_object { my ($amd_sev, $bios) = @_; @@ -836,22 +851,41 @@ sub get_amd_sev_object { if ($amd_sev_conf->{type} eq 'es' && !$sev_hw_caps->{'sev-support-es'}) { die "Your CPU does not support AMD SEV-ES.\n"; } + if ($amd_sev_conf->{type} eq 'snp' && !$sev_hw_caps->{'sev-support-snp'}) { + die "Your CPU does not support AMD SEV-SNP.\n"; + } if (!$bios || $bios ne 'ovmf') { die "To use AMD SEV, you need to change the BIOS to OVMF.\n"; } - my $sev_mem_object = 'sev-guest,id=sev0'; - $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; - $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; - - # guest policy bit calculation as described here: - # https://documentation.suse.com/sles/15-SP5/html/SLES-amd-sev/article-amd-sev.html#table-guestpolicy - my $policy = 0; - $policy |= 1 << 0 if $amd_sev_conf->{'no-debug'}; - $policy |= 1 << 1 if $amd_sev_conf->{'no-key-sharing'}; - $policy |= 1 << 2 if $amd_sev_conf->{type} eq 'es'; - # disable migration with bit 3 nosend to prevent amd-sev-migration-attack - $policy |= 1 << 3; + my $sev_mem_object = ''; + my $policy; + if ($amd_sev_conf->{type} eq 'es' || $amd_sev_conf->{type} eq 'std') { + $sev_mem_object .= 'sev-guest,id=sev0'; + $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; + $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; + + # guest policy bit calculation as described here: + # https://documentation.suse.com/sles/15-SP5/html/SLES-amd-sev/article-amd-sev.html#table-guestpolicy + $policy = 0; + $policy |= 1 << 0 if $amd_sev_conf->{'no-debug'}; + $policy |= 1 << 1 if $amd_sev_conf->{'no-key-sharing'}; + $policy |= 1 << 2 if $amd_sev_conf->{type} eq 'es'; + # disable migration with bit 3 nosend to prevent amd-sev-migration-attack + $policy |= 1 << 3; + } elsif ($amd_sev_conf->{type} eq 'snp') { + $sev_mem_object .= 'sev-snp-guest,id=sev0'; + $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; + $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; + + # guest policy bit calculation as described in chapter 4.3: + # https://www.amd.com/system/files/TechDocs/56860.pdf + # Reserved bit must be one + $policy = 1 << 17; + $policy |= 1 << 16 if !defined($amd_sev_conf->{'allow-smt'}) || $amd_sev_conf->{'allow-smt'}; + $policy |= 1 << 19 if !$amd_sev_conf->{'no-debug'}; + } + $sev_mem_object .= ',policy='.sprintf("%#x", $policy); $sev_mem_object .= ',kernel-hashes=on' if ($amd_sev_conf->{'kernel-hashes'}); -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support. 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support Philipp Giersfeld @ 2025-03-18 9:41 ` Markus Frank 0 siblings, 0 replies; 8+ messages in thread From: Markus Frank @ 2025-03-18 9:41 UTC (permalink / raw) To: Philipp Giersfeld, pve-devel On 2025-03-11 16:04, Philipp Giersfeld wrote: > This patch is for enabling AMD SEV-SNP support. > > Where applicable, it extends support for existing SEV(-ES) variables > to SEV-SNP. This means that it retains no-debug and kernel-hashes > options, but the no-key-sharing option is removed. > > The default policy value is identical to QEMU’s, and the therefore > required option has been added to configure SMT support. > > The code was tested by running a VM without SEV, with SEV, SEV-ES, > SEV-SNP. Each configuration was tested with and without an EFI disk > attached. For SEV-enabled configurations it was also verified that the > kernel actually used the respective feature. > > Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> > Reviewed-by: Daniel Kral <d.kral@proxmox.com> > Tested-by: Markus Frank <m.frank@proxmox.com> I have not tested this version before (there have been some changes since v3/v2). But now I have. So the "Tested-by" can stay there. > --- > > changes since v3: https://lists.proxmox.com/pipermail/pve-devel/2025-February/068578.html > * Add and clarify logging statements and descriptions > * Add additional safeguards > > PVE/API2/Qemu.pm | 7 +++- > PVE/QemuServer.pm | 52 +++++++++++++++++++++-------- > PVE/QemuServer/CPUConfig.pm | 66 ++++++++++++++++++++++++++++--------- > 3 files changed, 95 insertions(+), 30 deletions(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 295260e7..ef3aa8d6 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -548,8 +548,13 @@ my sub create_disks : prototype($$$$$$$$$$$) { > my $volid; > if ($ds eq 'efidisk0') { > my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf); > + > + my $amd_sev_type = PVE::QemuServer::CPUConfig::get_amd_sev_type($conf); > + die "SEV-SNP uses consolidated read-only firmware and does not require an EFI disk\n" > + if $amd_sev_type && $amd_sev_type eq 'snp'; > + > ($volid, $size) = PVE::QemuServer::create_efidisk( > - $storecfg, $storeid, $vmid, $fmt, $arch, $disk, $smm); > + $storecfg, $storeid, $vmid, $fmt, $arch, $disk, $smm, $amd_sev_type); > } elsif ($ds eq 'tpmstate0') { > # swtpm can only use raw volumes, and uses a fixed size > $size = PVE::Tools::convert_size(PVE::QemuServer::Drive::TPMSTATE_DISK_SIZE, 'b' => 'kb'); > diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm > index 808c0e1c..727aad6c 100644 > --- a/PVE/QemuServer.pm > +++ b/PVE/QemuServer.pm > @@ -52,7 +52,7 @@ use PVE::QemuConfig; > use PVE::QemuServer::Helpers qw(config_aware_timeout min_version kvm_user_version windows_version); > use PVE::QemuServer::Cloudinit; > use PVE::QemuServer::CGroup; > -use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object); > +use PVE::QemuServer::CPUConfig qw(print_cpu_device get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object get_amd_sev_type); > use PVE::QemuServer::Drive qw(is_valid_drivename checked_volume_format drive_is_cloudinit drive_is_cdrom drive_is_read_only parse_drive print_drive); > use PVE::QemuServer::Machine; > use PVE::QemuServer::Memory qw(get_current_memory); > @@ -88,6 +88,13 @@ my $OVMF = { > "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", > "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd", > ], > + '4m-sev' => [ > + "$EDK2_FW_BASE/OVMF_CVM_CODE_4M.fd", > + "$EDK2_FW_BASE/OVMF_CVM_VARS_4M.fd", > + ], > + '4m-snp' => [ > + "$EDK2_FW_BASE/OVMF_CVM_4M.fd", > + ], > # FIXME: These are legacy 2MB-sized images that modern OVMF doesn't supports to build > # anymore. how can we deperacate this sanely without breaking existing instances, or using > # older backups and snapshot? > @@ -3172,15 +3179,22 @@ sub vga_conf_has_spice { > return $1 || 1; > } > > -sub get_ovmf_files($$$) { > - my ($arch, $efidisk, $smm) = @_; > +sub get_ovmf_files($$$$) { > + my ($arch, $efidisk, $smm, $amd_sev_type) = @_; > > my $types = $OVMF->{$arch} > or die "no OVMF images known for architecture '$arch'\n"; > > my $type = 'default'; > if ($arch eq 'x86_64') { > - if (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') { > + if ($amd_sev_type && $amd_sev_type eq 'snp') { > + $type = "4m-snp"; > + my ($ovmf) = $types->{$type}->@*; > + die "EFI base image '$ovmf' not found\n" if ! -f $ovmf; > + return ($ovmf); > + } elsif ($amd_sev_type) { > + $type = "4m-sev"; > + } elsif (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') { > $type = $smm ? "4m" : "4m-no-smm"; > $type .= '-ms' if $efidisk->{'pre-enrolled-keys'}; > } else { > @@ -3329,7 +3343,10 @@ my sub print_ovmf_drive_commandlines { > > my $d = $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef; > > - my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35); > + my $amd_sev_type = get_amd_sev_type($conf); > + die "Attempting to configure SEV-SNP with flash devices instead of using `-bios`\n" > + if $amd_sev_type && $amd_sev_type eq 'snp'; > + my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35, $amd_sev_type); > > my $var_drive_str = "if=pflash,unit=1,id=drive-efidisk0"; > if ($d) { > @@ -3526,10 +3543,18 @@ sub config_to_command { > die "OVMF (UEFI) BIOS is not supported on 32-bit CPU types\n" > if !$forcecpu && get_cpu_bitness($conf->{cpu}, $arch) == 32; > > - my ($code_drive_str, $var_drive_str) = > - print_ovmf_drive_commandlines($conf, $storecfg, $vmid, $arch, $q35, $version_guard); > - push $cmd->@*, '-drive', $code_drive_str; > - push $cmd->@*, '-drive', $var_drive_str; > + my $amd_sev_type = get_amd_sev_type($conf); > + if ($amd_sev_type && $amd_sev_type eq 'snp') { > + my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf); > + print "Existing EFI disk will be ignored for SEV-SNP\n" > + if parse_drive('efidisk0', $conf->{efidisk0}); > + push $cmd->@*, '-bios', get_ovmf_files($arch, undef, undef, $amd_sev_type); > + } else { > + my ($code_drive_str, $var_drive_str) = print_ovmf_drive_commandlines( > + $conf, $storecfg, $vmid, $arch, $q35, $version_guard); > + push $cmd->@*, '-drive', $code_drive_str; > + push $cmd->@*, '-drive', $var_drive_str; > + } > } > > if ($q35) { # tell QEMU to load q35 config early > @@ -8337,7 +8362,8 @@ sub get_efivars_size { > my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf); > $efidisk //= $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef; > my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf); > - my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm); > + my $amd_sev_type = get_amd_sev_type($conf); > + my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type); > return -s $ovmf_vars; > } > > @@ -8361,10 +8387,10 @@ sub update_tpmstate_size { > $conf->{tpmstate0} = print_drive($disk); > } > > -sub create_efidisk($$$$$$$) { > - my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm) = @_; > +sub create_efidisk($$$$$$$$) { > + my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm, $amd_sev_type) = @_; > > - my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm); > + my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type); > > my $vars_size_b = -s $ovmf_vars; > my $vars_size = PVE::Tools::convert_size($vars_size_b, 'b' => 'kb'); > diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm > index ad0be16e..9ae1996b 100644 > --- a/PVE/QemuServer/CPUConfig.pm > +++ b/PVE/QemuServer/CPUConfig.pm > @@ -18,6 +18,7 @@ get_cpu_options > get_cpu_bitness > is_native_arch > get_amd_sev_object > +get_amd_sev_type > ); > > # under certain race-conditions, this module might be loaded before pve-cluster > @@ -231,25 +232,32 @@ my $cpu_fmt = { > my $sev_fmt = { > type => { > description => "Enable standard SEV with type='std' or enable" > - ." experimental SEV-ES with the 'es' option.", > + ." experimental SEV-ES with the 'es' option or enable" > + ." experimental SEV-SNP with the 'snp' option.", > type => 'string', > default_key => 1, > format_description => "sev-type", > - enum => ['std', 'es'], > + enum => ['std', 'es', 'snp'], > maxLength => 3, > }, > 'no-debug' => { > - description => "Sets policy bit 0 to 1 to disallow debugging of guest", > + description => "Sets policy bit to disallow debugging of guest", > type => 'boolean', > default => 0, > optional => 1, > }, > 'no-key-sharing' => { > - description => "Sets policy bit 1 to 1 to disallow key sharing with other guests", > + description => "Sets policy bit to disallow key sharing with other guests (Ignored for SEV-SNP)", > type => 'boolean', > default => 0, > optional => 1, > }, > + 'allow-smt' => { > + description => "Sets policy bit to allow Simultaneous Multi Threading (SMT) (Ignored unless for SEV-SNP)", > + type => 'boolean', > + default => 1, > + optional => 1, > + }, > "kernel-hashes" => { > description => "Add kernel hashes to guest firmware for measured linux kernel launch", > type => 'boolean', > @@ -823,6 +831,13 @@ sub get_hw_capabilities { > } > return $hw_capabilities; > } > +sub get_amd_sev_type { > + my ($conf) = @_; > + > + return undef if !$conf->{'amd-sev'}; > + > + return PVE::JSONSchema::parse_property_string($sev_fmt, $conf->{'amd-sev'})->{type}; > +} > > sub get_amd_sev_object { > my ($amd_sev, $bios) = @_; > @@ -836,22 +851,41 @@ sub get_amd_sev_object { > if ($amd_sev_conf->{type} eq 'es' && !$sev_hw_caps->{'sev-support-es'}) { > die "Your CPU does not support AMD SEV-ES.\n"; > } > + if ($amd_sev_conf->{type} eq 'snp' && !$sev_hw_caps->{'sev-support-snp'}) { > + die "Your CPU does not support AMD SEV-SNP.\n"; > + } > if (!$bios || $bios ne 'ovmf') { > die "To use AMD SEV, you need to change the BIOS to OVMF.\n"; > } > > - my $sev_mem_object = 'sev-guest,id=sev0'; > - $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; > - $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; > - > - # guest policy bit calculation as described here: > - # https://documentation.suse.com/sles/15-SP5/html/SLES-amd-sev/article-amd-sev.html#table-guestpolicy > - my $policy = 0; > - $policy |= 1 << 0 if $amd_sev_conf->{'no-debug'}; > - $policy |= 1 << 1 if $amd_sev_conf->{'no-key-sharing'}; > - $policy |= 1 << 2 if $amd_sev_conf->{type} eq 'es'; > - # disable migration with bit 3 nosend to prevent amd-sev-migration-attack > - $policy |= 1 << 3; > + my $sev_mem_object = ''; > + my $policy; > + if ($amd_sev_conf->{type} eq 'es' || $amd_sev_conf->{type} eq 'std') { > + $sev_mem_object .= 'sev-guest,id=sev0'; > + $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; > + $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; > + > + # guest policy bit calculation as described here: > + # https://documentation.suse.com/sles/15-SP5/html/SLES-amd-sev/article-amd-sev.html#table-guestpolicy > + $policy = 0; > + $policy |= 1 << 0 if $amd_sev_conf->{'no-debug'}; > + $policy |= 1 << 1 if $amd_sev_conf->{'no-key-sharing'}; > + $policy |= 1 << 2 if $amd_sev_conf->{type} eq 'es'; > + # disable migration with bit 3 nosend to prevent amd-sev-migration-attack > + $policy |= 1 << 3; > + } elsif ($amd_sev_conf->{type} eq 'snp') { > + $sev_mem_object .= 'sev-snp-guest,id=sev0'; > + $sev_mem_object .= ',cbitpos='.$sev_hw_caps->{cbitpos}; > + $sev_mem_object .= ',reduced-phys-bits='.$sev_hw_caps->{'reduced-phys-bits'}; > + > + # guest policy bit calculation as described in chapter 4.3: > + # https://www.amd.com/system/files/TechDocs/56860.pdf > + # Reserved bit must be one > + $policy = 1 << 17; > + $policy |= 1 << 16 if !defined($amd_sev_conf->{'allow-smt'}) || $amd_sev_conf->{'allow-smt'}; > + $policy |= 1 << 19 if !$amd_sev_conf->{'no-debug'}; > + } > + > > $sev_mem_object .= ',policy='.sprintf("%#x", $policy); > $sev_mem_object .= ',kernel-hashes=on' if ($amd_sev_conf->{'kernel-hashes'}); _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP 2025-03-11 15:04 [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP Philipp Giersfeld ` (2 preceding siblings ...) 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support Philipp Giersfeld @ 2025-03-11 15:04 ` Philipp Giersfeld 2025-03-17 10:13 ` Markus Frank 3 siblings, 1 reply; 8+ messages in thread From: Philipp Giersfeld @ 2025-03-11 15:04 UTC (permalink / raw) To: pve-devel Expand input panel with AMD SEV-SNP selection, and relevant optional parameters similar to existing options for AMD SEV(-ES). Further, upon selecting AMD SEV-SNP, issue a warning that EFI disks are not included when using SEV-SNP. Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> Reviewed-by: Daniel Kral <d.kral@proxmox.com> --- no changes since last version www/manager6/qemu/Options.js | 1 + www/manager6/qemu/SevEdit.js | 46 ++++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/www/manager6/qemu/Options.js b/www/manager6/qemu/Options.js index cbe9e52b..49a921cd 100644 --- a/www/manager6/qemu/Options.js +++ b/www/manager6/qemu/Options.js @@ -346,6 +346,7 @@ Ext.define('PVE.qemu.Options', { let amd_sev = PVE.Parser.parsePropertyString(value, "type"); if (amd_sev.type === 'std') return 'AMD SEV (' + value + ')'; if (amd_sev.type === 'es') return 'AMD SEV-ES (' + value + ')'; + if (amd_sev.type === 'snp') return 'AMD SEV-SNP (' + value + ')'; return value; }, }, diff --git a/www/manager6/qemu/SevEdit.js b/www/manager6/qemu/SevEdit.js index a2080f2d..3e0d0cbb 100644 --- a/www/manager6/qemu/SevEdit.js +++ b/www/manager6/qemu/SevEdit.js @@ -9,7 +9,8 @@ Ext.define('PVE.qemu.SevInputPanel', { type: '__default__', }, formulas: { - sevEnabled: get => get('type') !== '__default__', + sevEnabled: get => get('type') === 'std' || get('type') === 'es' || get('type') === 'snp', + snpEnabled: get => get('type') === 'snp', }, }, @@ -21,10 +22,14 @@ Ext.define('PVE.qemu.SevInputPanel', { if (!values.debug) { values["no-debug"] = 1; } - if (!values["key-sharing"]) { + if (values.smt) { + values["allow-smt"] = 1; + } + if (!values["key-sharing"] && values.type !== 'snp') { values["no-key-sharing"] = 1; } delete values.debug; + delete values.smt; delete values["key-sharing"]; let ret = {}; ret['amd-sev'] = PVE.Parser.printPropertyString(values, 'type'); @@ -36,13 +41,16 @@ Ext.define('PVE.qemu.SevInputPanel', { if (PVE.Parser.parseBoolean(values["no-debug"])) { values.debug = 0; } + if (PVE.Parser.parseBoolean(values["allow-smt"])) { + values.smt = 1; + } if (PVE.Parser.parseBoolean(values["no-key-sharing"])) { values["key-sharing"] = 0; } this.callParent(arguments); }, - items: { + items: [{ xtype: 'proxmoxKVComboBox', fieldLabel: gettext('AMD SEV Type'), labelWidth: 150, @@ -52,11 +60,28 @@ Ext.define('PVE.qemu.SevInputPanel', { ['__default__', Proxmox.Utils.defaultText + ' (' + Proxmox.Utils.disabledText + ')'], ['std', 'AMD SEV'], ['es', 'AMD SEV-ES (highly experimental)'], + ['snp', 'AMD SEV-SNP (highly experimental)'], ], bind: { value: '{type}', }, }, + { + xtype: 'displayfield', + userCls: 'pmx-hint', + value: gettext('WARNING: When using SEV-SNP no EFI disk is loaded as pflash.'), + bind: { + hidden: '{!snpEnabled}', + }, + }, + { + xtype: 'displayfield', + userCls: 'pmx-hint', + value: gettext('Note: SEV-SNP requires host kernel version 6.11 or higher.'), + bind: { + hidden: '{!snpEnabled}', + }, + }], advancedItems: [ { @@ -77,8 +102,19 @@ Ext.define('PVE.qemu.SevInputPanel', { name: 'key-sharing', value: 1, bind: { - hidden: '{!sevEnabled}', - disabled: '{!sevEnabled}', + hidden: '{!sevEnabled || snpEnabled}', + disabled: '{!sevEnabled || snpEnabled}', + }, + }, + { + xtype: 'proxmoxcheckbox', + fieldLabel: gettext('Allow SMT'), + labelWidth: 150, + name: 'smt', + value: 1, + bind: { + hidden: '{!snpEnabled}', + disabled: '{!snpEnabled}', }, }, { -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP 2025-03-11 15:04 ` [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP Philipp Giersfeld @ 2025-03-17 10:13 ` Markus Frank 0 siblings, 0 replies; 8+ messages in thread From: Markus Frank @ 2025-03-17 10:13 UTC (permalink / raw) To: Proxmox VE development discussion, Philipp Giersfeld Hello, I noticed that currently I cannot disable 'allow-smt' in the WebUI. The default value for allow-smt in qemu-server is '1'. So setting it to 1 or no value in the WebUI results in allow-smt always being enabled. To fix this, you can explicitly set allow-smt to 0 when the checkbox is not checked. Also, currently if I uncheck the allow-smt checkbox, save it to config and then reopen the window, the 'Allow SMT' checkbox is checked again. See my suggested fixes inline: On 2025-03-11 16:04, Philipp Giersfeld wrote: > Expand input panel with AMD SEV-SNP selection, and relevant optional > parameters similar to existing options for AMD SEV(-ES). > > Further, upon selecting AMD SEV-SNP, issue a warning that EFI disks are > not included when using SEV-SNP. > > Signed-off-by: Philipp Giersfeld <philipp.giersfeld@canarybit.eu> > Reviewed-by: Daniel Kral <d.kral@proxmox.com> > --- > > no changes since last version > > www/manager6/qemu/Options.js | 1 + > www/manager6/qemu/SevEdit.js | 46 ++++++++++++++++++++++++++++++++---- > 2 files changed, 42 insertions(+), 5 deletions(-) > > diff --git a/www/manager6/qemu/Options.js b/www/manager6/qemu/Options.js > index cbe9e52b..49a921cd 100644 > --- a/www/manager6/qemu/Options.js > +++ b/www/manager6/qemu/Options.js > @@ -346,6 +346,7 @@ Ext.define('PVE.qemu.Options', { > let amd_sev = PVE.Parser.parsePropertyString(value, "type"); > if (amd_sev.type === 'std') return 'AMD SEV (' + value + ')'; > if (amd_sev.type === 'es') return 'AMD SEV-ES (' + value + ')'; > + if (amd_sev.type === 'snp') return 'AMD SEV-SNP (' + value + ')'; > return value; > }, > }, > diff --git a/www/manager6/qemu/SevEdit.js b/www/manager6/qemu/SevEdit.js > index a2080f2d..3e0d0cbb 100644 > --- a/www/manager6/qemu/SevEdit.js > +++ b/www/manager6/qemu/SevEdit.js > @@ -9,7 +9,8 @@ Ext.define('PVE.qemu.SevInputPanel', { > type: '__default__', > }, > formulas: { > - sevEnabled: get => get('type') !== '__default__', > + sevEnabled: get => get('type') === 'std' || get('type') === 'es' || get('type') === 'snp', > + snpEnabled: get => get('type') === 'snp', > }, > }, > > @@ -21,10 +22,14 @@ Ext.define('PVE.qemu.SevInputPanel', { > if (!values.debug) { > values["no-debug"] = 1; > } > - if (!values["key-sharing"]) { > + if (values.smt) { > + values["allow-smt"] = 1; > + } You could replace the if above with something like this: if (!values.smt && values.type === 'snp') { values["allow-smt"] = 0; } > + if (!values["key-sharing"] && values.type !== 'snp') { > values["no-key-sharing"] = 1; > } > delete values.debug; > + delete values.smt; > delete values["key-sharing"]; > let ret = {}; > ret['amd-sev'] = PVE.Parser.printPropertyString(values, 'type'); > @@ -36,13 +41,16 @@ Ext.define('PVE.qemu.SevInputPanel', { > if (PVE.Parser.parseBoolean(values["no-debug"])) { > values.debug = 0; > } > + if (PVE.Parser.parseBoolean(values["allow-smt"])) { > + values.smt = 1; > + } You could replace the if above with something like this: values.smt = PVE.Parser.parseBoolean(values["allow-smt"], 1); > if (PVE.Parser.parseBoolean(values["no-key-sharing"])) { > values["key-sharing"] = 0; > } > this.callParent(arguments); > }, > > - items: { > + items: [{ > xtype: 'proxmoxKVComboBox', > fieldLabel: gettext('AMD SEV Type'), > labelWidth: 150, > @@ -52,11 +60,28 @@ Ext.define('PVE.qemu.SevInputPanel', { > ['__default__', Proxmox.Utils.defaultText + ' (' + Proxmox.Utils.disabledText + ')'], > ['std', 'AMD SEV'], > ['es', 'AMD SEV-ES (highly experimental)'], > + ['snp', 'AMD SEV-SNP (highly experimental)'], > ], > bind: { > value: '{type}', > }, > }, > + { > + xtype: 'displayfield', > + userCls: 'pmx-hint', > + value: gettext('WARNING: When using SEV-SNP no EFI disk is loaded as pflash.'), > + bind: { > + hidden: '{!snpEnabled}', > + }, > + }, > + { > + xtype: 'displayfield', > + userCls: 'pmx-hint', > + value: gettext('Note: SEV-SNP requires host kernel version 6.11 or higher.'), > + bind: { > + hidden: '{!snpEnabled}', > + }, > + }], > > advancedItems: [ > { > @@ -77,8 +102,19 @@ Ext.define('PVE.qemu.SevInputPanel', { > name: 'key-sharing', > value: 1, > bind: { > - hidden: '{!sevEnabled}', > - disabled: '{!sevEnabled}', > + hidden: '{!sevEnabled || snpEnabled}', > + disabled: '{!sevEnabled || snpEnabled}', > + }, > + }, > + { > + xtype: 'proxmoxcheckbox', > + fieldLabel: gettext('Allow SMT'), > + labelWidth: 150, > + name: 'smt', > + value: 1, > + bind: { > + hidden: '{!snpEnabled}', > + disabled: '{!snpEnabled}', > }, > }, > { _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-03-18 9:41 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-03-11 15:04 [pve-devel] [PATCH edk2-firmware/qemu-server/manager v3 0/4] AMD SEV-SNP Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH edk2-firmware v4 1/4] Add OVMF targets for AMD SEV-ES and SEV-SNP Philipp Giersfeld 2025-03-18 9:40 ` Markus Frank 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 2/4] Convert policy calculation Philipp Giersfeld 2025-03-11 15:04 ` [pve-devel] [PATCH qemu-server v4 3/4] config: add AMD SEV-SNP support Philipp Giersfeld 2025-03-18 9:41 ` Markus Frank 2025-03-11 15:04 ` [pve-devel] [PATCH pve-manager v4 4/4] Add configuration options for AMD SEV-SNP Philipp Giersfeld 2025-03-17 10:13 ` Markus Frank
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.