diff options
author | Ashish Kalra <ashish.kalra@amd.com> | 2025-06-16 21:50:27 +0000 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2025-06-23 17:00:27 +0800 |
commit | ab8b9fd39c45b7760093528cbef93e7353359d82 (patch) | |
tree | cb3d078be824e98102a6a43d075c3228cb6cb15f | |
parent | f5ad93ffb54119a8dc5e18f070624d4ead586969 (diff) |
crypto: ccp - Fix SNP panic notifier unregistration
Panic notifiers are invoked with RCU read lock held and when the
SNP panic notifier tries to unregister itself from the panic
notifier callback itself it causes a deadlock as notifier
unregistration does RCU synchronization.
Code flow for SNP panic notifier:
snp_shutdown_on_panic() ->
__sev_firmware_shutdown() ->
__sev_snp_shutdown_locked() ->
atomic_notifier_chain_unregister(.., &snp_panic_notifier)
Fix SNP panic notifier to unregister itself during SNP shutdown
only if panic is not in progress.
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Cc: stable@vger.kernel.org
Fixes: 19860c3274fb ("crypto: ccp - Register SNP panic notifier only if SNP is enabled")
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/crypto/ccp/sev-dev.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 8fb94c5f006a..17edc6bf5622 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -1787,8 +1787,14 @@ static int __sev_snp_shutdown_locked(int *error, bool panic) sev->snp_initialized = false; dev_dbg(sev->dev, "SEV-SNP firmware shutdown\n"); - atomic_notifier_chain_unregister(&panic_notifier_list, - &snp_panic_notifier); + /* + * __sev_snp_shutdown_locked() deadlocks when it tries to unregister + * itself during panic as the panic notifier is called with RCU read + * lock held and notifier unregistration does RCU synchronization. + */ + if (!panic) + atomic_notifier_chain_unregister(&panic_notifier_list, + &snp_panic_notifier); /* Reset TMR size back to default */ sev_es_tmr_size = SEV_TMR_SIZE; |