kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages
@ 2023-01-08 20:24 Jarkko Sakkinen
  2023-01-08 22:49 ` David Rientjes
  2023-01-09 14:33 ` Tom Lendacky
  0 siblings, 2 replies; 3+ messages in thread
From: Jarkko Sakkinen @ 2023-01-08 20:24 UTC (permalink / raw)
  To: Sean Christopherson, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Brijesh Singh,
	Tom Lendacky, John Allen, Herbert Xu, David S. Miller
  Cc: David Rientjes, Jarkko Sakkinen, Jarkko Sakkinen,
	open list:KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86),
	open list:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	open list:AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - SE...

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()

However, only sev_pci_init() prints out the failed command error code, and
even there the error message does not specify, SEV which command failed.

Address this by printing out the SEV command errors inside
__sev_platform_init_locked(), and differentiate between DF_FLUSH, INIT and
INIT_EX commands.  As a side-effect, @error can be removed from the
parameter list.

This extra information is particularly useful if firmware loading and/or
initialization is going to be made more robust, e.g. by allowing firmware
loading to be postponed.

Signed-off-by: Jarkko Sakkinen <jarkko@profian.com>
---
v2:
* Address David Rientjes's feedback:
  https://lore.kernel.org/all/6a16bbe4-4281-fb28-78c4-4ec44c8aa679@google.com/
* Remove @error.
* Remove "SEV_" prefix: it is obvious from context so no need to make klog
  line longer.
---
 arch/x86/kvm/svm/sev.c       |  2 +-
 drivers/crypto/ccp/sev-dev.c | 33 +++++++++++++++++----------------
 include/linux/psp-sev.h      |  4 +---
 3 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index efaaef2b7ae1..42e6bd637896 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -254,7 +254,7 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
 		goto e_no_asid;
 	sev->asid = asid;
 
-	ret = sev_platform_init(&argp->error);
+	ret = sev_platform_init();
 	if (ret)
 		goto e_free;
 
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index 06fc7156c04f..3b66cb1495d4 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -440,7 +440,7 @@ static int __sev_init_ex_locked(int *error)
 	return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error);
 }
 
-static int __sev_platform_init_locked(int *error)
+static int __sev_platform_init_locked(void)
 {
 	struct psp_device *psp = psp_master;
 	struct sev_device *sev;
@@ -476,19 +476,21 @@ static int __sev_platform_init_locked(int *error)
 		dev_err(sev->dev, "SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state.");
 		rc = init_function(&psp_ret);
 	}
-	if (error)
-		*error = psp_ret;
-
-	if (rc)
+	if (rc) {
+		dev_err(sev->dev, "SEV: %s failed error %#x",
+			sev_init_ex_buffer ? "CMD_INIT_EX" : "CMD_INIT", psp_ret);
 		return rc;
+	}
 
 	sev->state = SEV_STATE_INIT;
 
 	/* Prepare for first SEV guest launch after INIT */
 	wbinvd_on_all_cpus();
-	rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, error);
-	if (rc)
+	rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, &psp_ret);
+	if (rc) {
+		dev_err(sev->dev, "SEV: CMD_DF_FLUSH failed error %#x", psp_ret);
 		return rc;
+	}
 
 	dev_dbg(sev->dev, "SEV firmware initialized\n");
 
@@ -498,12 +500,12 @@ static int __sev_platform_init_locked(int *error)
 	return 0;
 }
 
-int sev_platform_init(int *error)
+int sev_platform_init(void)
 {
 	int rc;
 
 	mutex_lock(&sev_cmd_mutex);
-	rc = __sev_platform_init_locked(error);
+	rc = __sev_platform_init_locked();
 	mutex_unlock(&sev_cmd_mutex);
 
 	return rc;
@@ -610,7 +612,7 @@ static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp, bool wr
 		return -EPERM;
 
 	if (sev->state == SEV_STATE_UNINIT) {
-		rc = __sev_platform_init_locked(&argp->error);
+		rc = __sev_platform_init_locked();
 		if (rc)
 			return rc;
 	}
@@ -653,7 +655,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
 
 cmd:
 	if (sev->state == SEV_STATE_UNINIT) {
-		ret = __sev_platform_init_locked(&argp->error);
+		ret = __sev_platform_init_locked();
 		if (ret)
 			goto e_free_blob;
 	}
@@ -849,7 +851,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
 
 	/* If platform is not in INIT state then transition it to INIT */
 	if (sev->state != SEV_STATE_INIT) {
-		ret = __sev_platform_init_locked(&argp->error);
+		ret = __sev_platform_init_locked();
 		if (ret)
 			goto e_free_oca;
 	}
@@ -973,7 +975,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
 		if (!writable)
 			return -EPERM;
 
-		ret = __sev_platform_init_locked(&argp->error);
+		ret = __sev_platform_init_locked();
 		if (ret)
 			return ret;
 	}
@@ -1335,10 +1337,9 @@ void sev_pci_init(void)
 		return;
 
 	/* Initialize the platform */
