The following functions end up calling sev_platform_init() or __sev_platform_init_locked(): * sev_guest_init() * sev_ioctl_do_pek_csr * sev_ioctl_do_pdh_export() * sev_ioctl_do_pek_import() * sev_ioctl_do_pek_pdh_gen() * sev_pci_init() Only sev_guest_init() and sev_pci_init() also call sev_snp_init(). Address this by calling __sev_snp_init_locked() inside __sev_platform_init_locked() before any other initialization. Signed-off-by: Jarkko Sakkinen <jarkko@xxxxxxxxxxx> --- arch/x86/kvm/svm/sev.c | 4 +-- drivers/crypto/ccp/sev-dev.c | 51 +++++++++++++----------------------- include/linux/psp-sev.h | 15 ----------- 3 files changed, 19 insertions(+), 51 deletions(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 5e4666b79689..2dd56f59fc50 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -343,11 +343,9 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) goto e_free; mutex_init(&sev->guest_req_lock); - ret = sev_snp_init(&argp->error, false); - } else { - ret = sev_platform_init(&argp->error); } + ret = sev_platform_init(&argp->error); if (ret) goto e_free; diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 50e73df966ec..be040926f66a 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -102,6 +102,7 @@ struct sev_data_range_list *snp_range_list; static size_t sev_es_tmr_size = SEV_ES_TMR_SIZE; static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret); +static int __sev_snp_init_locked(int *error); static inline bool sev_version_greater_or_equal(u8 maj, u8 min) { @@ -965,7 +966,8 @@ static int __sev_platform_init_locked(int *error) { struct psp_device *psp = psp_master; struct sev_device *sev; - int rc = 0, psp_ret = -1; + int psp_ret = -1; + int rc; int (*init_function)(int *error); if (!psp || !psp->sev_data) @@ -976,6 +978,18 @@ static int __sev_platform_init_locked(int *error) if (sev->state == SEV_STATE_INIT) return 0; + rc = __sev_snp_init_locked(error); + if (rc < 0 && rc != -ENODEV) + return rc; + + if (!sev_es_tmr) { + /* Obtain the TMR memory area for SEV-ES use */ + sev_es_tmr = sev_fw_alloc(sev_es_tmr_size); + if (!sev_es_tmr) + dev_warn(sev->dev, + "SEV: TMR allocation failed, SEV-ES support unavailable\n"); + } + if (sev_init_ex_buffer) { init_function = __sev_init_ex_locked; rc = sev_read_init_ex_file(); @@ -1373,6 +1387,9 @@ static int __sev_snp_init_locked(int *error) struct sev_device *sev; int rc = 0; + if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) + return -ENODEV; + if (!psp || !psp->sev_data) return -ENODEV; @@ -1457,24 +1474,6 @@ static int __sev_snp_init_locked(int *error) return rc; } -int sev_snp_init(int *error, bool init_on_probe) -{ - int rc; - - if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) - return -ENODEV; - - if (init_on_probe && !psp_init_on_probe) - return 0; - - mutex_lock(&sev_cmd_mutex); - rc = __sev_snp_init_locked(error); - mutex_unlock(&sev_cmd_mutex); - - return rc; -} -EXPORT_SYMBOL_GPL(sev_snp_init); - static int __sev_snp_shutdown_locked(int *error) { struct sev_device *sev = psp_master->sev_data; @@ -2319,14 +2318,6 @@ void sev_pci_init(void) } } - rc = sev_snp_init(&error, true); - if (rc) - /* - * Don't abort the probe if SNP INIT failed, - * continue to initialize the legacy SEV firmware. - */ - dev_err(sev->dev, "SEV-SNP: failed to INIT error %#x\n", error); - /* * If boot CPU supports SNP, then first attempt to initialize * the SNP firmware. @@ -2341,12 +2332,6 @@ void sev_pci_init(void) } } - /* Obtain the TMR memory area for SEV-ES use */ - sev_es_tmr = sev_fw_alloc(sev_es_tmr_size); - if (!sev_es_tmr) - dev_warn(sev->dev, - "SEV: TMR allocation failed, SEV-ES support unavailable\n"); - if (!psp_init_on_probe) return; diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index 970a9de0ed20..ef0c6941a8f4 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -794,21 +794,6 @@ struct sev_data_snp_shutdown_ex { */ int sev_platform_init(int *error); -/** - * sev_snp_init - perform SEV SNP_INIT command - * - * @error: SEV command return code - * @init_on_probe: indicates if called during module probe/init - * - * Returns: - * 0 if the SEV successfully processed the command - * -%ENODEV if the SEV device is not available - * -%ENOTSUPP if the SEV does not support SEV - * -%ETIMEDOUT if the SEV command timed out - * -%EIO if the SEV returned a non-zero return code - */ -int sev_snp_init(int *error, bool init_on_probe); - /** * sev_platform_status - perform SEV PLATFORM_STATUS command * -- 2.38.1