4 * Copyright Advanced Micro Devices 2016-2018
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include <linux/kvm.h>
17 #include <linux/psp-sev.h>
19 #include <sys/ioctl.h>
21 #include "qapi/error.h"
22 #include "qom/object_interfaces.h"
23 #include "qemu/base64.h"
24 #include "qemu/module.h"
25 #include "sysemu/kvm.h"
27 #include "sysemu/sysemu.h"
28 #include "sysemu/runstate.h"
30 #include "migration/blocker.h"
32 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
33 #define DEFAULT_SEV_DEVICE "/dev/sev"
35 static SEVState *sev_state;
36 static Error *sev_mig_blocker;
38 static const char *const sev_fw_errlist[] = {
40 "Platform state is invalid",
41 "Guest state is invalid",
42 "Platform configuration is invalid",
44 "Platform is already owned",
45 "Certificate is invalid",
46 "Policy is not allowed",
47 "Guest is not active",
51 "Asid is already owned",
54 "DF_FLUSH is required",
55 "Guest handle is invalid",
60 "Feature not supported",
64 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
67 sev_ioctl(int fd, int cmd, void *data, int *error)
70 struct kvm_sev_cmd input;
72 memset(&input, 0x0, sizeof(input));
76 input.data = (__u64)(unsigned long)data;
78 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
88 sev_platform_ioctl(int fd, int cmd, void *data, int *error)
91 struct sev_issue_cmd arg;
94 arg.data = (unsigned long)data;
95 r = ioctl(fd, SEV_ISSUE_CMD, &arg);
104 fw_error_to_str(int code)
106 if (code < 0 || code >= SEV_FW_MAX_ERROR) {
107 return "unknown error";
110 return sev_fw_errlist[code];
114 sev_check_state(SevState state)
117 return sev_state->state == state ? true : false;
121 sev_set_guest_state(SevState new_state)
123 assert(new_state < SEV_STATE__MAX);
126 trace_kvm_sev_change_state(SevState_str(sev_state->state),
127 SevState_str(new_state));
128 sev_state->state = new_state;
132 sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
135 struct kvm_enc_region range;
140 * The RAM device presents a memory region that should be treated
141 * as IO region and should not be pinned.
143 mr = memory_region_from_host(host, &offset);
144 if (mr && memory_region_is_ram_device(mr)) {
148 range.addr = (__u64)(unsigned long)host;
151 trace_kvm_memcrypt_register_region(host, size);
152 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
154 error_report("%s: failed to register region (%p+%#zx) error '%s'",
155 __func__, host, size, strerror(errno));
161 sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
164 struct kvm_enc_region range;
169 * The RAM device presents a memory region that should be treated
170 * as IO region and should not have been pinned.
172 mr = memory_region_from_host(host, &offset);
173 if (mr && memory_region_is_ram_device(mr)) {
177 range.addr = (__u64)(unsigned long)host;
180 trace_kvm_memcrypt_unregister_region(host, size);
181 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
183 error_report("%s: failed to unregister region (%p+%#zx)",
184 __func__, host, size);
188 static struct RAMBlockNotifier sev_ram_notifier = {
189 .ram_block_added = sev_ram_block_added,
190 .ram_block_removed = sev_ram_block_removed,
194 qsev_guest_finalize(Object *obj)
199 qsev_guest_get_session_file(Object *obj, Error **errp)
201 QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
203 return s->session_file ? g_strdup(s->session_file) : NULL;
207 qsev_guest_set_session_file(Object *obj, const char *value, Error **errp)
209 QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
211 s->session_file = g_strdup(value);
215 qsev_guest_get_dh_cert_file(Object *obj, Error **errp)
217 QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
219 return g_strdup(s->dh_cert_file);
223 qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
225 QSevGuestInfo *s = QSEV_GUEST_INFO(obj);
227 s->dh_cert_file = g_strdup(value);
231 qsev_guest_get_sev_device(Object *obj, Error **errp)
233 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
235 return g_strdup(sev->sev_device);
239 qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
241 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
243 sev->sev_device = g_strdup(value);
247 qsev_guest_class_init(ObjectClass *oc, void *data)
249 object_class_property_add_str(oc, "sev-device",
250 qsev_guest_get_sev_device,
251 qsev_guest_set_sev_device);
252 object_class_property_set_description(oc, "sev-device",
253 "SEV device to use");
254 object_class_property_add_str(oc, "dh-cert-file",
255 qsev_guest_get_dh_cert_file,
256 qsev_guest_set_dh_cert_file);
257 object_class_property_set_description(oc, "dh-cert-file",
258 "guest owners DH certificate (encoded with base64)");
259 object_class_property_add_str(oc, "session-file",
260 qsev_guest_get_session_file,
261 qsev_guest_set_session_file);
262 object_class_property_set_description(oc, "session-file",
263 "guest owners session parameters (encoded with base64)");
267 qsev_guest_init(Object *obj)
269 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj);
271 sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
272 sev->policy = DEFAULT_GUEST_POLICY;
273 object_property_add_uint32_ptr(obj, "policy", &sev->policy,
274 OBJ_PROP_FLAG_READWRITE);
275 object_property_add_uint32_ptr(obj, "handle", &sev->handle,
276 OBJ_PROP_FLAG_READWRITE);
277 object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos,
278 OBJ_PROP_FLAG_READWRITE);
279 object_property_add_uint32_ptr(obj, "reduced-phys-bits",
280 &sev->reduced_phys_bits,
281 OBJ_PROP_FLAG_READWRITE);
285 static const TypeInfo qsev_guest_info = {
286 .parent = TYPE_OBJECT,
287 .name = TYPE_QSEV_GUEST_INFO,
288 .instance_size = sizeof(QSevGuestInfo),
289 .instance_finalize = qsev_guest_finalize,
290 .class_size = sizeof(QSevGuestInfoClass),
291 .class_init = qsev_guest_class_init,
292 .instance_init = qsev_guest_init,
293 .interfaces = (InterfaceInfo[]) {
294 { TYPE_USER_CREATABLE },
299 static QSevGuestInfo *
300 lookup_sev_guest_info(const char *id)
305 obj = object_resolve_path_component(object_get_objects_root(), id);
310 info = (QSevGuestInfo *)
311 object_dynamic_cast(obj, TYPE_QSEV_GUEST_INFO);
322 return sev_state ? true : false;
326 sev_get_me_mask(void)
328 return sev_state ? sev_state->me_mask : ~0;
332 sev_get_cbit_position(void)
334 return sev_state ? sev_state->cbitpos : 0;
338 sev_get_reduced_phys_bits(void)
340 return sev_state ? sev_state->reduced_phys_bits : 0;
348 info = g_new0(SevInfo, 1);
349 info->enabled = sev_state ? true : false;
352 info->api_major = sev_state->api_major;
353 info->api_minor = sev_state->api_minor;
354 info->build_id = sev_state->build_id;
355 info->policy = sev_state->policy;
356 info->state = sev_state->state;
357 info->handle = sev_state->handle;
364 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
365 size_t *cert_chain_len)
367 guchar *pdh_data = NULL;
368 guchar *cert_chain_data = NULL;
369 struct sev_user_data_pdh_cert_export export = {};
372 /* query the certificate length */
373 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
375 if (err != SEV_RET_INVALID_LEN) {
376 error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
377 r, err, fw_error_to_str(err));
382 pdh_data = g_new(guchar, export.pdh_cert_len);
383 cert_chain_data = g_new(guchar, export.cert_chain_len);
384 export.pdh_cert_address = (unsigned long)pdh_data;
385 export.cert_chain_address = (unsigned long)cert_chain_data;
387 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
389 error_report("failed to export PDH cert ret=%d fw_err=%d (%s)",
390 r, err, fw_error_to_str(err));
395 *pdh_len = export.pdh_cert_len;
396 *cert_chain = cert_chain_data;
397 *cert_chain_len = export.cert_chain_len;
402 g_free(cert_chain_data);
407 sev_get_capabilities(void)
409 SevCapability *cap = NULL;
410 guchar *pdh_data = NULL;
411 guchar *cert_chain_data = NULL;
412 size_t pdh_len = 0, cert_chain_len = 0;
416 fd = open(DEFAULT_SEV_DEVICE, O_RDWR);
418 error_report("%s: Failed to open %s '%s'", __func__,
419 DEFAULT_SEV_DEVICE, strerror(errno));
423 if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
424 &cert_chain_data, &cert_chain_len)) {
428 cap = g_new0(SevCapability, 1);
429 cap->pdh = g_base64_encode(pdh_data, pdh_len);
430 cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len);
432 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
433 cap->cbitpos = ebx & 0x3f;
436 * When SEV feature is enabled, we loose one bit in guest physical
439 cap->reduced_phys_bits = 1;
443 g_free(cert_chain_data);
449 sev_read_file_base64(const char *filename, guchar **data, gsize *len)
453 GError *error = NULL;
455 if (!g_file_get_contents(filename, &base64, &sz, &error)) {
456 error_report("failed to read '%s' (%s)", filename, error->message);
460 *data = g_base64_decode(base64, len);
465 sev_launch_start(SEVState *s)
470 QSevGuestInfo *sev = s->sev_info;
471 struct kvm_sev_launch_start *start;
472 guchar *session = NULL, *dh_cert = NULL;
474 start = g_new0(struct kvm_sev_launch_start, 1);
476 start->handle = object_property_get_int(OBJECT(sev), "handle",
478 start->policy = object_property_get_int(OBJECT(sev), "policy",
480 if (sev->session_file) {
481 if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
484 start->session_uaddr = (unsigned long)session;
485 start->session_len = sz;
488 if (sev->dh_cert_file) {
489 if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
492 start->dh_uaddr = (unsigned long)dh_cert;
496 trace_kvm_sev_launch_start(start->policy, session, dh_cert);
497 rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
499 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
500 __func__, ret, fw_error, fw_error_to_str(fw_error));
504 object_property_set_int(OBJECT(sev), start->handle, "handle",
506 sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE);
507 s->handle = start->handle;
508 s->policy = start->policy;
519 sev_launch_update_data(uint8_t *addr, uint64_t len)
522 struct kvm_sev_launch_update_data update;
528 update.uaddr = (__u64)(unsigned long)addr;
530 trace_kvm_sev_launch_update_data(addr, len);
531 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
534 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
535 __func__, ret, fw_error, fw_error_to_str(fw_error));
542 sev_launch_get_measure(Notifier *notifier, void *unused)
546 SEVState *s = sev_state;
547 struct kvm_sev_launch_measure *measurement;
549 if (!sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
553 measurement = g_new0(struct kvm_sev_launch_measure, 1);
555 /* query the measurement blob length */
556 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE,
557 measurement, &error);
558 if (!measurement->len) {
559 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
560 __func__, ret, error, fw_error_to_str(errno));
561 goto free_measurement;
564 data = g_new0(guchar, measurement->len);
565 measurement->uaddr = (unsigned long)data;
567 /* get the measurement blob */
568 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE,
569 measurement, &error);
571 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
572 __func__, ret, error, fw_error_to_str(errno));
576 sev_set_guest_state(SEV_STATE_LAUNCH_SECRET);
578 /* encode the measurement value and emit the event */
579 s->measurement = g_base64_encode(data, measurement->len);
580 trace_kvm_sev_launch_measurement(s->measurement);
589 sev_get_launch_measurement(void)
592 sev_state->state >= SEV_STATE_LAUNCH_SECRET) {
593 return g_strdup(sev_state->measurement);
599 static Notifier sev_machine_done_notify = {
600 .notify = sev_launch_get_measure,
604 sev_launch_finish(SEVState *s)
607 Error *local_err = NULL;
609 trace_kvm_sev_launch_finish();
610 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error);
612 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
613 __func__, ret, error, fw_error_to_str(error));
617 sev_set_guest_state(SEV_STATE_RUNNING);
619 /* add migration blocker */
620 error_setg(&sev_mig_blocker,
621 "SEV: Migration is not implemented");
622 ret = migrate_add_blocker(sev_mig_blocker, &local_err);
624 error_report_err(local_err);
625 error_free(sev_mig_blocker);
631 sev_vm_state_change(void *opaque, int running, RunState state)
633 SEVState *s = opaque;
636 if (!sev_check_state(SEV_STATE_RUNNING)) {
637 sev_launch_finish(s);
643 sev_guest_init(const char *id)
649 uint32_t host_cbitpos;
650 struct sev_user_data_status status = {};
652 sev_state = s = g_new0(SEVState, 1);
653 s->sev_info = lookup_sev_guest_info(id);
655 error_report("%s: '%s' is not a valid '%s' object",
656 __func__, id, TYPE_QSEV_GUEST_INFO);
660 s->state = SEV_STATE_UNINIT;
662 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
663 host_cbitpos = ebx & 0x3f;
665 s->cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL);
666 if (host_cbitpos != s->cbitpos) {
667 error_report("%s: cbitpos check failed, host '%d' requested '%d'",
668 __func__, host_cbitpos, s->cbitpos);
672 s->reduced_phys_bits = object_property_get_int(OBJECT(s->sev_info),
673 "reduced-phys-bits", NULL);
674 if (s->reduced_phys_bits < 1) {
675 error_report("%s: reduced_phys_bits check failed, it should be >=1,"
676 " requested '%d'", __func__, s->reduced_phys_bits);
680 s->me_mask = ~(1UL << s->cbitpos);
682 devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL);
683 s->sev_fd = open(devname, O_RDWR);
685 error_report("%s: Failed to open %s '%s'", __func__,
686 devname, strerror(errno));
693 ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status,
696 error_report("%s: failed to get platform status ret=%d "
697 "fw_error='%d: %s'", __func__, ret, fw_error,
698 fw_error_to_str(fw_error));
701 s->build_id = status.build;
702 s->api_major = status.api_major;
703 s->api_minor = status.api_minor;
705 trace_kvm_sev_init();
706 ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error);
708 error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
709 __func__, ret, fw_error, fw_error_to_str(fw_error));
713 ret = sev_launch_start(s);
715 error_report("%s: failed to create encryption context", __func__);
719 ram_block_notifier_add(&sev_ram_notifier);
720 qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
721 qemu_add_vm_change_state_handler(sev_vm_state_change, s);
731 sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
735 /* if SEV is in update state then encrypt the data else do nothing */
736 if (sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
737 return sev_launch_update_data(ptr, len);
744 sev_register_types(void)
746 type_register_static(&qsev_guest_info);
749 type_init(sev_register_types);