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