1 /* 2 * QEMU SEV support 3 * 4 * Copyright Advanced Micro Devices 2016-2018 5 * 6 * Author: 7 * Brijesh Singh <brijesh.singh@amd.com> 8 * 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. 11 * 12 */ 13 14 #include "qemu/osdep.h" 15 16 #include <linux/kvm.h> 17 #include <linux/psp-sev.h> 18 19 #include <sys/ioctl.h> 20 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" 26 #include "sev_i386.h" 27 #include "sysemu/sysemu.h" 28 #include "trace.h" 29 #include "migration/blocker.h" 30 31 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ 32 #define DEFAULT_SEV_DEVICE "/dev/sev" 33 34 static SEVState *sev_state; 35 static Error *sev_mig_blocker; 36 37 static const char *const sev_fw_errlist[] = { 38 "", 39 "Platform state is invalid", 40 "Guest state is invalid", 41 "Platform configuration is invalid", 42 "Buffer too small", 43 "Platform is already owned", 44 "Certificate is invalid", 45 "Policy is not allowed", 46 "Guest is not active", 47 "Invalid address", 48 "Bad signature", 49 "Bad measurement", 50 "Asid is already owned", 51 "Invalid ASID", 52 "WBINVD is required", 53 "DF_FLUSH is required", 54 "Guest handle is invalid", 55 "Invalid command", 56 "Guest is active", 57 "Hardware error", 58 "Hardware unsafe", 59 "Feature not supported", 60 "Invalid parameter" 61 }; 62 63 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) 64 65 static int 66 sev_ioctl(int fd, int cmd, void *data, int *error) 67 { 68 int r; 69 struct kvm_sev_cmd input; 70 71 memset(&input, 0x0, sizeof(input)); 72 73 input.id = cmd; 74 input.sev_fd = fd; 75 input.data = (__u64)(unsigned long)data; 76 77 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input); 78 79 if (error) { 80 *error = input.error; 81 } 82 83 return r; 84 } 85 86 static int 87 sev_platform_ioctl(int fd, int cmd, void *data, int *error) 88 { 89 int r; 90 struct sev_issue_cmd arg; 91 92 arg.cmd = cmd; 93 arg.data = (unsigned long)data; 94 r = ioctl(fd, SEV_ISSUE_CMD, &arg); 95 if (error) { 96 *error = arg.error; 97 } 98 99 return r; 100 } 101 102 static const char * 103 fw_error_to_str(int code) 104 { 105 if (code < 0 || code >= SEV_FW_MAX_ERROR) { 106 return "unknown error"; 107 } 108 109 return sev_fw_errlist[code]; 110 } 111 112 static bool 113 sev_check_state(SevState state) 114 { 115 assert(sev_state); 116 return sev_state->state == state ? true : false; 117 } 118 119 static void 120 sev_set_guest_state(SevState new_state) 121 { 122 assert(new_state < SEV_STATE__MAX); 123 assert(sev_state); 124 125 trace_kvm_sev_change_state(SevState_str(sev_state->state), 126 SevState_str(new_state)); 127 sev_state->state = new_state; 128 } 129 130 static void 131 sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) 132 { 133 int r; 134 struct kvm_enc_region range; 135 ram_addr_t offset; 136 MemoryRegion *mr; 137 138 /* 139 * The RAM device presents a memory region that should be treated 140 * as IO region and should not be pinned. 141 */ 142 mr = memory_region_from_host(host, &offset); 143 if (mr && memory_region_is_ram_device(mr)) { 144 return; 145 } 146 147 range.addr = (__u64)(unsigned long)host; 148 range.size = size; 149 150 trace_kvm_memcrypt_register_region(host, size); 151 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range); 152 if (r) { 153 error_report("%s: failed to register region (%p+%#zx) error '%s'", 154 __func__, host, size, strerror(errno)); 155 exit(1); 156 } 157 } 158 159 static void 160 sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size) 161 { 162 int r; 163 struct kvm_enc_region range; 164 ram_addr_t offset; 165 MemoryRegion *mr; 166 167 /* 168 * The RAM device presents a memory region that should be treated 169 * as IO region and should not have been pinned. 170 */ 171 mr = memory_region_from_host(host, &offset); 172 if (mr && memory_region_is_ram_device(mr)) { 173 return; 174 } 175 176 range.addr = (__u64)(unsigned long)host; 177 range.size = size; 178 179 trace_kvm_memcrypt_unregister_region(host, size); 180 r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range); 181 if (r) { 182 error_report("%s: failed to unregister region (%p+%#zx)", 183 __func__, host, size); 184 } 185 } 186 187 static struct RAMBlockNotifier sev_ram_notifier = { 188 .ram_block_added = sev_ram_block_added, 189 .ram_block_removed = sev_ram_block_removed, 190 }; 191 192 static void 193 qsev_guest_finalize(Object *obj) 194 { 195 } 196 197 static char * 198 qsev_guest_get_session_file(Object *obj, Error **errp) 199 { 200 QSevGuestInfo *s = QSEV_GUEST_INFO(obj); 201 202 return s->session_file ? g_strdup(s->session_file) : NULL; 203 } 204 205 static void 206 qsev_guest_set_session_file(Object *obj, const char *value, Error **errp) 207 { 208 QSevGuestInfo *s = QSEV_GUEST_INFO(obj); 209 210 s->session_file = g_strdup(value); 211 } 212 213 static char * 214 qsev_guest_get_dh_cert_file(Object *obj, Error **errp) 215 { 216 QSevGuestInfo *s = QSEV_GUEST_INFO(obj); 217 218 return g_strdup(s->dh_cert_file); 219 } 220 221 static void 222 qsev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp) 223 { 224 QSevGuestInfo *s = QSEV_GUEST_INFO(obj); 225 226 s->dh_cert_file = g_strdup(value); 227 } 228 229 static char * 230 qsev_guest_get_sev_device(Object *obj, Error **errp) 231 { 232 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 233 234 return g_strdup(sev->sev_device); 235 } 236 237 static void 238 qsev_guest_set_sev_device(Object *obj, const char *value, Error **errp) 239 { 240 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 241 242 sev->sev_device = g_strdup(value); 243 } 244 245 static void 246 qsev_guest_class_init(ObjectClass *oc, void *data) 247 { 248 object_class_property_add_str(oc, "sev-device", 249 qsev_guest_get_sev_device, 250 qsev_guest_set_sev_device, 251 NULL); 252 object_class_property_set_description(oc, "sev-device", 253 "SEV device to use", NULL); 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 NULL); 258 object_class_property_set_description(oc, "dh-cert-file", 259 "guest owners DH certificate (encoded with base64)", NULL); 260 object_class_property_add_str(oc, "session-file", 261 qsev_guest_get_session_file, 262 qsev_guest_set_session_file, 263 NULL); 264 object_class_property_set_description(oc, "session-file", 265 "guest owners session parameters (encoded with base64)", NULL); 266 } 267 268 static void 269 qsev_guest_set_handle(Object *obj, Visitor *v, const char *name, 270 void *opaque, Error **errp) 271 { 272 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 273 uint32_t value; 274 275 visit_type_uint32(v, name, &value, errp); 276 sev->handle = value; 277 } 278 279 static void 280 qsev_guest_set_policy(Object *obj, Visitor *v, const char *name, 281 void *opaque, Error **errp) 282 { 283 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 284 uint32_t value; 285 286 visit_type_uint32(v, name, &value, errp); 287 sev->policy = value; 288 } 289 290 static void 291 qsev_guest_set_cbitpos(Object *obj, Visitor *v, const char *name, 292 void *opaque, Error **errp) 293 { 294 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 295 uint32_t value; 296 297 visit_type_uint32(v, name, &value, errp); 298 sev->cbitpos = value; 299 } 300 301 static void 302 qsev_guest_set_reduced_phys_bits(Object *obj, Visitor *v, const char *name, 303 void *opaque, Error **errp) 304 { 305 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 306 uint32_t value; 307 308 visit_type_uint32(v, name, &value, errp); 309 sev->reduced_phys_bits = value; 310 } 311 312 static void 313 qsev_guest_get_policy(Object *obj, Visitor *v, const char *name, 314 void *opaque, Error **errp) 315 { 316 uint32_t value; 317 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 318 319 value = sev->policy; 320 visit_type_uint32(v, name, &value, errp); 321 } 322 323 static void 324 qsev_guest_get_handle(Object *obj, Visitor *v, const char *name, 325 void *opaque, Error **errp) 326 { 327 uint32_t value; 328 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 329 330 value = sev->handle; 331 visit_type_uint32(v, name, &value, errp); 332 } 333 334 static void 335 qsev_guest_get_cbitpos(Object *obj, Visitor *v, const char *name, 336 void *opaque, Error **errp) 337 { 338 uint32_t value; 339 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 340 341 value = sev->cbitpos; 342 visit_type_uint32(v, name, &value, errp); 343 } 344 345 static void 346 qsev_guest_get_reduced_phys_bits(Object *obj, Visitor *v, const char *name, 347 void *opaque, Error **errp) 348 { 349 uint32_t value; 350 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 351 352 value = sev->reduced_phys_bits; 353 visit_type_uint32(v, name, &value, errp); 354 } 355 356 static void 357 qsev_guest_init(Object *obj) 358 { 359 QSevGuestInfo *sev = QSEV_GUEST_INFO(obj); 360 361 sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE); 362 sev->policy = DEFAULT_GUEST_POLICY; 363 object_property_add(obj, "policy", "uint32", qsev_guest_get_policy, 364 qsev_guest_set_policy, NULL, NULL, NULL); 365 object_property_add(obj, "handle", "uint32", qsev_guest_get_handle, 366 qsev_guest_set_handle, NULL, NULL, NULL); 367 object_property_add(obj, "cbitpos", "uint32", qsev_guest_get_cbitpos, 368 qsev_guest_set_cbitpos, NULL, NULL, NULL); 369 object_property_add(obj, "reduced-phys-bits", "uint32", 370 qsev_guest_get_reduced_phys_bits, 371 qsev_guest_set_reduced_phys_bits, NULL, NULL, NULL); 372 } 373 374 /* sev guest info */ 375 static const TypeInfo qsev_guest_info = { 376 .parent = TYPE_OBJECT, 377 .name = TYPE_QSEV_GUEST_INFO, 378 .instance_size = sizeof(QSevGuestInfo), 379 .instance_finalize = qsev_guest_finalize, 380 .class_size = sizeof(QSevGuestInfoClass), 381 .class_init = qsev_guest_class_init, 382 .instance_init = qsev_guest_init, 383 .interfaces = (InterfaceInfo[]) { 384 { TYPE_USER_CREATABLE }, 385 { } 386 } 387 }; 388 389 static QSevGuestInfo * 390 lookup_sev_guest_info(const char *id) 391 { 392 Object *obj; 393 QSevGuestInfo *info; 394 395 obj = object_resolve_path_component(object_get_objects_root(), id); 396 if (!obj) { 397 return NULL; 398 } 399 400 info = (QSevGuestInfo *) 401 object_dynamic_cast(obj, TYPE_QSEV_GUEST_INFO); 402 if (!info) { 403 return NULL; 404 } 405 406 return info; 407 } 408 409 bool 410 sev_enabled(void) 411 { 412 return sev_state ? true : false; 413 } 414 415 uint64_t 416 sev_get_me_mask(void) 417 { 418 return sev_state ? sev_state->me_mask : ~0; 419 } 420 421 uint32_t 422 sev_get_cbit_position(void) 423 { 424 return sev_state ? sev_state->cbitpos : 0; 425 } 426 427 uint32_t 428 sev_get_reduced_phys_bits(void) 429 { 430 return sev_state ? sev_state->reduced_phys_bits : 0; 431 } 432 433 SevInfo * 434 sev_get_info(void) 435 { 436 SevInfo *info; 437 438 info = g_new0(SevInfo, 1); 439 info->enabled = sev_state ? true : false; 440 441 if (info->enabled) { 442 info->api_major = sev_state->api_major; 443 info->api_minor = sev_state->api_minor; 444 info->build_id = sev_state->build_id; 445 info->policy = sev_state->policy; 446 info->state = sev_state->state; 447 info->handle = sev_state->handle; 448 } 449 450 return info; 451 } 452 453 static int 454 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain, 455 size_t *cert_chain_len) 456 { 457 guchar *pdh_data = NULL; 458 guchar *cert_chain_data = NULL; 459 struct sev_user_data_pdh_cert_export export = {}; 460 int err, r; 461 462 /* query the certificate length */ 463 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err); 464 if (r < 0) { 465 if (err != SEV_RET_INVALID_LEN) { 466 error_report("failed to export PDH cert ret=%d fw_err=%d (%s)", 467 r, err, fw_error_to_str(err)); 468 return 1; 469 } 470 } 471 472 pdh_data = g_new(guchar, export.pdh_cert_len); 473 cert_chain_data = g_new(guchar, export.cert_chain_len); 474 export.pdh_cert_address = (unsigned long)pdh_data; 475 export.cert_chain_address = (unsigned long)cert_chain_data; 476 477 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err); 478 if (r < 0) { 479 error_report("failed to export PDH cert ret=%d fw_err=%d (%s)", 480 r, err, fw_error_to_str(err)); 481 goto e_free; 482 } 483 484 *pdh = pdh_data; 485 *pdh_len = export.pdh_cert_len; 486 *cert_chain = cert_chain_data; 487 *cert_chain_len = export.cert_chain_len; 488 return 0; 489 490 e_free: 491 g_free(pdh_data); 492 g_free(cert_chain_data); 493 return 1; 494 } 495 496 SevCapability * 497 sev_get_capabilities(void) 498 { 499 SevCapability *cap = NULL; 500 guchar *pdh_data = NULL; 501 guchar *cert_chain_data = NULL; 502 size_t pdh_len = 0, cert_chain_len = 0; 503 uint32_t ebx; 504 int fd; 505 506 fd = open(DEFAULT_SEV_DEVICE, O_RDWR); 507 if (fd < 0) { 508 error_report("%s: Failed to open %s '%s'", __func__, 509 DEFAULT_SEV_DEVICE, strerror(errno)); 510 return NULL; 511 } 512 513 if (sev_get_pdh_info(fd, &pdh_data, &pdh_len, 514 &cert_chain_data, &cert_chain_len)) { 515 goto out; 516 } 517 518 cap = g_new0(SevCapability, 1); 519 cap->pdh = g_base64_encode(pdh_data, pdh_len); 520 cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len); 521 522 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); 523 cap->cbitpos = ebx & 0x3f; 524 525 /* 526 * When SEV feature is enabled, we loose one bit in guest physical 527 * addressing. 528 */ 529 cap->reduced_phys_bits = 1; 530 531 out: 532 g_free(pdh_data); 533 g_free(cert_chain_data); 534 close(fd); 535 return cap; 536 } 537 538 static int 539 sev_read_file_base64(const char *filename, guchar **data, gsize *len) 540 { 541 gsize sz; 542 gchar *base64; 543 GError *error = NULL; 544 545 if (!g_file_get_contents(filename, &base64, &sz, &error)) { 546 error_report("failed to read '%s' (%s)", filename, error->message); 547 return -1; 548 } 549 550 *data = g_base64_decode(base64, len); 551 return 0; 552 } 553 554 static int 555 sev_launch_start(SEVState *s) 556 { 557 gsize sz; 558 int ret = 1; 559 int fw_error, rc; 560 QSevGuestInfo *sev = s->sev_info; 561 struct kvm_sev_launch_start *start; 562 guchar *session = NULL, *dh_cert = NULL; 563 564 start = g_new0(struct kvm_sev_launch_start, 1); 565 566 start->handle = object_property_get_int(OBJECT(sev), "handle", 567 &error_abort); 568 start->policy = object_property_get_int(OBJECT(sev), "policy", 569 &error_abort); 570 if (sev->session_file) { 571 if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { 572 goto out; 573 } 574 start->session_uaddr = (unsigned long)session; 575 start->session_len = sz; 576 } 577 578 if (sev->dh_cert_file) { 579 if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { 580 goto out; 581 } 582 start->dh_uaddr = (unsigned long)dh_cert; 583 start->dh_len = sz; 584 } 585 586 trace_kvm_sev_launch_start(start->policy, session, dh_cert); 587 rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); 588 if (rc < 0) { 589 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", 590 __func__, ret, fw_error, fw_error_to_str(fw_error)); 591 goto out; 592 } 593 594 object_property_set_int(OBJECT(sev), start->handle, "handle", 595 &error_abort); 596 sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE); 597 s->handle = start->handle; 598 s->policy = start->policy; 599 ret = 0; 600 601 out: 602 g_free(start); 603 g_free(session); 604 g_free(dh_cert); 605 return ret; 606 } 607 608 static int 609 sev_launch_update_data(uint8_t *addr, uint64_t len) 610 { 611 int ret, fw_error; 612 struct kvm_sev_launch_update_data update; 613 614 if (!addr || !len) { 615 return 1; 616 } 617 618 update.uaddr = (__u64)(unsigned long)addr; 619 update.len = len; 620 trace_kvm_sev_launch_update_data(addr, len); 621 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, 622 &update, &fw_error); 623 if (ret) { 624 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'", 625 __func__, ret, fw_error, fw_error_to_str(fw_error)); 626 } 627 628 return ret; 629 } 630 631 static void 632 sev_launch_get_measure(Notifier *notifier, void *unused) 633 { 634 int ret, error; 635 guchar *data; 636 SEVState *s = sev_state; 637 struct kvm_sev_launch_measure *measurement; 638 639 if (!sev_check_state(SEV_STATE_LAUNCH_UPDATE)) { 640 return; 641 } 642 643 measurement = g_new0(struct kvm_sev_launch_measure, 1); 644 645 /* query the measurement blob length */ 646 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE, 647 measurement, &error); 648 if (!measurement->len) { 649 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", 650 __func__, ret, error, fw_error_to_str(errno)); 651 goto free_measurement; 652 } 653 654 data = g_new0(guchar, measurement->len); 655 measurement->uaddr = (unsigned long)data; 656 657 /* get the measurement blob */ 658 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_MEASURE, 659 measurement, &error); 660 if (ret) { 661 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", 662 __func__, ret, error, fw_error_to_str(errno)); 663 goto free_data; 664 } 665 666 sev_set_guest_state(SEV_STATE_LAUNCH_SECRET); 667 668 /* encode the measurement value and emit the event */ 669 s->measurement = g_base64_encode(data, measurement->len); 670 trace_kvm_sev_launch_measurement(s->measurement); 671 672 free_data: 673 g_free(data); 674 free_measurement: 675 g_free(measurement); 676 } 677 678 char * 679 sev_get_launch_measurement(void) 680 { 681 if (sev_state && 682 sev_state->state >= SEV_STATE_LAUNCH_SECRET) { 683 return g_strdup(sev_state->measurement); 684 } 685 686 return NULL; 687 } 688 689 static Notifier sev_machine_done_notify = { 690 .notify = sev_launch_get_measure, 691 }; 692 693 static void 694 sev_launch_finish(SEVState *s) 695 { 696 int ret, error; 697 Error *local_err = NULL; 698 699 trace_kvm_sev_launch_finish(); 700 ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error); 701 if (ret) { 702 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'", 703 __func__, ret, error, fw_error_to_str(error)); 704 exit(1); 705 } 706 707 sev_set_guest_state(SEV_STATE_RUNNING); 708 709 /* add migration blocker */ 710 error_setg(&sev_mig_blocker, 711 "SEV: Migration is not implemented"); 712 ret = migrate_add_blocker(sev_mig_blocker, &local_err); 713 if (local_err) { 714 error_report_err(local_err); 715 error_free(sev_mig_blocker); 716 exit(1); 717 } 718 } 719 720 static void 721 sev_vm_state_change(void *opaque, int running, RunState state) 722 { 723 SEVState *s = opaque; 724 725 if (running) { 726 if (!sev_check_state(SEV_STATE_RUNNING)) { 727 sev_launch_finish(s); 728 } 729 } 730 } 731 732 void * 733 sev_guest_init(const char *id) 734 { 735 SEVState *s; 736 char *devname; 737 int ret, fw_error; 738 uint32_t ebx; 739 uint32_t host_cbitpos; 740 struct sev_user_data_status status = {}; 741 742 sev_state = s = g_new0(SEVState, 1); 743 s->sev_info = lookup_sev_guest_info(id); 744 if (!s->sev_info) { 745 error_report("%s: '%s' is not a valid '%s' object", 746 __func__, id, TYPE_QSEV_GUEST_INFO); 747 goto err; 748 } 749 750 s->state = SEV_STATE_UNINIT; 751 752 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); 753 host_cbitpos = ebx & 0x3f; 754 755 s->cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL); 756 if (host_cbitpos != s->cbitpos) { 757 error_report("%s: cbitpos check failed, host '%d' requested '%d'", 758 __func__, host_cbitpos, s->cbitpos); 759 goto err; 760 } 761 762 s->reduced_phys_bits = object_property_get_int(OBJECT(s->sev_info), 763 "reduced-phys-bits", NULL); 764 if (s->reduced_phys_bits < 1) { 765 error_report("%s: reduced_phys_bits check failed, it should be >=1," 766 " requested '%d'", __func__, s->reduced_phys_bits); 767 goto err; 768 } 769 770 s->me_mask = ~(1UL << s->cbitpos); 771 772 devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL); 773 s->sev_fd = open(devname, O_RDWR); 774 if (s->sev_fd < 0) { 775 error_report("%s: Failed to open %s '%s'", __func__, 776 devname, strerror(errno)); 777 } 778 g_free(devname); 779 if (s->sev_fd < 0) { 780 goto err; 781 } 782 783 ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status, 784 &fw_error); 785 if (ret) { 786 error_report("%s: failed to get platform status ret=%d " 787 "fw_error='%d: %s'", __func__, ret, fw_error, 788 fw_error_to_str(fw_error)); 789 goto err; 790 } 791 s->build_id = status.build; 792 s->api_major = status.api_major; 793 s->api_minor = status.api_minor; 794 795 trace_kvm_sev_init(); 796 ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error); 797 if (ret) { 798 error_report("%s: failed to initialize ret=%d fw_error=%d '%s'", 799 __func__, ret, fw_error, fw_error_to_str(fw_error)); 800 goto err; 801 } 802 803 ret = sev_launch_start(s); 804 if (ret) { 805 error_report("%s: failed to create encryption context", __func__); 806 goto err; 807 } 808 809 ram_block_notifier_add(&sev_ram_notifier); 810 qemu_add_machine_init_done_notifier(&sev_machine_done_notify); 811 qemu_add_vm_change_state_handler(sev_vm_state_change, s); 812 813 return s; 814 err: 815 g_free(sev_state); 816 sev_state = NULL; 817 return NULL; 818 } 819 820 int 821 sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len) 822 { 823 assert(handle); 824 825 /* if SEV is in update state then encrypt the data else do nothing */ 826 if (sev_check_state(SEV_STATE_LAUNCH_UPDATE)) { 827 return sev_launch_update_data(ptr, len); 828 } 829 830 return 0; 831 } 832 833 static void 834 sev_register_types(void) 835 { 836 type_register_static(&qsev_guest_info); 837 } 838 839 type_init(sev_register_types); 840