@@ -39,12 +39,12 @@
#include "qemu/main-loop.h"
#include "trace.h"
#include "hw/irq.h"
-#include "sysemu/sev.h"
#include "sysemu/balloon.h"
#include "qapi/visitor.h"
#include "qapi/qapi-types-common.h"
#include "qapi/qapi-visit-common.h"
#include "sysemu/reset.h"
+#include "exec/host-trust-limitation.h"
#include "hw/boards.h"
@@ -118,9 +118,8 @@ struct KVMState
KVMMemoryListener memory_listener;
QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
- /* memory encryption */
- void *memcrypt_handle;
- int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);
+ /* host trust limitation (e.g. by guest memory encryption) */
+ HostTrustLimitation *htl;
/* For "info mtree -f" to tell if an MR is registered in KVM */
int nr_as;
@@ -222,7 +221,7 @@ int kvm_get_max_memslots(void)
bool kvm_memcrypt_enabled(void)
{
- if (kvm_state && kvm_state->memcrypt_handle) {
+ if (kvm_state && kvm_state->htl) {
return true;
}
@@ -231,10 +230,12 @@ bool kvm_memcrypt_enabled(void)
int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
{
- if (kvm_state->memcrypt_handle &&
- kvm_state->memcrypt_encrypt_data) {
- return kvm_state->memcrypt_encrypt_data(kvm_state->memcrypt_handle,
- ptr, len);
+ HostTrustLimitation *htl = kvm_state->htl;
+
+ if (htl) {
+ HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_GET_CLASS(htl);
+
+ return htlc->encrypt_data(htl, ptr, len);
}
return 1;
@@ -2180,13 +2181,24 @@ static int kvm_init(MachineState *ms)
* encryption context.
*/
if (ms->memory_encryption) {
- kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption);
- if (!kvm_state->memcrypt_handle) {
+ Object *obj = object_resolve_path_component(object_get_objects_root(),
+ ms->memory_encryption);
+
+ if (object_dynamic_cast(obj, TYPE_HOST_TRUST_LIMITATION)) {
+ HostTrustLimitation *htl = HOST_TRUST_LIMITATION(obj);
+ HostTrustLimitationClass *htlc
+ = HOST_TRUST_LIMITATION_GET_CLASS(htl);
+
+ ret = htlc->kvm_init(htl);
+ if (ret < 0) {
+ goto err;
+ }
+
+ kvm_state->htl = htl;
+ } else {
ret = -1;
goto err;
}
-
- kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
}
ret = kvm_arch_init(ms, s);
@@ -15,12 +15,7 @@
#include "qemu-common.h"
#include "sysemu/sev.h"
-int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
-{
- abort();
-}
-
-void *sev_guest_init(const char *id)
+HostTrustLimitation *sev_guest_init(const char *id)
{
return NULL;
}
@@ -28,6 +28,9 @@
typedef struct HostTrustLimitationClass {
InterfaceClass parent;
+
+ int (*kvm_init)(HostTrustLimitation *);
+ int (*encrypt_data)(HostTrustLimitation *, uint8_t *, uint64_t);
} HostTrustLimitationClass;
#endif /* QEMU_HOST_TRUST_LIMITATION_H */
@@ -16,6 +16,6 @@
#include "sysemu/kvm.h"
-void *sev_guest_init(const char *id);
-int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
+HostTrustLimitation *sev_guest_init(const char *id);
+
#endif
@@ -28,6 +28,7 @@
#include "sysemu/runstate.h"
#include "trace.h"
#include "migration/blocker.h"
+#include "exec/host-trust-limitation.h"
#define TYPE_SEV_GUEST "sev-guest"
#define SEV_GUEST(obj) \
@@ -281,26 +282,6 @@ sev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
sev->sev_device = g_strdup(value);
}
-static void
-sev_guest_class_init(ObjectClass *oc, void *data)
-{
- object_class_property_add_str(oc, "sev-device",
- sev_guest_get_sev_device,
- sev_guest_set_sev_device);
- object_class_property_set_description(oc, "sev-device",
- "SEV device to use");
- object_class_property_add_str(oc, "dh-cert-file",
- sev_guest_get_dh_cert_file,
- sev_guest_set_dh_cert_file);
- object_class_property_set_description(oc, "dh-cert-file",
- "guest owners DH certificate (encoded with base64)");
- object_class_property_add_str(oc, "session-file",
- sev_guest_get_session_file,
- sev_guest_set_session_file);
- object_class_property_set_description(oc, "session-file",
- "guest owners session parameters (encoded with base64)");
-}
-
static void
sev_guest_instance_init(Object *obj)
{
@@ -319,40 +300,6 @@ sev_guest_instance_init(Object *obj)
OBJ_PROP_FLAG_READWRITE);
}
-/* sev guest info */
-static const TypeInfo sev_guest_info = {
- .parent = TYPE_OBJECT,
- .name = TYPE_SEV_GUEST,
- .instance_size = sizeof(SevGuestState),
- .instance_finalize = sev_guest_finalize,
- .class_init = sev_guest_class_init,
- .instance_init = sev_guest_instance_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_USER_CREATABLE },
- { }
- }
-};
-
-static SevGuestState *
-lookup_sev_guest_info(const char *id)
-{
- Object *obj;
- SevGuestState *info;
-
- obj = object_resolve_path_component(object_get_objects_root(), id);
- if (!obj) {
- return NULL;
- }
-
- info = (SevGuestState *)
- object_dynamic_cast(obj, TYPE_SEV_GUEST);
- if (!info) {
- return NULL;
- }
-
- return info;
-}
-
bool
sev_enabled(void)
{
@@ -670,23 +617,15 @@ sev_vm_state_change(void *opaque, int running, RunState state)
}
}
-void *
-sev_guest_init(const char *id)
+static int sev_kvm_init(HostTrustLimitation *htl)
{
- SevGuestState *sev;
+ SevGuestState *sev = SEV_GUEST(htl);
char *devname;
int ret, fw_error;
uint32_t ebx;
uint32_t host_cbitpos;
struct sev_user_data_status status = {};
- sev = lookup_sev_guest_info(id);
- if (!sev) {
- error_report("%s: '%s' is not a valid '%s' object",
- __func__, id, TYPE_SEV_GUEST);
- goto err;
- }
-
sev_guest = sev;
sev->state = SEV_STATE_UNINIT;
@@ -748,16 +687,16 @@ sev_guest_init(const char *id)
qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
qemu_add_vm_change_state_handler(sev_vm_state_change, sev);
- return sev;
+ return 0;
err:
sev_guest = NULL;
- return NULL;
+ return -1;
}
-int
-sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
+static int
+sev_encrypt_data(HostTrustLimitation *opaque, uint8_t *ptr, uint64_t len)
{
- SevGuestState *sev = handle;
+ SevGuestState *sev = SEV_GUEST(opaque);
assert(sev);
@@ -769,6 +708,46 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
return 0;
}
+static void
+sev_guest_class_init(ObjectClass *oc, void *data)
+{
+ HostTrustLimitationClass *htlc = HOST_TRUST_LIMITATION_CLASS(oc);
+
+ object_class_property_add_str(oc, "sev-device",
+ sev_guest_get_sev_device,
+ sev_guest_set_sev_device);
+ object_class_property_set_description(oc, "sev-device",
+ "SEV device to use");
+ object_class_property_add_str(oc, "dh-cert-file",
+ sev_guest_get_dh_cert_file,
+ sev_guest_set_dh_cert_file);
+ object_class_property_set_description(oc, "dh-cert-file",
+ "guest owners DH certificate (encoded with base64)");
+ object_class_property_add_str(oc, "session-file",
+ sev_guest_get_session_file,
+ sev_guest_set_session_file);
+ object_class_property_set_description(oc, "session-file",
+ "guest owners session parameters (encoded with base64)");
+
+ htlc->kvm_init = sev_kvm_init;
+ htlc->encrypt_data = sev_encrypt_data;
+}
+
+/* sev guest info */
+static const TypeInfo sev_guest_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_SEV_GUEST,
+ .instance_size = sizeof(SevGuestState),
+ .instance_finalize = sev_guest_finalize,
+ .class_init = sev_guest_class_init,
+ .instance_init = sev_guest_instance_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOST_TRUST_LIMITATION },
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
static void
sev_register_types(void)
{