diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index 84aad306dc7957924a6990d864c9886e45323631..ed00786f42518b505774d30069e7d7a9be98d247 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -209,9 +209,12 @@ static void pc_system_flash_map(PCMachineState *pcms, exit(1); } - if (csv_enabled()) + if (csv_enabled()) { + if (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM) + csv3_set_guest_private_memory(&error_fatal); + csv_load_data(flash_mem->addr, flash_ptr, flash_size, &error_fatal); - else + } else sev_encrypt_flash(flash_ptr, flash_size, &error_fatal); } } diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 3875127a375d412c6d8f4f5db5f3017cd0df6a4c..02bba131e6c9cb0634e1d428f4c06da1e27db692 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1155,6 +1155,13 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_ZPCI_OP 221 #define KVM_CAP_S390_CPU_TOPOLOGY 222 #define KVM_CAP_SEV_ES_GHCB 500 +#define KVM_CAP_HYGON_COCO_EXT 501 +/* support userspace to request firmware to build CSV3 guest's memory space */ +#define KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM (1 << 0) +/* support request to update CSV3 guest's memory region multiple times */ +#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) #define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE) @@ -1943,43 +1950,34 @@ struct kvm_sev_receive_update_vmsa { __u32 trans_len; }; -/* CSV command */ -enum csv_cmd_id { - KVM_CSV_NR_MIN = 0xc0, +/* CSV3 command */ +enum csv3_cmd_id { + KVM_CSV3_NR_MIN = 0xc0, - KVM_CSV_INIT = KVM_CSV_NR_MIN, - KVM_CSV_LAUNCH_ENCRYPT_DATA, - KVM_CSV_LAUNCH_ENCRYPT_VMCB, - KVM_CSV_SEND_ENCRYPT_DATA, - KVM_CSV_SEND_ENCRYPT_CONTEXT, - KVM_CSV_RECEIVE_ENCRYPT_DATA, - KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, + KVM_CSV3_INIT = KVM_CSV3_NR_MIN, + KVM_CSV3_LAUNCH_ENCRYPT_DATA, + KVM_CSV3_LAUNCH_ENCRYPT_VMCB, + KVM_CSV3_SEND_ENCRYPT_DATA, + KVM_CSV3_SEND_ENCRYPT_CONTEXT, + KVM_CSV3_RECEIVE_ENCRYPT_DATA, + KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, - KVM_CSV_NR_MAX, + KVM_CSV3_SET_GUEST_PRIVATE_MEMORY = 0xc8, + + KVM_CSV3_NR_MAX, }; -struct kvm_csv_launch_encrypt_data { +struct kvm_csv3_launch_encrypt_data { __u64 gpa; __u64 uaddr; __u32 len; }; -struct kvm_csv_init_data { +struct kvm_csv3_init_data { __u64 nodemask; }; -struct kvm_csv_batch_list_node { - __u64 cmd_data_addr; - __u64 addr; - __u64 next_cmd_addr; -}; - -struct kvm_csv_command_batch { - __u32 command_id; - __u64 csv_batch_list_uaddr; -}; - -struct kvm_csv_send_encrypt_data { +struct kvm_csv3_send_encrypt_data { __u64 hdr_uaddr; __u32 hdr_len; __u64 guest_addr_data; @@ -1988,14 +1986,14 @@ struct kvm_csv_send_encrypt_data { __u32 trans_len; }; -struct kvm_csv_send_encrypt_context { +struct kvm_csv3_send_encrypt_context { __u64 hdr_uaddr; __u32 hdr_len; __u64 trans_uaddr; __u32 trans_len; }; -struct kvm_csv_receive_encrypt_data { +struct kvm_csv3_receive_encrypt_data { __u64 hdr_uaddr; __u32 hdr_len; __u64 guest_addr_data; @@ -2004,13 +2002,24 @@ struct kvm_csv_receive_encrypt_data { __u32 trans_len; }; -struct kvm_csv_receive_encrypt_context { +struct kvm_csv3_receive_encrypt_context { __u64 hdr_uaddr; __u32 hdr_len; __u64 trans_uaddr; __u32 trans_len; }; +struct kvm_csv_batch_list_node { + __u64 cmd_data_addr; + __u64 addr; + __u64 next_cmd_addr; +}; + +struct kvm_csv_command_batch { + __u32 command_id; + __u64 csv_batch_list_uaddr; +}; + struct kvm_csv_init { __u64 userid_addr; __u32 len; diff --git a/qapi/qom.json b/qapi/qom.json index 387c0a142df10ffeb50314cc567b65d187569e47..a2ac0ae33e380a666af51eb1ab29da35e09aa9c0 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -775,6 +775,11 @@ # # @user-id: the user id of the guest owner, only support on Hygon CPUs # +# @secret-header-file: the header file of guest owner's secret, only +# support on Hygon CPUs (since 6.2) +# @secret-file: the file guest owner's secret, only support on Hygon +# CPUs (since 6.2) +# # Since: 2.12 ## { 'struct': 'SevGuestProperties', @@ -786,7 +791,9 @@ '*cbitpos': 'uint32', 'reduced-phys-bits': 'uint32', '*kernel-hashes': 'bool', - '*user-id': 'str' } } + '*user-id': 'str', + '*secret-header-file': 'str', + '*secret-file': 'str' } } ## # @ObjectType: diff --git a/qemu-options.hx b/qemu-options.hx index c3c070de6f031ccbc4f3f3fcea2325743260d2b2..453d220226bdbbe3a967619335ff3cf11ab4b9b8 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -5189,7 +5189,7 @@ SRST -object secret,id=sec0,keyid=secmaster0,format=base64,\\ data=$SECRET,iv=$(sev_ioctl(fd, KVM_CSV_INIT, &data, &fw_error); + ret = ops->sev_ioctl(fd, KVM_CSV3_INIT, &data, &fw_error); if (ret) { csv_guest.policy = 0; error_report("%s: Fail to initialize ret=%d fw_error=%d '%s'", @@ -104,13 +107,13 @@ csv_enabled(void) } static bool -csv_check_state(SevState state) +csv3_check_state(SevState state) { return *((SevState *)csv_guest.state) == state ? true : false; } static int -csv_ioctl(int cmd, void *data, int *error) +csv3_ioctl(int cmd, void *data, int *error) { if (csv_guest.sev_ioctl) return csv_guest.sev_ioctl(csv_guest.sev_fd, cmd, data, error); @@ -131,7 +134,7 @@ static int csv_launch_encrypt_data(uint64_t gpa, uint8_t *addr, uint64_t len) { int ret, fw_error; - struct kvm_csv_launch_encrypt_data update; + struct kvm_csv3_launch_encrypt_data update; if (!addr || !len) { return 1; @@ -140,8 +143,8 @@ csv_launch_encrypt_data(uint64_t gpa, uint8_t *addr, uint64_t len) update.gpa = (__u64)gpa; update.uaddr = (__u64)(unsigned long)addr; update.len = len; - trace_kvm_csv_launch_encrypt_data(gpa, addr, len); - ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_DATA, &update, &fw_error); + trace_kvm_csv3_launch_encrypt_data(gpa, addr, len); + ret = csv3_ioctl(KVM_CSV3_LAUNCH_ENCRYPT_DATA, &update, &fw_error); if (ret) { error_report("%s: CSV LAUNCH_ENCRYPT_DATA ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); @@ -161,7 +164,7 @@ csv_load_data(uint64_t gpa, uint8_t *ptr, uint64_t len, Error **errp) } /* if CSV is in update state then load the data to secure memory */ - if (csv_check_state(SEV_STATE_LAUNCH_UPDATE)) { + if (csv3_check_state(SEV_STATE_LAUNCH_UPDATE)) { ret = csv_launch_encrypt_data(gpa, ptr, len); if (ret) error_setg(errp, "%s: CSV fail to encrypt data", __func__); @@ -180,7 +183,7 @@ csv_launch_encrypt_vmcb(void) return -1; } - ret = csv_ioctl(KVM_CSV_LAUNCH_ENCRYPT_VMCB, NULL, &fw_error); + ret = csv3_ioctl(KVM_CSV3_LAUNCH_ENCRYPT_VMCB, NULL, &fw_error); if (ret) { error_report("%s: CSV LAUNCH_ENCRYPT_VMCB ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); @@ -344,11 +347,11 @@ static int csv_send_get_packet_len(int *fw_err) { int ret; - struct kvm_csv_send_encrypt_data update = {0}; + struct kvm_csv3_send_encrypt_data update = {0}; update.hdr_len = 0; update.trans_len = 0; - ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, fw_err); + ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_DATA, &update, fw_err); if (*fw_err != SEV_RET_INVALID_LEN) { error_report("%s: failed to get session length ret=%d fw_error=%d '%s'", __func__, ret, *fw_err, fw_error_to_str(*fw_err)); @@ -373,7 +376,7 @@ csv_send_encrypt_data(CsvGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size guchar *trans; uint32_t guest_addr_entry_num; uint32_t i; - struct kvm_csv_send_encrypt_data update = { }; + struct kvm_csv3_send_encrypt_data update = { }; /* * If this is first call then query the packet header bytes and allocate @@ -407,9 +410,9 @@ csv_send_encrypt_data(CsvGuestState *s, QEMUFile *f, uint8_t *ptr, uint32_t size update.trans_uaddr = (uintptr_t)trans; update.trans_len = guest_addr_entry_num * TARGET_PAGE_SIZE; - trace_kvm_csv_send_encrypt_data(trans, update.trans_len); + trace_kvm_csv3_send_encrypt_data(trans, update.trans_len); - ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_DATA, &update, &fw_error); + ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_DATA, &update, &fw_error); if (ret) { error_report("%s: SEND_ENCRYPT_DATA ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); @@ -478,7 +481,7 @@ csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent) * If this is a first buffer then create outgoing encryption context * and write our PDH, policy and session data. */ - if (!csv_check_state(SEV_STATE_SEND_UPDATE) && + if (!csv3_check_state(SEV_STATE_SEND_UPDATE) && csv_send_start(f, bytes_sent)) { error_report("Failed to create outgoing context"); return 1; @@ -502,7 +505,7 @@ static int csv_receive_encrypt_data(QEMUFile *f, uint8_t *ptr) uint32_t i, guest_addr_entry_num; gchar *hdr = NULL, *trans = NULL; struct guest_addr_entry *guest_addr_data; - struct kvm_csv_receive_encrypt_data update = {}; + struct kvm_csv3_receive_encrypt_data update = {}; void *hva = NULL; MemoryRegion *mr = NULL; @@ -540,9 +543,9 @@ static int csv_receive_encrypt_data(QEMUFile *f, uint8_t *ptr) } } - trace_kvm_csv_receive_encrypt_data(trans, update.trans_len, hdr, update.hdr_len); + trace_kvm_csv3_receive_encrypt_data(trans, update.trans_len, hdr, update.hdr_len); - ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_DATA, &update, &fw_error); + ret = csv3_ioctl(KVM_CSV3_RECEIVE_ENCRYPT_DATA, &update, &fw_error); if (ret) { error_report("Error RECEIVE_ENCRYPT_DATA ret=%d fw_error=%d '%s'", ret, fw_error, fw_error_to_str(fw_error)); @@ -562,7 +565,7 @@ int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr) * If this is first buffer and SEV is not in recieiving state then * use RECEIVE_START command to create a encryption context. */ - if (!csv_check_state(SEV_STATE_RECEIVE_UPDATE) && + if (!csv3_check_state(SEV_STATE_RECEIVE_UPDATE) && csv_receive_start(f)) { return 1; } @@ -574,9 +577,9 @@ static int csv_send_get_context_len(int *fw_err, int *context_len, int *hdr_len) { int ret = 0; - struct kvm_csv_send_encrypt_context update = {}; + struct kvm_csv3_send_encrypt_context update = {}; - ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, fw_err); + ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_CONTEXT, &update, fw_err); if (*fw_err != SEV_RET_INVALID_LEN) { error_report("%s: failed to get context length ret=%d fw_error=%d '%s'", __func__, ret, *fw_err, fw_error_to_str(*fw_err)); @@ -601,7 +604,7 @@ csv_send_encrypt_context(CsvGuestState *s, QEMUFile *f) int hdr_len = 0; guchar *trans; guchar *hdr; - struct kvm_csv_send_encrypt_context update = { }; + struct kvm_csv3_send_encrypt_context update = { }; ret = csv_send_get_context_len(&fw_error, &context_len, &hdr_len); if (context_len < 1 || hdr_len < 1) { @@ -619,9 +622,9 @@ csv_send_encrypt_context(CsvGuestState *s, QEMUFile *f) update.trans_uaddr = (uintptr_t)trans; update.trans_len = context_len; - trace_kvm_csv_send_encrypt_context(trans, update.trans_len); + trace_kvm_csv3_send_encrypt_context(trans, update.trans_len); - ret = csv_ioctl(KVM_CSV_SEND_ENCRYPT_CONTEXT, &update, &fw_error); + ret = csv3_ioctl(KVM_CSV3_SEND_ENCRYPT_CONTEXT, &update, &fw_error); if (ret) { error_report("%s: SEND_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); @@ -645,7 +648,7 @@ csv_receive_encrypt_context(CsvGuestState *s, QEMUFile *f) { int ret = 1, fw_error = 0; gchar *hdr = NULL, *trans = NULL; - struct kvm_csv_receive_encrypt_context update = {}; + struct kvm_csv3_receive_encrypt_context update = {}; /* get packet header */ update.hdr_len = qemu_get_be32(f); @@ -661,9 +664,9 @@ csv_receive_encrypt_context(CsvGuestState *s, QEMUFile *f) update.trans_uaddr = (uintptr_t)trans; qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len); - trace_kvm_csv_receive_encrypt_context(trans, update.trans_len, hdr, update.hdr_len); + trace_kvm_csv3_receive_encrypt_context(trans, update.trans_len, hdr, update.hdr_len); - ret = csv_ioctl(KVM_CSV_RECEIVE_ENCRYPT_CONTEXT, &update, &fw_error); + ret = csv3_ioctl(KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, &update, &fw_error); if (ret) { error_report("Error RECEIVE_ENCRYPT_CONTEXT ret=%d fw_error=%d '%s'", ret, fw_error, fw_error_to_str(fw_error)); @@ -691,3 +694,24 @@ int csv3_load_incoming_context(QEMUFile *f) /* receive csv context. */ return csv_receive_encrypt_context(s, f); } + +int csv3_set_guest_private_memory(Error **errp) +{ + int fw_error; + int ret = 0; + + if (!csv_enabled()) { + error_setg(errp, "%s: CSV3 is not enabled", __func__); + return -1; + } + + /* if CSV3 is in update state then load the data to secure memory */ + if (csv3_check_state(SEV_STATE_LAUNCH_UPDATE)) { + trace_kvm_csv3_set_guest_private_memory(); + ret = csv3_ioctl(KVM_CSV3_SET_GUEST_PRIVATE_MEMORY, NULL, &fw_error); + if (ret) + error_setg(errp, "%s: CSV3 fail set private memory", __func__); + } + + return ret; +} diff --git a/target/i386/csv.h b/target/i386/csv.h index 86f46d30c2cdc924dcee5023a0738f741d2eb1f6..485534d2d69a36ba6c81e93797c96095b9ef0565 100644 --- a/target/i386/csv.h +++ b/target/i386/csv.h @@ -67,6 +67,9 @@ struct dma_map_region { #define CSV3_OUTGOING_PAGE_WINDOW_SIZE (512 * TARGET_PAGE_SIZE) +extern uint32_t kvm_hygon_coco_ext; +extern uint32_t kvm_hygon_coco_ext_inuse; + struct guest_addr_entry { uint64_t share: 1; uint64_t reserved: 11; @@ -112,4 +115,6 @@ int csv3_load_incoming_page(QEMUFile *f, uint8_t *ptr); int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); +int csv3_set_guest_private_memory(Error **errp); + #endif diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index cecc3d035d8ccdabfba25eb896ee83263e3d3f67..469349420ca709000432757c8f1e6d2ace1b7538 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -2455,6 +2455,23 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } + if (is_hygon_cpu()) { + /* check and enable Hygon coco extensions */ + kvm_hygon_coco_ext = (uint32_t)kvm_vm_check_extension(s, + KVM_CAP_HYGON_COCO_EXT); + if (kvm_hygon_coco_ext) { + ret = kvm_vm_enable_cap(s, KVM_CAP_HYGON_COCO_EXT, 0, + (uint64_t)kvm_hygon_coco_ext); + if (ret == -EINVAL) { + error_report("kvm: Failed to enable KVM_CAP_HYGON_COCO_EXT cap: %s", + strerror(-ret)); + kvm_hygon_coco_ext_inuse = 0; + } else { + kvm_hygon_coco_ext_inuse = (uint32_t)ret; + } + } + } + ret = kvm_get_supported_msrs(s); if (ret < 0) { return ret; diff --git a/target/i386/sev.c b/target/i386/sev.c index 813f0de716115e9f31158bf51218842865727ec9..94d3c1853b64479e9865ddcf01f03ff07b94f70f 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -83,6 +83,8 @@ struct SevGuestState { uint32_t reduced_phys_bits; bool kernel_hashes; char *user_id; + char *secret_header_file; + char *secret_file; /* runtime state */ uint32_t handle; @@ -400,6 +402,38 @@ sev_guest_set_user_id(Object *obj, const char *value, Error **errp) s->user_id = g_strdup(value); } +static char * +sev_guest_get_secret_header_file(Object *obj, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + return g_strdup(s->secret_header_file); +} + +static void +sev_guest_set_secret_header_file(Object *obj, const char *value, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + s->secret_header_file = g_strdup(value); +} + +static char * +sev_guest_get_secret_file(Object *obj, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + return g_strdup(s->secret_file); +} + +static void +sev_guest_set_secret_file(Object *obj, const char *value, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + s->secret_file = g_strdup(value); +} + static char * sev_guest_get_sev_device(Object *obj, Error **errp) { @@ -458,6 +492,16 @@ sev_guest_class_init(ObjectClass *oc, void *data) sev_guest_set_user_id); object_class_property_set_description(oc, "user-id", "user id of the guest owner"); + object_class_property_add_str(oc, "secret-header-file", + sev_guest_get_secret_header_file, + sev_guest_set_secret_header_file); + object_class_property_set_description(oc, "secret-header-file", + "header file of the guest owner's secret"); + object_class_property_add_str(oc, "secret-file", + sev_guest_get_secret_file, + sev_guest_set_secret_file); + object_class_property_set_description(oc, "secret-file", + "file of the guest owner's secret"); } static void @@ -836,6 +880,9 @@ sev_launch_update_vmsa(SevGuestState *sev) return ret; } +static int +csv_load_launch_secret(const char *secret_header_file, const char *secret_file); + static void sev_launch_get_measure(Notifier *notifier, void *unused) { @@ -885,6 +932,15 @@ sev_launch_get_measure(Notifier *notifier, void *unused) /* encode the measurement value and emit the event */ sev->measurement = g_base64_encode(data, measurement.len); trace_kvm_sev_launch_measurement(sev->measurement); + + /* Hygon CSV will auto load guest owner's secret */ + if (is_hygon_cpu()) { + if (sev->secret_header_file && + strlen(sev->secret_header_file) && + sev->secret_file && + strlen(sev->secret_file)) + csv_load_launch_secret(sev->secret_header_file, sev->secret_file); + } } static char *sev_get_launch_measurement(void) @@ -1317,7 +1373,17 @@ int sev_inject_launch_secret(const char *packet_hdr, const char *secret, input.trans_uaddr = (uint64_t)(unsigned long)data; input.trans_len = data_sz; - input.guest_uaddr = (uint64_t)(unsigned long)hva; + /* For Hygon CSV3 guest, the guest_uaddr should be the gpa */ + if (csv_enabled()) { + if (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET) { + input.guest_uaddr = gpa; + } else { + error_setg(errp, "CSV3 inject secret unsupported!"); + return 1; + } + } else { + input.guest_uaddr = (uint64_t)(unsigned long)hva; + } input.guest_len = data_sz; trace_kvm_sev_launch_secret(gpa, input.guest_uaddr, @@ -2479,6 +2545,50 @@ int csv_load_incoming_cpu_state(QEMUFile *f) return ret; } +static int +csv_load_launch_secret(const char *secret_header_file, const char *secret_file) +{ + gsize secret_header_size, secret_size; + gchar *secret_header = NULL, *secret = NULL; + uint8_t *data; + struct sev_secret_area *area; + uint64_t gpa; + GError *error = NULL; + Error *local_err = NULL; + int ret = 0; + + if (!g_file_get_contents(secret_header_file, + &secret_header, + &secret_header_size, &error)) { + error_report("CSV: Failed to read '%s' (%s)", + secret_header_file, error->message); + g_error_free(error); + return -1; + } + + if (!g_file_get_contents(secret_file, &secret, &secret_size, &error)) { + error_report("CSV: Failed to read '%s' (%s)", secret_file, error->message); + g_error_free(error); + return -1; + } + + if (!pc_system_ovmf_table_find(SEV_SECRET_GUID, &data, NULL)) { + error_report("CSV: no secret area found in OVMF, gpa must be" + " specified."); + return -1; + } + area = (struct sev_secret_area *)data; + gpa = area->base; + + ret = sev_inject_launch_secret((char *)secret_header, + (char *)secret, gpa, &local_err); + + if (local_err) { + error_report_err(local_err); + } + return ret; +} + static const QemuUUID sev_hash_table_header_guid = { .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, 0xd4, 0x11, 0xfd, 0x21) @@ -2601,7 +2711,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) /* zero the excess data so the measurement can be reliably calculated */ memset(padded_ht->padding, 0, sizeof(padded_ht->padding)); - if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { + if (csv_enabled()) { + if (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA) { + if (csv_load_data(area->base, (uint8_t *)padded_ht, + sizeof(*padded_ht), errp) < 0) { + ret = false; + } + } else { + error_report("%s: CSV3 load kernel hashes unsupported!", __func__); + ret = false; + } + } else if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { ret = false; } diff --git a/target/i386/trace-events b/target/i386/trace-events index 47ab390de6983123665d61c3d94aaf078bfd4ae5..0610d5ea8fdf213e103f37a636ae2ba8f9207b25 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -21,8 +21,9 @@ kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" # csv.c -kvm_csv_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIu64 -kvm_csv_send_encrypt_data(void *dst, int len) "trans %p len %d" -kvm_csv_send_encrypt_context(void *dst, int len) "trans %p len %d" -kvm_csv_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" -kvm_csv_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIx64 +kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" +kvm_csv3_send_encrypt_context(void *dst, int len) "trans %p len %d" +kvm_csv3_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +kvm_csv3_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" +kvm_csv3_set_guest_private_memory(void) ""