]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/sev: Create snp_shutdown()
authorTycho Andersen (AMD) <tycho@kernel.org>
Tue, 24 Mar 2026 16:12:57 +0000 (10:12 -0600)
committerBorislav Petkov (AMD) <bp@alien8.de>
Sun, 29 Mar 2026 10:15:17 +0000 (12:15 +0200)
After SNP_SHUTDOWN, two things should be done:

1. clear the RMP table
2. disable MFDM to prevent the FW_WARN in k8_check_syscfg_dram_mod_en() in
   the event of a kexec

Create and export to the CCP driver a function that does them.

Also change the MFDM helper to allow for disabling the bit, since the SNP x86
shutdown path needs to disable MFDM.

The comment for k8_check_syscfg_dram_mod_en() notes, the "BIOS" is supposed
clear it, or the kernel in the case of module unload and shutdown followed by
kexec.

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>
Link: https://patch.msgid.link/20260324161301.1353976-4-tycho@kernel.org
arch/x86/include/asm/sev.h
arch/x86/virt/svm/sev.c

index 2140e26dec6cab16c9f91a14b480c45acb45f05a..09e605c85de4cdf50edbdef23a87dc6be9c23d15 100644 (file)
@@ -662,6 +662,7 @@ static inline void snp_leak_pages(u64 pfn, unsigned int pages)
        __snp_leak_pages(pfn, pages, true);
 }
 void snp_prepare(void);
+void snp_shutdown(void);
 #else
 static inline bool snp_probe_rmptable_info(void) { return false; }
 static inline int snp_rmptable_init(void) { return -ENOSYS; }
@@ -679,6 +680,7 @@ static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
 static inline void kdump_sev_callback(void) { }
 static inline void snp_fixup_e820_tables(void) {}
 static inline void snp_prepare(void) {}
+static inline void snp_shutdown(void) {}
 #endif
 
 #endif
index ccec529525735c172e9c7913a647a627e9f0089b..3b2273dca1964dadc244297f3d2a2cd64bc6a149 100644 (file)
@@ -132,12 +132,15 @@ static unsigned long snp_nr_leaked_pages;
 #undef pr_fmt
 #define pr_fmt(fmt)    "SEV-SNP: " fmt
 
-static void mfd_enable(void *arg)
+static void mfd_reconfigure(void *arg)
 {
        if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
                return;
 
-       msr_set_bit(MSR_AMD64_SYSCFG, MSR_AMD64_SYSCFG_MFDM_BIT);
+       if (arg)
+               msr_set_bit(MSR_AMD64_SYSCFG, MSR_AMD64_SYSCFG_MFDM_BIT);
+       else
+               msr_clear_bit(MSR_AMD64_SYSCFG, MSR_AMD64_SYSCFG_MFDM_BIT);
 }
 
 static void snp_enable(void *arg)
@@ -523,13 +526,26 @@ void snp_prepare(void)
         * MtrrFixDramModEn is not shared between threads on a core,
         * therefore it must be set on all CPUs prior to enabling SNP.
         */
-       on_each_cpu(mfd_enable, NULL, 1);
+       on_each_cpu(mfd_reconfigure, (void *)1, 1);
        on_each_cpu(snp_enable, NULL, 1);
 
        cpus_read_unlock();
 }
 EXPORT_SYMBOL_FOR_MODULES(snp_prepare, "ccp");
 
+void snp_shutdown(void)
+{
+       u64 syscfg;
+
+       rdmsrq(MSR_AMD64_SYSCFG, syscfg);
+       if (syscfg & MSR_AMD64_SYSCFG_SNP_EN)
+               return;
+
+       clear_rmp();
+       on_each_cpu(mfd_reconfigure, NULL, 1);
+}
+EXPORT_SYMBOL_FOR_MODULES(snp_shutdown, "ccp");
+
 /*
  * Do the necessary preparations which are verified by the firmware as
  * described in the SNP_INIT_EX firmware command description in the SNP