Re: [PATCH RFC v7 37/64] KVM: SVM: Add KVM_SNP_INIT command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 05, 2023 at 05:37:20PM -0600, Kalra, Ashish wrote:
> Hello Jarkko,
> 
> On 12/31/2022 8:27 AM, Jarkko Sakkinen wrote:
> > On Wed, Dec 14, 2022 at 01:40:29PM -0600, Michael Roth wrote:
> > >   static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
> > >   {
> > >   	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
> > > @@ -260,13 +279,23 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
> > >   		return ret;
> > >   	sev->active = true;
> > > -	sev->es_active = argp->id == KVM_SEV_ES_INIT;
> > > +	sev->es_active = (argp->id == KVM_SEV_ES_INIT || argp->id == KVM_SEV_SNP_INIT);
> > > +	sev->snp_active = argp->id == KVM_SEV_SNP_INIT;
> > >   	asid = sev_asid_new(sev);
> > >   	if (asid < 0)
> > >   		goto e_no_asid;
> > >   	sev->asid = asid;
> > > -	ret = sev_platform_init(&argp->error);
> > > +	if (sev->snp_active) {
> > > +		ret = verify_snp_init_flags(kvm, argp);
> > > +		if (ret)
> > > +			goto e_free;
> > > +
> > > +		ret = sev_snp_init(&argp->error, false);
> > > +	} else {
> > > +		ret = sev_platform_init(&argp->error);
> > > +	}
> > 
> > Couldn't sev_snp_init() and sev_platform_init() be called unconditionally
> > in order?
> > 
> > Since there is a hardware constraint that SNP init needs to always happen
> > before platform init, shouldn't SNP init happen as part of
> > __sev_platform_init_locked() instead?
> > 
> 
> On Genoa there is currently an issue that if we do an SNP_INIT before an
> SEV_INIT and then attempt to launch a SEV guest that may fail, so we need to
> keep SNP INIT and SEV INIT separate.
> 
> We need to provide a way to run (existing) SEV guests on a system that
> supports SNP without doing an SNP_INIT at all.
> 
> This is done using psp_init_on_probe parameter of the CCP module to avoid
> doing either SNP/SEV firmware initialization during module load and then
> defer the firmware initialization till someone launches a guest of one
> flavor or the other.
> 
> And then sev_guest_init() does either SNP or SEV firmware init depending on
> the type of the guest being launched.

OK, got it, thank you. I have not noticed the init_on_probe for
sev_snp_init() before. Was it in earlier patch set version?

The benefit of having everything in __sev_platform_init_lock() would be first 
less risk of shooting yourself into foot, and also no need to pass
init_on_probe to sev_snp_init() as it would be internal to sev-dev.c, and
no need for special cases for callers. It is in my opinion internals of the
SEV driver to guarantee the order.

E.g. changes to svm/sev.c would be then quite trivial.

> > I found these call sites for __sev_platform_init_locked(), none of which
> > follow the correct call order:
> > 
> > * sev_guest_init()
> 
> As explained above, this call site is important for deferring the firmware
> initialization to an actual guest launch.
> 
> > * sev_ioctl_do_pek_csr
> > * sev_ioctl_do_pdh_export()
> > * sev_ioctl_do_pek_import()
> > * sev_ioctl_do_pek_pdh_gen()

What happens if any of these are called before sev_guest_init()? They only
call __sev_platform_init_locked().

> > * sev_pci_init()
> > 
> > For me it looks like a bit flakky API use to have sev_snp_init() as an API
> > call.
> > 
> > I would suggest to make SNP init internal to the ccp driver and take care
> > of the correct orchestration over there.
> > 
> 
> Due to Genoa issue, we may still need SNP init and SEV init to be invoked
> separately outside the CCP driver.
> 
> > Also, how it currently works in this patch set, if the firmware did not
> > load correctly, SNP init halts the whole system. The version check needs
> > to be in all call paths.
> > 
> 
> Yes, i agree with that.

Attached the fix I sent in private earlier.

> Thanks,
> Ashish

BR, Jarkko
>From f24054af9eeeb0314bbd0c37bd97ff38e2ded717 Mon Sep 17 00:00:00 2001
From: Jarkko Sakkinen <jarkko@xxxxxxxxxxx>
Date: Sun, 4 Dec 2022 06:17:07 +0000
Subject: [PATCH] crypto: ccp: Prevent a spurious SEV_CMD_SNP_INIT triggered by
 sev_guest_init()

Move the firmware version check from sev_pci_init() to sev_snp_init().

Signed-off-by: Jarkko Sakkinen <jarkko@xxxxxxxxxxx>
---
 drivers/crypto/ccp/sev-dev.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 7c5698bde655..08787d998f15 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -1387,6 +1387,12 @@ static int __sev_snp_init_locked(int *error)
 	if (sev->snp_initialized)
 		return 0;
 
+	if (!sev_version_greater_or_equal(SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR)) {
+		dev_dbg(sev->dev, "SEV-SNP support requires firmware version >= %d:%d\n",
+			SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR);
+		return 0;
+	}
+
 	/*
 	 * The SNP_INIT requires the MSR_VM_HSAVE_PA must be set to 0h
 	 * across all cores.
@@ -2319,25 +2325,19 @@ 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.
 	 */
 	if (cpu_feature_enabled(X86_FEATURE_SEV_SNP)) {
-		if (!sev_version_greater_or_equal(SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR)) {
-			dev_err(sev->dev, "SEV-SNP support requires firmware version >= %d:%d\n",
-				SNP_MIN_API_MAJOR, SNP_MIN_API_MINOR);
-		} else {
-			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);
-			}
-		}
-
 		/*
 		 * Allocate the intermediate buffers used for the legacy command handling.
 		 */
-- 
2.38.1


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux