]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: ccp - Add an S4 restore flow
authorMario Limonciello (AMD) <superm1@kernel.org>
Fri, 16 Jan 2026 04:11:30 +0000 (22:11 -0600)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Wed, 21 Jan 2026 08:51:59 +0000 (10:51 +0200)
The system will have lost power during S4.  The ring used for TEE
communications needs to be initialized before use.

Fixes: f892a21f51162 ("crypto: ccp - use generic power management")
Reported-by: Lars Francke <lars.francke@gmail.com>
Closes: https://lore.kernel.org/platform-driver-x86/CAD-Ua_gfJnQSo8ucS_7ZwzuhoBRJ14zXP7s8b-zX3ZcxcyWePw@mail.gmail.com/
Tested-by: Yijun Shen <Yijun.Shen@Dell.com>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Link: https://patch.msgid.link/20260116041132.153674-4-superm1@kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/crypto/ccp/psp-dev.c
drivers/crypto/ccp/sp-dev.c
drivers/crypto/ccp/sp-dev.h
drivers/crypto/ccp/sp-pci.c
drivers/crypto/ccp/tee-dev.c
drivers/crypto/ccp/tee-dev.h

index 9e21da0e298ad76b68385204118d7b5ce0889c77..5c7f7e02a7d8ab14b89cc26c4cce3c1fc97f193e 100644 (file)
@@ -351,6 +351,17 @@ struct psp_device *psp_get_master_device(void)
        return sp ? sp->psp_data : NULL;
 }
 
+int psp_restore(struct sp_device *sp)
+{
+       struct psp_device *psp = sp->psp_data;
+       int ret = 0;
+
+       if (psp->tee_data)
+               ret = tee_restore(psp);
+
+       return ret;
+}
+
 void psp_pci_init(void)
 {
        psp_master = psp_get_master_device();
index 3467f6db4f505a2fbca05e36878b1d20f6ec556c..f204aa5df96e248f9b278eca9784e9eb57eefb35 100644 (file)
@@ -230,6 +230,18 @@ int sp_resume(struct sp_device *sp)
        return 0;
 }
 
+int sp_restore(struct sp_device *sp)
+{
+       if (sp->psp_data) {
+               int ret = psp_restore(sp);
+
+               if (ret)
+                       return ret;
+       }
+
+       return sp_resume(sp);
+}
+
 struct sp_device *sp_get_psp_master_device(void)
 {
        struct sp_device *i, *ret = NULL;
index 1335a83fe052ea90c0e998a3fee1a8ccc87f5a9a..a83751cfd00603c609ce037d83bbad39d7e87387 100644 (file)
@@ -141,6 +141,7 @@ void sp_destroy(struct sp_device *sp);
 
 int sp_suspend(struct sp_device *sp);
 int sp_resume(struct sp_device *sp);
+int sp_restore(struct sp_device *sp);
 int sp_request_ccp_irq(struct sp_device *sp, irq_handler_t handler,
                       const char *name, void *data);
 void sp_free_ccp_irq(struct sp_device *sp, void *data);
@@ -174,6 +175,7 @@ int psp_dev_init(struct sp_device *sp);
 void psp_pci_init(void);
 void psp_dev_destroy(struct sp_device *sp);
 void psp_pci_exit(void);
+int psp_restore(struct sp_device *sp);
 
 #else /* !CONFIG_CRYPTO_DEV_SP_PSP */
 
@@ -181,6 +183,7 @@ static inline int psp_dev_init(struct sp_device *sp) { return 0; }
 static inline void psp_pci_init(void) { }
 static inline void psp_dev_destroy(struct sp_device *sp) { }
 static inline void psp_pci_exit(void) { }
+static inline int psp_restore(struct sp_device *sp) { return 0; }
 
 #endif /* CONFIG_CRYPTO_DEV_SP_PSP */
 
index 8891ceee1d7d05ab763c5de4e72362dbc2a4a5d2..6ac805d99ccb30164b55ba1e629fa7bc9e753474 100644 (file)
@@ -353,6 +353,13 @@ static int __maybe_unused sp_pci_resume(struct device *dev)
        return sp_resume(sp);
 }
 
+static int __maybe_unused sp_pci_restore(struct device *dev)
+{
+       struct sp_device *sp = dev_get_drvdata(dev);
+
+       return sp_restore(sp);
+}
+
 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
 static const struct sev_vdata sevv1 = {
        .cmdresp_reg            = 0x10580,      /* C2PMSG_32 */
@@ -563,7 +570,14 @@ static const struct pci_device_id sp_pci_table[] = {
 };
 MODULE_DEVICE_TABLE(pci, sp_pci_table);
 
-static SIMPLE_DEV_PM_OPS(sp_pci_pm_ops, sp_pci_suspend, sp_pci_resume);
+static const struct dev_pm_ops sp_pci_pm_ops = {
+       .suspend = pm_sleep_ptr(sp_pci_suspend),
+       .resume = pm_sleep_ptr(sp_pci_resume),
+       .freeze = pm_sleep_ptr(sp_pci_suspend),
+       .thaw = pm_sleep_ptr(sp_pci_resume),
+       .poweroff = pm_sleep_ptr(sp_pci_suspend),
+       .restore_early = pm_sleep_ptr(sp_pci_restore),
+};
 
 static struct pci_driver sp_pci_driver = {
        .name = "ccp",
index af881daa5855b21fcb95a2fd04698b2636fdbb0d..11c4b05e2f3a28c262b384e42c2c4703e0d9929c 100644 (file)
@@ -366,3 +366,8 @@ int psp_check_tee_status(void)
        return 0;
 }
 EXPORT_SYMBOL(psp_check_tee_status);
+
+int tee_restore(struct psp_device *psp)
+{
+       return tee_init_ring(psp->tee_data);
+}
index ea9a2b7c05f577c9919836e68ff92dc7de8bc10e..c23416cb7bb37f6304add81f9aba6be7ffbfaac6 100644 (file)
@@ -111,5 +111,6 @@ struct tee_ring_cmd {
 
 int tee_dev_init(struct psp_device *psp);
 void tee_dev_destroy(struct psp_device *psp);
+int tee_restore(struct psp_device *psp);
 
 #endif /* __TEE_DEV_H__ */