aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Kalra <ashish.kalra@amd.com>2019-10-17 22:35:11 +0000
committerHerbert Xu <herbert@gondor.apana.org.au>2019-10-26 02:09:58 +1100
commit1d55fdc85799372ab3b0d2a6928e73439f8149aa (patch)
tree157ea4d1e9678945646577317ca414b58781a3d6
parentcrypto: amlogic - Add crypto accelerator for amlogic GXL (diff)
downloadlinux-dev-1d55fdc85799372ab3b0d2a6928e73439f8149aa.tar.xz
linux-dev-1d55fdc85799372ab3b0d2a6928e73439f8149aa.zip
crypto: ccp - Retry SEV INIT command in case of integrity check failure.
SEV INIT command loads the SEV related persistent data from NVS and initializes the platform context. The firmware validates the persistent state. If validation fails, the firmware will reset the persisent state and return an integrity check failure status. At this point, a subsequent INIT command should succeed, so retry the command. The INIT command retry is only done during driver initialization. Additional enums along with SEV_RET_SECURE_DATA_INVALID are added to sev_ret_code to maintain continuity and relevance of enum values. Signed-off-by: Ashish Kalra <ashish.kalra@amd.com> Acked-by: David Rientjes <rientjes@google.com> Reviewed-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/ccp/psp-dev.c12
-rw-r--r--include/uapi/linux/psp-sev.h3
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
index 6b17d179ef8a..f9318d4482f2 100644
--- a/drivers/crypto/ccp/psp-dev.c
+++ b/drivers/crypto/ccp/psp-dev.c
@@ -1064,6 +1064,18 @@ void psp_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(sp->dev, "SEV: retrying INIT command");
+ rc = sev_platform_init(&error);
+ }
+
if (rc) {
dev_err(sp->dev, "SEV: failed to INIT error %#x\n", error);
return;
diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h
index 592a0c1b77c9..0549a5c622bf 100644
--- a/include/uapi/linux/psp-sev.h
+++ b/include/uapi/linux/psp-sev.h
@@ -58,6 +58,9 @@ typedef enum {
SEV_RET_HWSEV_RET_PLATFORM,
SEV_RET_HWSEV_RET_UNSAFE,
SEV_RET_UNSUPPORTED,
+ SEV_RET_INVALID_PARAM,
+ SEV_RET_RESOURCE_LIMIT,
+ SEV_RET_SECURE_DATA_INVALID,
SEV_RET_MAX,
} sev_ret_code;