]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto/ccp: Implement SNP x86 shutdown
authorTycho Andersen (AMD) <tycho@kernel.org>
Tue, 24 Mar 2026 16:13:00 +0000 (10:13 -0600)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 30 Mar 2026 10:02:12 +0000 (12:02 +0200)
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. Also skip the panic
case, since snp_shutdown() does IPIs.

Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Link: https://patch.msgid.link/20260324161301.1353976-7-tycho@kernel.org
drivers/crypto/ccp/sev-dev.c
include/linux/psp-sev.h

index 0d0c09a3a0afa8d23bb7e023622df521213e4ee1..cc5c5b3ad66d00b07fa2e50baaf5cff440a27a03 100644 (file)
@@ -2039,6 +2039,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
@@ -2072,23 +2074,28 @@ 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;
+       if (data.x86_snp_shutdown) {
+               if (!panic)
+                       snp_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();
index 69ffa4b4d1fa5346f73e2eb43a221fd6a7abab5c..d5099a2baca51888732c05200ba1fe2dc935e601 100644 (file)
@@ -829,12 +829,14 @@ struct sev_data_range_list {
  *
  * @len: length of the command buffer read by the PSP
  * @iommu_snp_shutdown: Disable enforcement of SNP in the IOMMU
+ * @x86_snp_shutdown: Disable SNP on all cores
  * @rsvd1: reserved
  */
 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 +893,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)