kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Brijesh Singh <brijesh.singh@amd.com>
To: Venu Busireddy <venu.busireddy@oracle.com>,
	Ashish Kalra <Ashish.Kalra@amd.com>
Cc: brijesh.singh@amd.com, pbonzini@redhat.com, tglx@linutronix.de,
	mingo@redhat.com, hpa@zytor.com, joro@8bytes.org, bp@suse.de,
	thomas.lendacky@amd.com, x86@kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, rientjes@google.com,
	srutherford@google.com, luto@kernel.org
Subject: Re: [PATCH v6 01/14] KVM: SVM: Add KVM_SEV SEND_START command
Date: Thu, 2 Apr 2020 07:59:54 -0500	[thread overview]
Message-ID: <89a586e4-8074-0d32-f384-a4597975d129@amd.com> (raw)
In-Reply-To: <20200402062726.GA647295@vbusired-dt>

Hi Venu,

Thanks for the feedback.

On 4/2/20 1:27 AM, Venu Busireddy wrote:
> On 2020-03-30 06:19:59 +0000, Ashish Kalra wrote:
>> From: Brijesh Singh <Brijesh.Singh@amd.com>
>>
>> The command is used to create an outgoing SEV guest encryption context.
>>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: "H. Peter Anvin" <hpa@zytor.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: "Radim Krčmář" <rkrcmar@redhat.com>
>> Cc: Joerg Roedel <joro@8bytes.org>
>> Cc: Borislav Petkov <bp@suse.de>
>> Cc: Tom Lendacky <thomas.lendacky@amd.com>
>> Cc: x86@kernel.org
>> Cc: kvm@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org
>> Reviewed-by: Steve Rutherford <srutherford@google.com>
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
>> ---
>>  .../virt/kvm/amd-memory-encryption.rst        |  27 ++++
>>  arch/x86/kvm/svm.c                            | 128 ++++++++++++++++++
>>  include/linux/psp-sev.h                       |   8 +-
>>  include/uapi/linux/kvm.h                      |  12 ++
>>  4 files changed, 171 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/virt/kvm/amd-memory-encryption.rst b/Documentation/virt/kvm/amd-memory-encryption.rst
>> index c3129b9ba5cb..4fd34fc5c7a7 100644
>> --- a/Documentation/virt/kvm/amd-memory-encryption.rst
>> +++ b/Documentation/virt/kvm/amd-memory-encryption.rst
>> @@ -263,6 +263,33 @@ Returns: 0 on success, -negative on error
>>                  __u32 trans_len;
>>          };
>>  
>> +10. KVM_SEV_SEND_START
>> +----------------------
>> +
>> +The KVM_SEV_SEND_START command can be used by the hypervisor to create an
>> +outgoing guest encryption context.
>> +
>> +Parameters (in): struct kvm_sev_send_start
>> +
>> +Returns: 0 on success, -negative on error
>> +
>> +::
>> +        struct kvm_sev_send_start {
>> +                __u32 policy;                 /* guest policy */
>> +
>> +                __u64 pdh_cert_uaddr;         /* platform Diffie-Hellman certificate */
>> +                __u32 pdh_cert_len;
>> +
>> +                __u64 plat_certs_uadr;        /* platform certificate chain */
> Could this please be changed to plat_certs_uaddr, as it is referred to
> in the rest of the code?
>
>> +                __u32 plat_certs_len;
>> +
>> +                __u64 amd_certs_uaddr;        /* AMD certificate */
>> +                __u32 amd_cert_len;
> Could this please be changed to amd_certs_len, as it is referred to in
> the rest of the code?
>
>> +
>> +                __u64 session_uaddr;          /* Guest session information */
>> +                __u32 session_len;
>> +        };
>> +
>>  References
>>  ==========
>>  
>> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
>> index 50d1ebafe0b3..63d172e974ad 100644
>> --- a/arch/x86/kvm/svm.c
>> +++ b/arch/x86/kvm/svm.c
>> @@ -7149,6 +7149,131 @@ static int sev_launch_secret(struct kvm *kvm, struct kvm_sev_cmd *argp)
>>  	return ret;
>>  }
>>  
>> +/* Userspace wants to query session length. */
>> +static int
>> +__sev_send_start_query_session_length(struct kvm *kvm, struct kvm_sev_cmd *argp,
>> +				      struct kvm_sev_send_start *params)
>> +{
>> +	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
>> +	struct sev_data_send_start *data;
>> +	int ret;
>> +
>> +	data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
>> +	if (data == NULL)
>> +		return -ENOMEM;
>> +
>> +	data->handle = sev->handle;
>> +	ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, data, &argp->error);
>> +
>> +	params->session_len = data->session_len;
>> +	if (copy_to_user((void __user *)(uintptr_t)argp->data, params,
>> +				sizeof(struct kvm_sev_send_start)))
>> +		ret = -EFAULT;
>> +
>> +	kfree(data);
>> +	return ret;
>> +}
>> +
>> +static int sev_send_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
>> +{
>> +	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
>> +	struct sev_data_send_start *data;
>> +	struct kvm_sev_send_start params;
>> +	void *amd_certs, *session_data;
>> +	void *pdh_cert, *plat_certs;
>> +	int ret;
>> +
>> +	if (!sev_guest(kvm))
>> +		return -ENOTTY;
>> +
>> +	if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data,
>> +				sizeof(struct kvm_sev_send_start)))
>> +		return -EFAULT;
>> +
>> +	/* if session_len is zero, userspace wants to query the session length */
>> +	if (!params.session_len)
>> +		return __sev_send_start_query_session_length(kvm, argp,
>> +				&params);
>> +
>> +	/* some sanity checks */
>> +	if (!params.pdh_cert_uaddr || !params.pdh_cert_len ||
>> +	    !params.session_uaddr || params.session_len > SEV_FW_BLOB_MAX_SIZE)
>> +		return -EINVAL;
>> +
>> +	/* allocate the memory to hold the session data blob */
>> +	session_data = kmalloc(params.session_len, GFP_KERNEL_ACCOUNT);
>> +	if (!session_data)
>> +		return -ENOMEM;
>> +
>> +	/* copy the certificate blobs from userspace */
>> +	pdh_cert = psp_copy_user_blob(params.pdh_cert_uaddr,
>> +				params.pdh_cert_len);
>> +	if (IS_ERR(pdh_cert)) {
>> +		ret = PTR_ERR(pdh_cert);
>> +		goto e_free_session;
>> +	}
>> +
>> +	plat_certs = psp_copy_user_blob(params.plat_certs_uaddr,
>> +				params.plat_certs_len);
>> +	if (IS_ERR(plat_certs)) {
>> +		ret = PTR_ERR(plat_certs);
>> +		goto e_free_pdh;
>> +	}
>> +
>> +	amd_certs = psp_copy_user_blob(params.amd_certs_uaddr,
>> +				params.amd_certs_len);
>> +	if (IS_ERR(amd_certs)) {
>> +		ret = PTR_ERR(amd_certs);
>> +		goto e_free_plat_cert;
>> +	}
>> +
>> +	data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT);
>> +	if (data == NULL) {
>> +		ret = -ENOMEM;
>> +		goto e_free_amd_cert;
>> +	}
>> +
>> +	/* populate the FW SEND_START field with system physical address */
>> +	data->pdh_cert_address = __psp_pa(pdh_cert);
>> +	data->pdh_cert_len = params.pdh_cert_len;
>> +	data->plat_certs_address = __psp_pa(plat_certs);
>> +	data->plat_certs_len = params.plat_certs_len;
>> +	data->amd_certs_address = __psp_pa(amd_certs);
>> +	data->amd_certs_len = params.amd_certs_len;
>> +	data->session_address = __psp_pa(session_data);
>> +	data->session_len = params.session_len;
>> +	data->handle = sev->handle;
>> +
>> +	ret = sev_issue_cmd(kvm, SEV_CMD_SEND_START, data, &argp->error);
>> +
>> +	if (ret)
>> +		goto e_free;
>> +
>> +	if (copy_to_user((void __user *)(uintptr_t) params.session_uaddr,
>> +			session_data, params.session_len)) {
>> +		ret = -EFAULT;
>> +		goto e_free;
>> +	}
> To optimize the amount of data being copied to user space, could the
> above section of code changed as follows?
>
> 	params.session_len = data->session_len;
> 	if (copy_to_user((void __user *)(uintptr_t) params.session_uaddr,
> 			session_data, params.session_len)) {
> 		ret = -EFAULT;
> 		goto e_free;
> 	}


