From: Peter Gonda pgonda@google.com
[ Upstream commit e423b9d75e779d921e6adf5ac3d0b59400d6ba7e ]
Move the data corrupted retry of SEV_INIT into the __sev_platform_init_locked() function. This is for upcoming INIT_EX support as well as helping direct callers of __sev_platform_init_locked() which currently do not support the retry.
Signed-off-by: Peter Gonda pgonda@google.com Reviewed-by: Marc Orr marcorr@google.com Acked-by: David Rientjes rientjes@google.com Acked-by: Tom Lendacky thomas.lendacky@amd.com Acked-by: Brijesh Singh brijesh.singh@amd.com Cc: Tom Lendacky thomas.lendacky@amd.com Cc: Brijesh Singh brijesh.singh@amd.com Cc: Marc Orr marcorr@google.com Cc: Joerg Roedel jroedel@suse.de Cc: Herbert Xu herbert@gondor.apana.org.au Cc: David Rientjes rientjes@google.com Cc: John Allen john.allen@amd.com Cc: "David S. Miller" davem@davemloft.net Cc: Paolo Bonzini pbonzini@redhat.com Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccp/sev-dev.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index e09925d86bf36..581a1b13d5c3d 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -241,7 +241,7 @@ static int __sev_platform_init_locked(int *error) struct psp_device *psp = psp_master; struct sev_data_init data; struct sev_device *sev; - int rc = 0; + int psp_ret, rc = 0;
if (!psp || !psp->sev_data) return -ENODEV; @@ -266,7 +266,21 @@ static int __sev_platform_init_locked(int *error) data.tmr_len = SEV_ES_TMR_SIZE; }
- rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, error); + rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); + if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { + /* + * Initialization command returned an integrity check failure + * status code, meaning that firmware load and validation of SEV + * related persistent data has failed. Retrying the + * initialization function should succeed by replacing the state + * with a reset state. + */ + dev_dbg(sev->dev, "SEV: retrying INIT command"); + rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); + } + if (error) + *error = psp_ret; + if (rc) return rc;
@@ -1091,18 +1105,6 @@ void sev_pci_init(void)
/* Initialize the platform */ rc = sev_platform_init(&error); - if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) { - /* - * INIT command returned an integrity check failure - * status code, meaning that firmware load and - * validation of SEV related persistent data has - * failed and persistent state has been erased. - * Retrying INIT command here should succeed. - */ - dev_dbg(sev->dev, "SEV: retrying INIT command"); - rc = sev_platform_init(&error); - } - if (rc) { dev_err(sev->dev, "SEV: failed to INIT error %#x\n", error); return;