@@ -5713,31 +5713,6 @@ static int sev_issue_cmd(int fd, int id, void *data, int *error)
return ret;
}
-static void *copy_user_blob(u64 __user uaddr, u32 len)
-{
- void *data;
-
- if (!uaddr || !len)
- return ERR_PTR(-EINVAL);
-
- /* verify that blob length does not exceed our limit */
- if (len > SEV_FW_BLOB_MAX_SIZE)
- return ERR_PTR(-EINVAL);
-
- data = kmalloc(len, GFP_KERNEL);
- if (!data)
- return ERR_PTR(-ENOMEM);
-
- if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len))
- goto e_free;
-
- return data;
-
-e_free:
- kfree(data);
- return ERR_PTR(-EFAULT);
-}
-
static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
{
struct kvm_sev_info *sev = &kvm->arch.sev_info;
@@ -5750,8 +5725,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
if (!sev_guest(kvm))
return -ENOTTY;
- if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data,
- sizeof(struct kvm_sev_launch_start)))
+ if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params)))
return -EFAULT;
start = kzalloc(sizeof(*start), GFP_KERNEL);
@@ -5760,7 +5734,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
dh_blob = NULL;
if (params.dh_uaddr) {
- dh_blob = copy_user_blob(params.dh_uaddr, params.dh_len);
+ dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len);
if (IS_ERR(dh_blob)) {
ret = PTR_ERR(dh_blob);
goto e_free;
@@ -5772,7 +5746,7 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
session_blob = NULL;
if (params.session_uaddr) {
- dh_blob = copy_user_blob(params.session_uaddr, params.session_len);
+ dh_blob = psp_copy_user_blob(params.session_uaddr, params.session_len);
if (IS_ERR(session_blob)) {
ret = PTR_ERR(session_blob);
goto e_free_dh;
@@ -5797,8 +5771,8 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
/* return handle to userspace */
params.handle = start->handle;
- if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms,
- sizeof(struct kvm_sev_launch_start))) {
+ ret = copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, sizeof(params));
+ if (ret) {
sev_unbind_asid(kvm, start->handle);
ret = -EFAULT;
goto e_free_session;
@@ -5834,10 +5808,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
r = sev_guest_init(kvm, &sev_cmd);
break;
- case KVM_SEV_LAUNCH_START: {
+ case KVM_SEV_LAUNCH_START:
r = sev_launch_start(kvm, &sev_cmd);
break;
- }
default:
break;
@@ -377,7 +377,7 @@ static int sev_ioctl_pek_csr(struct sev_issue_cmd *argp)
return ret;
}
-static void *copy_user_blob(u64 __user uaddr, u32 len)
+void *psp_copy_user_blob(u64 __user uaddr, u32 len)
{
void *data;
@@ -392,7 +392,7 @@ static void *copy_user_blob(u64 __user uaddr, u32 len)
if (!data)
return ERR_PTR(-ENOMEM);
- if (copy_from_user(data, (void __user *)uaddr, len))
+ if (copy_from_user(data, (void __user *)(uintptr_t)uaddr, len))
goto e_free;
return data;
@@ -401,6 +401,7 @@ static void *copy_user_blob(u64 __user uaddr, u32 len)
kfree(data);
return ERR_PTR(-EFAULT);
}
+EXPORT_SYMBOL_GPL(psp_copy_user_blob);
static int sev_ioctl_pek_cert_import(struct sev_issue_cmd *argp)
{
@@ -417,7 +418,7 @@ static int sev_ioctl_pek_cert_import(struct sev_issue_cmd *argp)
return -ENOMEM;
/* copy PEK certificate blobs from userspace */
- pek_blob = copy_user_blob(input.pek_cert_address, input.pek_cert_len);
+ pek_blob = psp_copy_user_blob(input.pek_cert_address, input.pek_cert_len);
if (IS_ERR(pek_blob)) {
ret = PTR_ERR(pek_blob);
goto e_free;
@@ -427,7 +428,7 @@ static int sev_ioctl_pek_cert_import(struct sev_issue_cmd *argp)
data->pek_cert_len = input.pek_cert_len;
/* copy PEK certificate blobs from userspace */
- oca_blob = copy_user_blob(input.oca_cert_address, input.oca_cert_len);
+ oca_blob = psp_copy_user_blob(input.oca_cert_address, input.oca_cert_len);
if (IS_ERR(oca_blob)) {
ret = PTR_ERR(oca_blob);
goto e_free_pek;
@@ -638,6 +638,7 @@ int sev_guest_df_flush(int *error);
* -%EIO if the sev returned a non-zero return code
*/
int sev_guest_decommission(struct sev_data_decommission *data, int *error);
+void *psp_copy_user_blob(u64 __user uaddr, u32 len);
#else /* !CONFIG_CRYPTO_DEV_SP_PSP */
@@ -667,6 +668,8 @@ sev_issue_cmd_external_user(struct file *filep,
return -ENODEV;
}
+static inline void *psp_copy_user_blob(u64 __user uaddr, u32 len) { return ERR_PTR(-EINVAL); }
+
#endif /* CONFIG_CRYPTO_DEV_SP_PSP */
#endif /* __PSP_SEV_H__ */