-	rc = sev_platform_init(&error);
+	rc = sev_platform_init();
 	if (rc)
-		dev_err(sev->dev, "SEV: failed to INIT error %#x, rc %d\n",
-			error, rc);
+		dev_err(sev->dev, "SEV: failed to INIT rc %d\n", rc);
 
 	return;
 
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index 1595088c428b..2f8681b753d0 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -536,8 +536,6 @@ struct sev_data_attestation_report {
 /**
  * sev_platform_init - perform SEV INIT command
  *
- * @error: SEV command return code
- *
  * Returns:
  * 0 if the SEV successfully processed the command
  * -%ENODEV    if the SEV device is not available
@@ -545,7 +543,7 @@ struct sev_data_attestation_report {
  * -%ETIMEDOUT if the SEV command timed out
  * -%EIO       if the SEV returned a non-zero return code
  */
-int sev_platform_init(int *error);
+int sev_platform_init(void);
 
 /**
  * sev_platform_status - perform SEV PLATFORM_STATUS command
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages
  2023-01-08 20:24 [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages Jarkko Sakkinen
@ 2023-01-08 22:49 ` David Rientjes
  2023-01-09 14:33 ` Tom Lendacky
  1 sibling, 0 replies; 3+ messages in thread
From: David Rientjes @ 2023-01-08 22:49 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Sean Christopherson, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Brijesh Singh,
	Tom Lendacky, John Allen, Herbert Xu, David S. Miller,
	Jarkko Sakkinen,
	open list:KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86),
	open list:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	open list:AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - SE...

On Sun, 8 Jan 2023, Jarkko Sakkinen wrote:

> 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()
> 
> However, only sev_pci_init() prints out the failed command error code, and
> even there the error message does not specify, SEV which command failed.
> 
> Address this by printing out the SEV command errors inside
> __sev_platform_init_locked(), and differentiate between DF_FLUSH, INIT and
> INIT_EX commands.  As a side-effect, @error can be removed from the
> parameter list.
> 
> This extra information is particularly useful if firmware loading and/or
> initialization is going to be made more robust, e.g. by allowing firmware
> loading to be postponed.
> 
> Signed-off-by: Jarkko Sakkinen <jarkko@profian.com>

Acked-by: David Rientjes <rientjes@google.com>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages
  2023-01-08 20:24 [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages Jarkko Sakkinen
  2023-01-08 22:49 ` David Rientjes
@ 2023-01-09 14:33 ` Tom Lendacky
  1 sibling, 0 replies; 3+ messages in thread
From: Tom Lendacky @ 2023-01-09 14:33 UTC (permalink / raw)
  To: Jarkko Sakkinen, Sean Christopherson, Paolo Bonzini,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Brijesh Singh, John Allen, Herbert Xu,
	David S. Miller
  Cc: David Rientjes, Jarkko Sakkinen,
	open list:KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86),
	open list:X86 ARCHITECTURE (32-BIT AND 64-BIT),
	open list:AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - SE...

On 1/8/23 14:24, Jarkko Sakkinen wrote:
> 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()
> 
> However, only sev_pci_init() prints out the failed command error code, and
> even there the error message does not specify, SEV which command failed.

event there, the error message does not specify which SEV command failed.

> 
> Address this by printing out the SEV command errors inside
> __sev_platform_init_locked(), and differentiate between DF_FLUSH, INIT and
> INIT_EX commands.  As a side-effect, @error can be removed from the
> parameter list.
> 
> This extra information is particularly useful if firmware loading and/or
> initialization is going to be made more robust, e.g. by allowing firmware
> loading to be postponed.
> 
> Signed-off-by: Jarkko Sakkinen <jarkko@profian.com>
> ---
> v2:
> * Address David Rientjes's feedback:
>    https://lore.kernel.org/all/6a16bbe4-4281-fb28-78c4-4ec44c8aa679@google.com/
> * Remove @error.
> * Remove "SEV_" prefix: it is obvious from context so no need to make klog
>    line longer.
> ---
>   arch/x86/kvm/svm/sev.c       |  2 +-
>   drivers/crypto/ccp/sev-dev.c | 33 +++++++++++++++++----------------
>   include/linux/psp-sev.h      |  4 +---
>   3 files changed, 19 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index efaaef2b7ae1..42e6bd637896 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -254,7 +254,7 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
>   		goto e_no_asid;
>   	sev->asid = asid;
>   
> -	ret = sev_platform_init(&argp->error);
> +	ret = sev_platform_init();
>   	if (ret)
>   		goto e_free;
>   
> diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
> index 06fc7156c04f..3b66cb1495d4 100644
> --- a/drivers/crypto/ccp/sev-dev.c
> +++ b/drivers/crypto/ccp/sev-dev.c
> @@ -440,7 +440,7 @@ static int __sev_init_ex_locked(int *error)
>   	return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error);
>   }
>   
> -static int __sev_platform_init_locked(int *error)
> +static int __sev_platform_init_locked(void)

Why is this being removed. Userspace may still want to see this. Some of 
the error pointers are from the ioctl() arguments...

>   {
>   	struct psp_device *psp = psp_master;
>   	struct sev_device *sev;
> @@ -476,19 +476,21 @@ static int __sev_platform_init_locked(int *error)
>   		dev_err(sev->dev, "SEV: retrying INIT command because of SECURE_DATA_INVALID error. Retrying once to reset PSP SEV state.");
>   		rc = init_function(&psp_ret);
>   	}
> -	if (error)
> -		*error = psp_ret;
> -
> -	if (rc)
> +	if (rc) {
> +		dev_err(sev->dev, "SEV: %s failed error %#x",
> +			sev_init_ex_buffer ? "CMD_INIT_EX" : "CMD_INIT", psp_ret);
>   		return rc;
> +	}
>   
>   	sev->state = SEV_STATE_INIT;
>   
>   	/* Prepare for first SEV guest launch after INIT */
>   	wbinvd_on_all_cpus();
> -	rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, error);
> -	if (rc)
> +	rc = __sev_do_cmd_locked(SEV_CMD_DF_FLUSH, NULL, &psp_ret);
> +	if (rc) {
> +		dev_err(sev->dev, "SEV: CMD_DF_FLUSH failed error %#x", psp_ret);
>   		return rc;
> +	}
>   
>   	dev_dbg(sev->dev, "SEV firmware initialized\n");
>   
> @@ -498,12 +500,12 @@ static int __sev_platform_init_locked(int *error)
>   	return 0;
>   }
>   
> -int sev_platform_init(int *error)
> +int sev_platform_init(void)
>   {
>   	int rc;
>   
>   	mutex_lock(&sev_cmd_mutex);
> -	rc = __sev_platform_init_locked(error);
> +	rc = __sev_platform_init_locked();
>   	mutex_unlock(&sev_cmd_mutex);
>   
>   	return rc;
> @@ -610,7 +612,7 @@ static int sev_ioctl_do_pek_pdh_gen(int cmd, struct sev_issue_cmd *argp, bool wr
>   		return -EPERM;
>   
>   	if (sev->state == SEV_STATE_UNINIT) {
> -		rc = __sev_platform_init_locked(&argp->error);
> +		rc = __sev_platform_init_locked();

... like here. So I don't think that should be removed.

Thanks,
Tom

>   		if (rc)
>   			return rc;
>   	}
> @@ -653,7 +655,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
>   
>   cmd:
>   	if (sev->state == SEV_STATE_UNINIT) {
> -		ret = __sev_platform_init_locked(&argp->error);
> +		ret = __sev_platform_init_locked();
>   		if (ret)
>   			goto e_free_blob;
>   	}
> @@ -849,7 +851,7 @@ static int sev_ioctl_do_pek_import(struct sev_issue_cmd *argp, bool writable)
>   
>   	/* If platform is not in INIT state then transition it to INIT */
>   	if (sev->state != SEV_STATE_INIT) {
> -		ret = __sev_platform_init_locked(&argp->error);
> +		ret = __sev_platform_init_locked();
>   		if (ret)
>   			goto e_free_oca;
>   	}
> @@ -973,7 +975,7 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
>   		if (!writable)
>   			return -EPERM;
>   
> -		ret = __sev_platform_init_locked(&argp->error);
> +		ret = __sev_platform_init_locked();
>   		if (ret)
>   			return ret;
>   	}
> @@ -1335,10 +1337,9 @@ void sev_pci_init(void)
>   		return;
>   
>   	/* Initialize the platform */
> -	rc = sev_platform_init(&error);
> +	rc = sev_platform_init();
>   	if (rc)
> -		dev_err(sev->dev, "SEV: failed to INIT error %#x, rc %d\n",
> -			error, rc);
> +		dev_err(sev->dev, "SEV: failed to INIT rc %d\n", rc);
>   
>   	return;
>   
> diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
> index 1595088c428b..2f8681b753d0 100644
> --- a/include/linux/psp-sev.h
> +++ b/include/linux/psp-sev.h
> @@ -536,8 +536,6 @@ struct sev_data_attestation_report {
>   /**
>    * sev_platform_init - perform SEV INIT command
>    *
> - * @error: SEV command return code
> - *
>    * Returns:
>    * 0 if the SEV successfully processed the command
>    * -%ENODEV    if the SEV device is not available
> @@ -545,7 +543,7 @@ struct sev_data_attestation_report {
>    * -%ETIMEDOUT if the SEV command timed out
>    * -%EIO       if the SEV returned a non-zero return code
>    */
> -int sev_platform_init(int *error);
> +int sev_platform_init(void);
>   
>   /**
>    * sev_platform_status - perform SEV PLATFORM_STATUS command

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-01-09 14:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-08 20:24 [PATCH v2] crypto: ccp: Sanitize sev_platform_init() error messages Jarkko Sakkinen
2023-01-08 22:49 ` David Rientjes
2023-01-09 14:33 ` Tom Lendacky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).