crypto: ccp - Add an S4 restore flow

The system will have lost power during S4.  The ring used for TEE
communications needs to be initialized before use.

Fixes: f892a21f51 ("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>
This commit is contained in:
Mario Limonciello (AMD)
2026-01-15 22:11:30 -06:00
committed by Ilpo Järvinen
parent 5e599d7871
commit 0ba2035026
6 changed files with 47 additions and 1 deletions
+11
View 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();
+12
View 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;
+3
View 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 */
+15 -1
View 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",
+5
View 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);
}
+1
View 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__ */