On Mon, Mar 09, 2020 at 06:41:02PM -0700, Steve Rutherford wrote: > > +static int sev_receive_start(struct kvm *kvm, struct kvm_sev_cmd *argp) > > +{ > > + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; > > + struct sev_data_receive_start *start; > > + struct kvm_sev_receive_start params; > > + int *error = &argp->error; > > + void *session_data; > > + void *pdh_data; > > + int ret; > > + > > + if (!sev_guest(kvm)) > > + return -ENOTTY; > > + > > + /* Get parameter from the userspace */ > > + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, > > + sizeof(struct kvm_sev_receive_start))) > > + return -EFAULT; > > + > > + /* some sanity checks */ > > + if (!params.pdh_uaddr || !params.pdh_len || > > + !params.session_uaddr || !params.session_len) > > + return -EINVAL; > > + > > + pdh_data = psp_copy_user_blob(params.pdh_uaddr, params.pdh_len); > > + if (IS_ERR(pdh_data)) > > + return PTR_ERR(pdh_data); > > + > > + session_data = psp_copy_user_blob(params.session_uaddr, > > + params.session_len); > > + if (IS_ERR(session_data)) { > > + ret = PTR_ERR(session_data); > > + goto e_free_pdh; > > + } > > + > > + ret = -ENOMEM; > > + start = kzalloc(sizeof(*start), GFP_KERNEL); > > + if (!start) > > + goto e_free_session; > > + > > + start->handle = params.handle; > > + start->policy = params.policy; > > + start->pdh_cert_address = __psp_pa(pdh_data); > > + start->pdh_cert_len = params.pdh_len; > > + start->session_address = __psp_pa(session_data); > > + start->session_len = params.session_len; > > + > > + /* create memory encryption context */ > > Set ret to a different value here, since otherwise this will look like -ENOMEM. But, ret will be the value returned by __sev_issue_cmd(), so why will it look like -ENOMEM ? > > > + ret = __sev_issue_cmd(argp->sev_fd, SEV_CMD_RECEIVE_START, start, > > + error); > > + if (ret) > > + goto e_free; > > + > > + /* Bind ASID to this guest */ > > Ideally, set ret to another distinct value, since the error spaces for > these commands overlap, so you won't be sure which had the problem. > You also wouldn't be sure if one succeeded and the other failed vs > both failing. Both commands "may" return the same error code as set by sev_do_cmd(), but then we need that very specific error code, sev_do_cmd() can't return different error codes for each command it is issuing ? > > > + ret = sev_bind_asid(kvm, start->handle, error); > > + if (ret) > > + goto e_free; > > + Thanks, Ashish