diff --git a/arch/x86/kvm/svm/csv.c b/arch/x86/kvm/svm/csv.c index ff418c87ea9b6f0a0c7000e83c760fa2575f2bd2..58d246294008b02066db19139c694fa3a6ecdbbf 100644 --- a/arch/x86/kvm/svm/csv.c +++ b/arch/x86/kvm/svm/csv.c @@ -1633,6 +1633,35 @@ static int csv3_launch_encrypt_vmcb(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static int csv3_launch_finish_ex(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + struct kvm_csv_info *csv = &to_kvm_svm_csv(kvm)->csv_info; + struct kvm_csv3_launch_finish_ex params; + struct csv3_data_launch_finish_ex *finish_ex = NULL; + int ret = 0; + + if (!csv3_guest(kvm) || + !(csv->inuse_ext & KVM_CAP_HYGON_COCO_EXT_CSV3_LFINISH_EX)) + return -ENOTTY; + + if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, + sizeof(params))) + return -EFAULT; + + finish_ex = kzalloc(sizeof(*finish_ex), GFP_KERNEL); + if (!finish_ex) + return -ENOMEM; + + finish_ex->handle = csv->sev->handle; + memcpy(finish_ex->host_data, params.host_data, KVM_CSV3_HOST_DATA_SIZE); + ret = hygon_kvm_hooks.sev_issue_cmd(kvm, CSV3_CMD_LAUNCH_FINISH_EX, + finish_ex, &argp->error); + + kfree(finish_ex); + + return ret; +} + /* Userspace wants to query either header or trans length. */ static int csv3_send_encrypt_data_query_lengths(struct kvm *kvm, struct kvm_sev_cmd *argp, @@ -2776,6 +2805,9 @@ static int csv_mem_enc_ioctl(struct kvm *kvm, void __user *argp) case KVM_CSV3_LAUNCH_ENCRYPT_VMCB: r = csv3_launch_encrypt_vmcb(kvm, &sev_cmd); break; + case KVM_CSV3_LAUNCH_FINISH_EX: + r = csv3_launch_finish_ex(kvm, &sev_cmd); + break; case KVM_CSV3_SEND_ENCRYPT_DATA: r = csv3_send_encrypt_data(kvm, &sev_cmd); break; @@ -3106,6 +3138,8 @@ static int csv_get_hygon_coco_extension(struct kvm *kvm) csv->kvm_ext |= KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA; if (csv->fw_ext & CSV_EXT_CSV3_INJ_SECRET) csv->kvm_ext |= KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET; + if (csv->fw_ext & CSV_EXT_CSV3_LFINISH_EX) + csv->kvm_ext |= KVM_CAP_HYGON_COCO_EXT_CSV3_LFINISH_EX; } csv->kvm_ext_valid = true; } diff --git a/drivers/crypto/ccp/hygon/csv-dev.c b/drivers/crypto/ccp/hygon/csv-dev.c index 203dc6933864a3c4a919e65012eb7d425e53e1b2..dd317b3341cc892eb8564521d471b38abbaa930b 100644 --- a/drivers/crypto/ccp/hygon/csv-dev.c +++ b/drivers/crypto/ccp/hygon/csv-dev.c @@ -66,6 +66,7 @@ int csv_cmd_buffer_len(int cmd) case CSV3_CMD_RECEIVE_ENCRYPT_DATA: return sizeof(struct csv3_data_receive_encrypt_data); case CSV3_CMD_RECEIVE_ENCRYPT_CONTEXT: + case CSV3_CMD_LAUNCH_FINISH_EX: return sizeof(struct csv3_data_launch_finish_ex); return sizeof(struct csv3_data_receive_encrypt_context); default: return 0; } @@ -680,6 +681,12 @@ int csv_get_extension_info(void *buf, size_t *size) *(uint32_t *)buf |= CSV_EXT_CSV3_INJ_SECRET; } + /* Since firmware with build id 2393, support: + * c. issue CSV3_LAUNCH_FINISH_EX command + */ + if (csv_version_greater_or_equal(2393)) + *(uint32_t *)buf |= CSV_EXT_CSV3_LFINISH_EX; + return 0; } EXPORT_SYMBOL_GPL(csv_get_extension_info); diff --git a/include/linux/psp-hygon.h b/include/linux/psp-hygon.h index 5f03517a4d0b0e6fbf5196fedc1444a0668e5cb4..1b49e6f8635a5d52dd2ede480964f209b1917c61 100644 --- a/include/linux/psp-hygon.h +++ b/include/linux/psp-hygon.h @@ -24,6 +24,8 @@ #define CSV_EXT_CSV3_MULT_LUP_DATA (1 << CSV_EXT_CSV3_MULT_LUP_DATA_BIT) #define CSV_EXT_CSV3_INJ_SECRET_BIT 1 #define CSV_EXT_CSV3_INJ_SECRET (1 << CSV_EXT_CSV3_INJ_SECRET_BIT) +#define CSV_EXT_CSV3_LFINISH_EX_BIT 2 +#define CSV_EXT_CSV3_LFINISH_EX (1 << CSV_EXT_CSV3_LFINISH_EX_BIT) /** * Guest/platform management commands for CSV @@ -42,6 +44,7 @@ enum csv3_cmd { CSV3_CMD_SET_GUEST_PRIVATE_MEMORY = 0x200, CSV3_CMD_LAUNCH_ENCRYPT_DATA = 0x201, CSV3_CMD_LAUNCH_ENCRYPT_VMCB = 0x202, + CSV3_CMD_LAUNCH_FINISH_EX = 0x204, /* Guest NPT(Nested Page Table) management commands */ CSV3_CMD_UPDATE_NPT = 0x203, @@ -207,6 +210,21 @@ struct csv3_data_launch_encrypt_vmcb { u32 secure_vmcb_len; /* Out */ } __packed; +/** + * struct csv3_data_launch_finish_ex - CSV3_CMD_LAUNCH_FINISH_EX command + * + * @handle: handle assigned to the VM + * @reserved0: reserved field, for future use + * @host_data: the host supplied data + * @reserved1: reserved field, for future use + */ +struct csv3_data_launch_finish_ex { + u32 handle; /* In */ + u32 reserved0; /* In */ + u8 host_data[64]; /* In */ + u8 reserved1[184]; /* In */ +} __packed; + /** * struct csv3_data_update_npt - CSV3_CMD_UPDATE_NPT command * diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 8f28b9ca4a3c9514aaae4ed5fb9d41ae1937a586..9cf50a383e1f33af0c2f157d297623eb620e44b5 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1239,6 +1239,8 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA (1 << 1) /* support request to inject secret to CSV3 guest */ #define KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET (1 << 2) +/* support finish launch process by CSV3_CMD_LAUNCH_FINISH_EX firmware API */ +#define KVM_CAP_HYGON_COCO_EXT_CSV3_LFINISH_EX (1 << 3) #ifdef KVM_CAP_IRQ_ROUTING @@ -2376,6 +2378,7 @@ enum csv3_cmd_id { KVM_CSV3_HANDLE_MEMORY, KVM_CSV3_SET_GUEST_PRIVATE_MEMORY = 0xc8, + KVM_CSV3_LAUNCH_FINISH_EX = 0xc9, KVM_CSV3_NR_MAX, }; @@ -2390,6 +2393,13 @@ struct kvm_csv3_launch_encrypt_data { __u32 len; }; +#define KVM_CSV3_HOST_DATA_SIZE 64 + +struct kvm_csv3_launch_finish_ex { + __u8 host_data[KVM_CSV3_HOST_DATA_SIZE]; + __u8 pad[16]; +}; + struct kvm_csv3_send_encrypt_data { __u64 hdr_uaddr; __u32 hdr_len;