From 8f4f8a2071e69130f0b9327ce8f9b92a5ae42c8d Mon Sep 17 00:00:00 2001 From: appleLin Date: Wed, 3 Aug 2022 21:02:41 +0800 Subject: [PATCH] target/i386: sev: Add support for reuse ASID for different CSV guests In you want to reuse one ASID for many CSV guests, you should provide a label (i.e. userid) and the length of the label when launch CSV guest. The CSV guests which were provided the same userid will share the same ASID. Signed-off-by: hanliyang --- linux-headers/linux/kvm.h | 5 +++++ qapi/qom.json | 6 ++++- qemu-options.hx | 5 ++++- target/i386/csv.h | 2 ++ target/i386/sev.c | 46 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index eb30402c2d..8dc00808ec 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -2103,6 +2103,11 @@ struct kvm_csv_command_batch { __u64 csv_batch_list_uaddr; }; +struct kvm_csv_init { + __u64 userid_addr; + __u32 len; +}; + #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) diff --git a/qapi/qom.json b/qapi/qom.json index 213edd8db2..8c7461a113 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -866,6 +866,9 @@ # designated guest firmware page for measured boot with -kernel # (default: false) (since 6.2) # +# @user-id: the user id of the guest owner, only support on Hygon CPUs +# (since 8.2) +# # Since: 2.12 ## { 'struct': 'SevGuestProperties', @@ -876,7 +879,8 @@ '*handle': 'uint32', '*cbitpos': 'uint32', 'reduced-phys-bits': 'uint32', - '*kernel-hashes': 'bool' } } + '*kernel-hashes': 'bool', + '*user-id': 'str' } } ## # @ThreadContextProperties: diff --git a/qemu-options.hx b/qemu-options.hx index 42fd09e4de..9829b1020a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -5637,7 +5637,7 @@ SRST -object secret,id=sec0,keyid=secmaster0,format=base64,\\ data=$SECRET,iv=$(dh_cert_file = g_strdup(value); } +static char * +sev_guest_get_user_id(Object *obj, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + return g_strdup(s->user_id); +} + +static void +sev_guest_set_user_id(Object *obj, const char *value, Error **errp) +{ + SevGuestState *s = SEV_GUEST(obj); + + s->user_id = g_strdup(value); +} + static char * sev_guest_get_sev_device(Object *obj, Error **errp) { @@ -426,6 +443,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) sev_guest_set_kernel_hashes); object_class_property_set_description(oc, "kernel-hashes", "add kernel hashes to guest firmware for measured Linux boot"); + object_class_property_add_str(oc, "user-id", + sev_guest_get_user_id, + sev_guest_set_user_id); + object_class_property_set_description(oc, "user-id", + "user id of the guest owner"); } static void @@ -1174,7 +1196,29 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) } trace_kvm_sev_init(); - ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); + + /* Only support reuse asid for CSV/CSV2 guest */ + if (is_hygon_cpu() && + (sev_guest->policy & GUEST_POLICY_REUSE_ASID)) { + char *user_id = NULL; + struct kvm_csv_init *init_cmd_buf = NULL; + + user_id = object_property_get_str(OBJECT(sev), "user-id", NULL); + if (user_id && strlen(user_id)) { + init_cmd_buf = g_new0(struct kvm_csv_init, 1); + init_cmd_buf->len = strlen(user_id); + init_cmd_buf->userid_addr = (__u64)user_id; + } + ret = sev_ioctl(sev->sev_fd, cmd, init_cmd_buf, &fw_error); + + if (user_id) { + g_free(user_id); + g_free(init_cmd_buf); + } + } else { + ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); + } + if (ret) { error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); -- 2.41.0.windows.1