178 lines
5.8 KiB
Diff
178 lines
5.8 KiB
Diff
|
|
From 8f4f8a2071e69130f0b9327ce8f9b92a5ae42c8d Mon Sep 17 00:00:00 2001
|
||
|
|
From: appleLin <appleLin@hygon.cn>
|
||
|
|
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 <hanliyang@hygon.cn>
|
||
|
|
---
|
||
|
|
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=$(<iv.b64)
|
||
|
|
|
||
|
|
- ``-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file,kernel-hashes=on|off]``
|
||
|
|
+ ``-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file,kernel-hashes=on|off,user-id=id]``
|
||
|
|
Create a Secure Encrypted Virtualization (SEV) guest object,
|
||
|
|
which can be used to provide the guest memory encryption support
|
||
|
|
on AMD processors.
|
||
|
|
@@ -5681,6 +5681,9 @@ SRST
|
||
|
|
cmdline to a designated guest firmware page for measured Linux
|
||
|
|
boot with -kernel. The default is off. (Since 6.2)
|
||
|
|
|
||
|
|
+ The ``user-id`` set the user id of the guest owner, this only
|
||
|
|
+ support on Hygon CPUs. (Since 8.2)
|
||
|
|
+
|
||
|
|
e.g to launch a SEV guest
|
||
|
|
|
||
|
|
.. parsed-literal::
|
||
|
|
diff --git a/target/i386/csv.h b/target/i386/csv.h
|
||
|
|
index ac4bb5bee1..05e7fd8dc1 100644
|
||
|
|
--- a/target/i386/csv.h
|
||
|
|
+++ b/target/i386/csv.h
|
||
|
|
@@ -14,6 +14,8 @@
|
||
|
|
#ifndef I386_CSV_H
|
||
|
|
#define I386_CSV_H
|
||
|
|
|
||
|
|
+#define GUEST_POLICY_REUSE_ASID (1 << 7)
|
||
|
|
+
|
||
|
|
#ifdef CONFIG_CSV
|
||
|
|
|
||
|
|
#include "cpu.h"
|
||
|
|
diff --git a/target/i386/sev.c b/target/i386/sev.c
|
||
|
|
index 04888bc3a8..af61ca5ba8 100644
|
||
|
|
--- a/target/i386/sev.c
|
||
|
|
+++ b/target/i386/sev.c
|
||
|
|
@@ -72,6 +72,7 @@ struct SevGuestState {
|
||
|
|
uint32_t cbitpos;
|
||
|
|
uint32_t reduced_phys_bits;
|
||
|
|
bool kernel_hashes;
|
||
|
|
+ char *user_id;
|
||
|
|
|
||
|
|
/* runtime state */
|
||
|
|
uint32_t handle;
|
||
|
|
@@ -373,6 +374,22 @@ sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
|
||
|
|
s->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
|
||
|
|
|