Re: [PATCH 10/11] crypto: ccp - implement SNP x86 shutdown
From: Tom Lendacky
Date: Mon Mar 02 2026 - 16:41:59 EST
On 3/2/26 13:13, Tycho Andersen wrote:
> From: "Tycho Andersen (AMD)" <tycho@xxxxxxxxxx>
>
> The SEV firmware has support to disable SNP during an SNP_SHUTDOWN_EX
> command. Verify that this support is available and set the flag so that SNP
> is disabled when it is not being used. In cases where SNP is disabled, skip
> the call to amd_iommu_snp_disable(), as all of the IOMMU pages have already
> been made shared.
>
> Signed-off-by: Tycho Andersen (AMD) <tycho@xxxxxxxxxx>
Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>
> ---
> drivers/crypto/ccp/sev-dev.c | 44 ++++++++++++++++++++++--------------
> include/linux/psp-sev.h | 4 +++-
> 2 files changed, 30 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
> index ef45977b09b6..665fe0615b06 100644
> --- a/drivers/crypto/ccp/sev-dev.c
> +++ b/drivers/crypto/ccp/sev-dev.c
> @@ -2028,6 +2028,7 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
> struct psp_device *psp = psp_master;
> struct sev_device *sev;
> struct sev_data_snp_shutdown_ex data;
> + u64 syscfg;
> int ret;
>
> if (!psp || !psp->sev_data)
> @@ -2041,6 +2042,8 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
> memset(&data, 0, sizeof(data));
> data.len = sizeof(data);
> data.iommu_snp_shutdown = 1;
> + if (sev->snp_feat_info_0.ecx & SNP_X86_SHUTDOWN_SUPPORTED)
> + data.x86_snp_shutdown = 1;
>
> /*
> * If invoked during panic handling, local interrupts are disabled
> @@ -2074,23 +2077,30 @@ static int __sev_snp_shutdown_locked(int *error, bool panic)
> return ret;
> }
>
> - /*
> - * SNP_SHUTDOWN_EX with IOMMU_SNP_SHUTDOWN set to 1 disables SNP
> - * enforcement by the IOMMU and also transitions all pages
> - * associated with the IOMMU to the Reclaim state.
> - * Firmware was transitioning the IOMMU pages to Hypervisor state
> - * before version 1.53. But, accounting for the number of assigned
> - * 4kB pages in a 2M page was done incorrectly by not transitioning
> - * to the Reclaim state. This resulted in RMP #PF when later accessing
> - * the 2M page containing those pages during kexec boot. Hence, the
> - * firmware now transitions these pages to Reclaim state and hypervisor
> - * needs to transition these pages to shared state. SNP Firmware
> - * version 1.53 and above are needed for kexec boot.
> - */
> - ret = amd_iommu_snp_disable();
> - if (ret) {
> - dev_err(sev->dev, "SNP IOMMU shutdown failed\n");
> - return ret;
> + rdmsrq(MSR_AMD64_SYSCFG, syscfg);
> + if (data.x86_snp_shutdown &&
> + !WARN_ON_ONCE(syscfg & MSR_AMD64_SYSCFG_SNP_EN)) {
> + if (!panic)
> + snp_x86_shutdown();
> + } else {
> + /*
> + * SNP_SHUTDOWN_EX with IOMMU_SNP_SHUTDOWN set to 1 disables SNP
> + * enforcement by the IOMMU and also transitions all pages
> + * associated with the IOMMU to the Reclaim state.
> + * Firmware was transitioning the IOMMU pages to Hypervisor state
> + * before version 1.53. But, accounting for the number of assigned
> + * 4kB pages in a 2M page was done incorrectly by not transitioning
> + * to the Reclaim state. This resulted in RMP #PF when later accessing
> + * the 2M page containing those pages during kexec boot. Hence, the
> + * firmware now transitions these pages to Reclaim state and hypervisor
> + * needs to transition these pages to shared state. SNP Firmware
> + * version 1.53 and above are needed for kexec boot.
> + */
> + ret = amd_iommu_snp_disable();
> + if (ret) {
> + dev_err(sev->dev, "SNP IOMMU shutdown failed\n");
> + return ret;
> + }
> }
>
> snp_leak_hv_fixed_pages();
> diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
> index 69ffa4b4d1fa..2adb990189c1 100644
> --- a/include/linux/psp-sev.h
> +++ b/include/linux/psp-sev.h
> @@ -834,7 +834,8 @@ struct sev_data_range_list {
> struct sev_data_snp_shutdown_ex {
> u32 len;
> u32 iommu_snp_shutdown:1;
> - u32 rsvd1:31;
> + u32 x86_snp_shutdown:1;
> + u32 rsvd1:30;
> } __packed;
>
> /**
> @@ -891,6 +892,7 @@ struct snp_feature_info {
> } __packed;
>
> /* Feature bits in ECX */
> +#define SNP_X86_SHUTDOWN_SUPPORTED BIT(1)
> #define SNP_RAPL_DISABLE_SUPPORTED BIT(2)
> #define SNP_CIPHER_TEXT_HIDING_SUPPORTED BIT(3)
> #define SNP_AES_256_XTS_POLICY_SUPPORTED BIT(4)