On Tue, 22 Oct 2019, Singh, Brijesh wrote: > >>>> From: Ashish Kalra <ashish.kalra@xxxxxxx> > >>>> > >>>> 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@xxxxxxx> > >>>> --- > >>>> drivers/crypto/ccp/psp-dev.c | 12 ++++++++++++ > >>>> include/uapi/linux/psp-sev.h | 3 +++ > >>>> 2 files changed, 15 insertions(+) > >>>> > >>>> 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; > >>> > >>> Curious why this isn't done in __sev_platform_init_locked() since > >>> sev_platform_init() can be called when loading the kvm module and the same > >>> init failure can happen that way. > >>> > >> > >> The FW initialization (aka PLATFORM_INIT) is called in the following > >> code paths: > >> > >> 1. During system boot up > >> > >> and > >> > >> 2. After the platform reset command is issued > >> > >> The patch takes care of #1. Based on the spec, platform reset command > >> should erase the persistent data and the PLATFORM_INIT should *not* fail > >> with SEV_RET_SECURE_DATA_INVALID error code. So, I am not able to see > >> any strong reason to move the retry code in > >> __sev_platform_init_locked(). > >> > > > > Hmm, is the sev_platform_init() call in sev_guest_init() intended to do > > SEV_CMD_INIT only after platform reset? I was under the impression it was > > done in case any previous init failed. > > > > > The PLATFORM_INIT command is allowed only when FW is in UINIT state. On > boot, the FW will be in UNINIT state and similarly after the platform > reset command the FW goes back to UNINIT state. > > The __sev_platform_init_locked() checks the FW state before issuing the > command, if FW is already in INIT state then it returns immediately. > Ah, got it, thanks. Acked-by: David Rientjes <rientjes@xxxxxxxxxx>