We should not be using the data->session_len, it will cause -EFAULT when
user has not allocated enough space in the session_uaddr. Lets consider
the case where user passes session_len=10 but firmware thinks the
session length should be 64. In that case the data->session_len will
contains a value of 64 but userspace has allocated space for 10 bytes
and copy_to_user() will fail. If we are really concern about the amount
of data getting copied to userspace then use min_t(size_t,
params.session_len, data->session_len).


>> +
>> +	params.policy = data->policy;
>> +	params.session_len = data->session_len;
>> +	if (copy_to_user((void __user *)(uintptr_t)argp->data, &params,
>> +				sizeof(struct kvm_sev_send_start)))
>> +		ret = -EFAULT;
> Since the only fields that are changed in the kvm_sev_send_start structure
> are session_len and policy, why do we need to copy the entire structure
> back to the user? Why not just those two values? Please see the changes
> proposed to kvm_sev_send_start structure further below to accomplish this.

I think we also need to consider the code readability while saving the
CPU cycles. This is very small structure. By duplicating into two calls
#1 copy params.policy and #2 copy params.session_len we will add more
CPU cycle. And, If we get creative and rearrange the structure then code
readability is lost because now the copy will depend on how the
structure is layout in the memory.

>
> 	params.policy = data->policy;
> 	if (copy_to_user((void __user *)(uintptr_t)argp->data, &params,
> 			sizeof(params.policy) + sizeof(params.session_len))
> 		ret = -EFAULT;
>> +
>> +e_free:
>> +	kfree(data);
>> +e_free_amd_cert:
>> +	kfree(amd_certs);
>> +e_free_plat_cert:
>> +	kfree(plat_certs);
>> +e_free_pdh:
>> +	kfree(pdh_cert);
>> +e_free_session:
>> +	kfree(session_data);
>> +	return ret;
>> +}
>> +
>>  static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
>>  {
>>  	struct kvm_sev_cmd sev_cmd;
>> @@ -7193,6 +7318,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
>>  	case KVM_SEV_LAUNCH_SECRET:
>>  		r = sev_launch_secret(kvm, &sev_cmd);
>>  		break;
>> +	case KVM_SEV_SEND_START:
>> +		r = sev_send_start(kvm, &sev_cmd);
>> +		break;
>>  	default:
>>  		r = -EINVAL;
>>  		goto out;
>> diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
>> index 5167bf2bfc75..9f63b9d48b63 100644
>> --- a/include/linux/psp-sev.h
>> +++ b/include/linux/psp-sev.h
>> @@ -323,11 +323,11 @@ struct sev_data_send_start {
>>  	u64 pdh_cert_address;			/* In */
>>  	u32 pdh_cert_len;			/* In */
>>  	u32 reserved1;
>> -	u64 plat_cert_address;			/* In */
>> -	u32 plat_cert_len;			/* In */
>> +	u64 plat_certs_address;			/* In */
>> +	u32 plat_certs_len;			/* In */
>>  	u32 reserved2;
>> -	u64 amd_cert_address;			/* In */
>> -	u32 amd_cert_len;			/* In */
>> +	u64 amd_certs_address;			/* In */
>> +	u32 amd_certs_len;			/* In */
>>  	u32 reserved3;
>>  	u64 session_address;			/* In */
>>  	u32 session_len;			/* In/Out */
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index 4b95f9a31a2f..17bef4c245e1 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -1558,6 +1558,18 @@ struct kvm_sev_dbg {
>>  	__u32 len;
>>  };
>>  
>> +struct kvm_sev_send_start {
>> +	__u32 policy;
>> +	__u64 pdh_cert_uaddr;
>> +	__u32 pdh_cert_len;
>> +	__u64 plat_certs_uaddr;
>> +	__u32 plat_certs_len;
>> +	__u64 amd_certs_uaddr;
>> +	__u32 amd_certs_len;
>> +	__u64 session_uaddr;
>> +	__u32 session_len;
>> +};
> Redo this structure as below:
>
> struct kvm_sev_send_start {
> 	__u32 policy;
> 	__u32 session_len;
> 	__u64 session_uaddr;
> 	__u64 pdh_cert_uaddr;
> 	__u32 pdh_cert_len;
> 	__u64 plat_certs_uaddr;
> 	__u32 plat_certs_len;
> 	__u64 amd_certs_uaddr;
> 	__u32 amd_certs_len;
> };
>
> Or as below, just to make it look better.
>
> struct kvm_sev_send_start {
> 	__u32 policy;
> 	__u32 session_len;
> 	__u64 session_uaddr;
> 	__u32 pdh_cert_len;
> 	__u64 pdh_cert_uaddr;
> 	__u32 plat_certs_len;
> 	__u64 plat_certs_uaddr;
> 	__u32 amd_certs_len;
> 	__u64 amd_certs_uaddr;
> };
>

Wherever applicable, I tried  best to not divert from the SEV spec
structure layout. Anyone who is reading the SEV FW spec  will see a
similar structure layout in the KVM/PSP header files. I would prefer to
stick to that approach.


>> +
>>  #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
>>  #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
>>  #define KVM_DEV_ASSIGN_MASK_INTX	(1 << 2)
>> -- 
>> 2.17.1
>>

  reply	other threads:[~2020-04-02 13:00 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-30  6:19 [PATCH v6 00/14] Add AMD SEV guest live migration support Ashish Kalra
2020-03-30  6:19 ` [PATCH v6 01/14] KVM: SVM: Add KVM_SEV SEND_START command Ashish Kalra
2020-04-02  6:27   ` Venu Busireddy
2020-04-02 12:59     ` Brijesh Singh [this message]
2020-04-02 16:37       ` Venu Busireddy
2020-04-02 18:04         ` Brijesh Singh
2020-04-02 18:57           ` Venu Busireddy
2020-04-02 19:17             ` Brijesh Singh
2020-04-02 19:43               ` Venu Busireddy
2020-04-02 20:04                 ` Brijesh Singh
2020-04-02 20:19                   ` Venu Busireddy
2020-04-02 17:51   ` Krish Sadhukhan
2020-04-02 18:38     ` Brijesh Singh
2020-03-30  6:20 ` [PATCH v6 02/14] KVM: SVM: Add KVM_SEND_UPDATE_DATA command Ashish Kalra
2020-04-02 17:55   ` Venu Busireddy
2020-04-02 20:13   ` Krish Sadhukhan
2020-03-30  6:20 ` [PATCH v6 03/14] KVM: SVM: Add KVM_SEV_SEND_FINISH command Ashish Kalra
2020-04-02 18:17   ` Venu Busireddy
2020-04-02 20:15   ` Krish Sadhukhan
2020-03-30  6:21 ` [PATCH v6 04/14] KVM: SVM: Add support for KVM_SEV_RECEIVE_START command Ashish Kalra
2020-04-02 21:35   ` Venu Busireddy
2020-04-02 22:09   ` Krish Sadhukhan
2020-03-30  6:21 ` [PATCH v6 05/14] KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command Ashish Kalra
2020-04-02 22:25   ` Krish Sadhukhan
2020-04-02 22:29   ` Venu Busireddy
2020-04-07  0:49     ` Steve Rutherford
2020-03-30  6:21 ` [PATCH v6 06/14] KVM: SVM: Add KVM_SEV_RECEIVE_FINISH command Ashish Kalra
2020-04-02 22:24   ` Venu Busireddy
2020-04-02 22:27   ` Krish Sadhukhan
2020-04-07  0:57     ` Steve Rutherford
2020-03-30  6:21 ` [PATCH v6 07/14] KVM: x86: Add AMD SEV specific Hypercall3 Ashish Kalra
2020-04-02 22:36   ` Venu Busireddy
2020-04-02 23:54   ` Krish Sadhukhan
2020-04-07  1:22     ` Steve Rutherford
2020-03-30  6:22 ` [PATCH v6 08/14] KVM: X86: Introduce KVM_HC_PAGE_ENC_STATUS hypercall Ashish Kalra
2020-04-03  0:00   ` Venu Busireddy
2020-04-03  1:31   ` Krish Sadhukhan
2020-04-03  1:57     ` Ashish Kalra
2020-04-03  2:58       ` Ashish Kalra
2020-04-06 22:27         ` Krish Sadhukhan
2020-04-07  2:17   ` Steve Rutherford
2020-04-07  5:27     ` Ashish Kalra
2020-04-08  0:01       ` Steve Rutherford
2020-04-08  0:29         ` Brijesh Singh
2020-04-08  0:35           ` Steve Rutherford
2020-04-08  1:17             ` Ashish Kalra
2020-04-08  1:38               ` Steve Rutherford
2020-04-08  2:34                 ` Brijesh Singh
2020-04-08  3:18                   ` Ashish Kalra
2020-04-09 16:18                     ` Ashish Kalra
2020-04-09 20:41                       ` Steve Rutherford
2020-03-30  6:22 ` [PATCH v6 09/14] KVM: x86: Introduce KVM_GET_PAGE_ENC_BITMAP ioctl Ashish Kalra
2020-04-03 18:30   ` Venu Busireddy
2020-04-03 20:18   ` Krish Sadhukhan
2020-04-03 20:47     ` Ashish Kalra
2020-04-06 22:07       ` Krish Sadhukhan
2020-04-03 20:55     ` Venu Busireddy
2020-04-03 21:01       ` Ashish Kalra
2020-03-30  6:22 ` [PATCH v6 10/14] mm: x86: Invoke hypercall when page encryption status is changed Ashish Kalra
2020-04-03 21:07   ` Krish Sadhukhan
2020-04-03 21:30     ` Ashish Kalra
2020-04-03 21:36   ` Venu Busireddy
2020-03-30  6:22 ` [PATCH v6 11/14] KVM: x86: Introduce KVM_SET_PAGE_ENC_BITMAP ioctl Ashish Kalra
2020-04-03 21:10   ` Krish Sadhukhan
2020-04-03 21:46   ` Venu Busireddy
2020-04-08  0:26   ` Steve Rutherford
2020-04-08  1:48     ` Ashish Kalra
2020-04-10  0:06       ` Steve Rutherford
2020-04-10  1:23         ` Ashish Kalra
2020-04-10 18:08           ` Steve Rutherford
2020-03-30  6:23 ` [PATCH v6 12/14] KVM: x86: Introduce KVM_PAGE_ENC_BITMAP_RESET ioctl Ashish Kalra
2020-04-03 21:14   ` Krish Sadhukhan
2020-04-03 21:45     ` Ashish Kalra
2020-04-06 18:52       ` Krish Sadhukhan
2020-04-08  1:25         ` Steve Rutherford
2020-04-08  1:52           ` Ashish Kalra
2020-04-10  0:59             ` Steve Rutherford
2020-04-10  1:34               ` Ashish Kalra
2020-04-10 18:14                 ` Steve Rutherford
2020-04-10 20:16                   ` Steve Rutherford
2020-04-10 20:18                     ` Steve Rutherford
2020-04-10 20:55                       ` Kalra, Ashish
2020-04-10 21:42                         ` Brijesh Singh
2020-04-10 21:46                           ` Sean Christopherson
2020-04-10 21:58                             ` Brijesh Singh
2020-04-10 22:02                         ` Brijesh Singh
2020-04-11  0:35                           ` Ashish Kalra
2020-04-03 22:01   ` Venu Busireddy
2020-03-30  6:23 ` [PATCH v6 13/14] KVM: x86: Introduce new KVM_FEATURE_SEV_LIVE_MIGRATION feature & Custom MSR Ashish Kalra
2020-03-30 15:52   ` Brijesh Singh
2020-03-30 16:42     ` Ashish Kalra
     [not found]     ` <20200330162730.GA21567@ashkalra_ubuntu_server>
     [not found]       ` <1de5e95f-4485-f2ff-aba8-aa8b15564796@amd.com>
     [not found]         ` <20200331171336.GA24050@ashkalra_ubuntu_server>
     [not found]           ` <20200401070931.GA8562@ashkalra_ubuntu_server>
2020-04-02 23:29             ` Ashish Kalra
2020-04-03 23:46   ` Krish Sadhukhan
2020-03-30  6:23 ` [PATCH v6 14/14] KVM: x86: Add kexec support for SEV Live Migration Ashish Kalra
2020-03-30 16:00   ` Brijesh Singh
2020-03-30 16:45     ` Ashish Kalra
2020-03-31 14:26       ` Brijesh Singh
2020-04-02 23:34         ` Ashish Kalra
2020-04-03 12:57   ` Dave Young
2020-04-04  0:55   ` Krish Sadhukhan
2020-04-04 21:57     ` Ashish Kalra
2020-04-06 18:37       ` Krish Sadhukhan
2020-03-30 17:24 ` [PATCH v6 00/14] Add AMD SEV guest live migration support Venu Busireddy
2020-03-30 18:28   ` Ashish Kalra
2020-03-30 19:13     ` Venu Busireddy
2020-03-30 21:52       ` Ashish Kalra
2020-03-31 14:42         ` Venu Busireddy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=89a586e4-8074-0d32-f384-a4597975d129@amd.com \
    --to=brijesh.singh@amd.com \
    --cc=Ashish.Kalra@amd.com \
    --cc=bp@suse.de \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rientjes@google.com \
    --cc=srutherford@google.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=venu.busireddy@oracle.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).