crypto: ccp - Retry SEV INIT command in case of integrity check failure.
authorAshish Kalra <ashish.kalra@amd.com>
Thu, 17 Oct 2019 22:35:11 +0000 (22:35 +0000)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 25 Oct 2019 15:09:58 +0000 (02:09 +1100)
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>
drivers/crypto/ccp/psp-dev.c
include/uapi/linux/psp-sev.h

index 6b17d17..f9318d4 100644 (file)
@@ -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;
index 592a0c1..0549a5c 100644 (file)
@@ -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;