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 bool 339 sev_enabled(void) 340 { 341 return !!sev_guest; 342 } 343 344 uint64_t 345 sev_get_me_mask(void) 346 { 347 return sev_guest ? sev_guest->me_mask : ~0; 348 } 349 350 uint32_t 351 sev_get_cbit_position(void) 352 { 353 return sev_guest ? sev_guest->cbitpos : 0; 354 } 355 356 uint32_t 357 sev_get_reduced_phys_bits(void) 358 { 359 return sev_guest ? sev_guest->reduced_phys_bits : 0; 360 } 361 362 SevInfo * 363 sev_get_info(void) 364 { 365 SevInfo *info; 366 367 info = g_new0(SevInfo, 1); 368 info->enabled = sev_enabled(); 369 370 if (info->enabled) { 371 info->api_major = sev_guest->api_major; 372 info->api_minor = sev_guest->api_minor; 373 info->build_id = sev_guest->build_id; 374 info->policy = sev_guest->policy; 375 info->state = sev_guest->state; 376 info->handle = sev_guest->handle; 377 } 378 379 return info; 380 } 381 382 static int 383 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain, 384 size_t *cert_chain_len, Error **errp) 385 { 386 guchar *pdh_data = NULL; 387 guchar *cert_chain_data = NULL; 388 struct sev_user_data_pdh_cert_export export = {}; 389 int err, r; 390 391 /* query the certificate length */ 392 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err); 393 if (r < 0) { 394 if (err != SEV_RET_INVALID_LEN) { 395 error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)", 396 r, err, fw_error_to_str(err)); 397 return 1; 398 } 399 } 400 401 pdh_data = g_new(guchar, export.pdh_cert_len); 402 cert_chain_data = g_new(guchar, export.cert_chain_len); 403 export.pdh_cert_address = (unsigned long)pdh_data; 404 export.cert_chain_address = (unsigned long)cert_chain_data; 405 406 r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err); 407 if (r < 0) { 408 error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)", 409 r, err, fw_error_to_str(err)); 410 goto e_free; 411 } 412 413 *pdh = pdh_data; 414 *pdh_len = export.pdh_cert_len; 415 *cert_chain = cert_chain_data; 416 *cert_chain_len = export.cert_chain_len; 417 return 0; 418 419 e_free: 420 g_free(pdh_data); 421 g_free(cert_chain_data); 422 return 1; 423 } 424 425 SevCapability * 426 sev_get_capabilities(Error **errp) 427 { 428 SevCapability *cap = NULL; 429 guchar *pdh_data = NULL; 430 guchar *cert_chain_data = NULL; 431 size_t pdh_len = 0, cert_chain_len = 0; 432 uint32_t ebx; 433 int fd; 434 435 if (!kvm_enabled()) { 436 error_setg(errp, "KVM not enabled"); 437 return NULL; 438 } 439 if (kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, NULL) < 0) { 440 error_setg(errp, "SEV is not enabled in KVM"); 441 return NULL; 442 } 443 444 fd = open(DEFAULT_SEV_DEVICE, O_RDWR); 445 if (fd < 0) { 446 error_setg_errno(errp, errno, "Failed to open %s", 447 DEFAULT_SEV_DEVICE); 448 return NULL; 449 } 450 451 if (sev_get_pdh_info(fd, &pdh_data, &pdh_len, 452 &cert_chain_data, &cert_chain_len, errp)) { 453 goto out; 454 } 455 456 cap = g_new0(SevCapability, 1); 457 cap->pdh = g_base64_encode(pdh_data, pdh_len); 458 cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len); 459 460 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); 461 cap->cbitpos = ebx & 0x3f; 462 463 /* 464 * When SEV feature is enabled, we loose one bit in guest physical 465 * addressing. 466 */ 467 cap->reduced_phys_bits = 1; 468 469 out: 470 g_free(pdh_data); 471 g_free(cert_chain_data); 472 close(fd); 473 return cap; 474 } 475 476 static int 477 sev_read_file_base64(const char *filename, guchar **data, gsize *len) 478 { 479 gsize sz; 480 gchar *base64; 481 GError *error = NULL; 482 483 if (!g_file_get_contents(filename, &base64, &sz, &error)) { 484 error_report("failed to read '%s' (%s)", filename, error->message); 485 g_error_free(error); 486 return -1; 487 } 488 489 *data = g_base64_decode(base64, len); 490 return 0; 491 } 492 493 static int 494 sev_launch_start(SevGuestState *sev) 495 { 496 gsize sz; 497 int ret = 1; 498 int fw_error, rc; 499 struct kvm_sev_launch_start *start; 500 guchar *session = NULL, *dh_cert = NULL; 501 502 start = g_new0(struct kvm_sev_launch_start, 1); 503 504 start->handle = sev->handle; 505 start->policy = sev->policy; 506 if (sev->session_file) { 507 if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { 508 goto out; 509 } 510 start->session_uaddr = (unsigned long)session; 511 start->session_len = sz; 512 } 513 514 if (sev->dh_cert_file) { 515 if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { 516 goto out; 517 } 518 start->dh_uaddr = (unsigned long)dh_cert; 519 start->dh_len = sz; 520 } 521 522 trace_kvm_sev_launch_start(start->policy, session, dh_cert); 523 rc = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); 524 if (rc < 0) { 525 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", 526 __func__, ret, fw_error, fw_error_to_str(fw_error)); 527 goto out; 528 } 529 530 sev_set_guest_state(sev, SEV_STATE_LAUNCH_UPDATE); 531 sev->handle = start->handle; 532 ret = 0; 533 534 out: 535 g_free(start); 536 g_free(session); 537 g_free(dh_cert); 538 return ret; 539 } 540 541 static int 542 sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len) 543 { 544 int ret, fw_error; 545 struct kvm_sev_launch_update_data update; 546 547 if (!addr || !len) { 548 return 1; 549 } 550 551 update.uaddr = (__u64)(unsigned long)addr; 552 update.len = len; 553 trace_kvm_sev_launch_update_data(addr, len); 554 ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA, 555 &update, &fw_error); 556 if (ret) { 557 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'", 558 __func__, ret, fw_error, fw_error_to_str(fw_error)); 559 } 560 561 return ret; 562 } 563 564 static void 565 sev_launch_get_measure(Notifier *notifier, void *unused) 566 { 567 SevGuestState *sev = sev_guest; 568 int ret, error; 569 guchar *data; 570 struct kvm_sev_launch_measure *measurement; 571 572 if (!sev_check_state(sev, SEV_STATE_LAUNCH_UPDATE)) { 573 return; 574 } 575 576 measurement = g_new0(struct kvm_sev_launch_measure, 1); 577 578 /* query the measurement blob length */ 579 ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE, 580 measurement, &error); 581 if (!measurement->len) { 582 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", 583 __func__, ret, error, fw_error_to_str(errno)); 584 goto free_measurement; 585 } 586 587 data = g_new0(guchar, measurement->len); 588 measurement->uaddr = (unsigned long)data; 589 590 /* get the measurement blob */ 591 ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE, 592 measurement, &error); 593 if (ret) { 594 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'", 595 __func__, ret, error, fw_error_to_str(errno)); 596 goto free_data; 597 } 598 599 sev_set_guest_state(sev, SEV_STATE_LAUNCH_SECRET); 600 601 /* encode the measurement value and emit the event */ 602 sev->measurement = g_base64_encode(data, measurement->len); 603 trace_kvm_sev_launch_measurement(sev->measurement); 604 605 free_data: 606 g_free(data); 607 free_measurement: 608 g_free(measurement); 609 } 610 611 char * 612 sev_get_launch_measurement(void) 613 { 614 if (sev_guest && 615 sev_guest->state >= SEV_STATE_LAUNCH_SECRET) { 616 return g_strdup(sev_guest->measurement); 617 } 618 619 return NULL; 620 } 621 622 static Notifier sev_machine_done_notify = { 623 .notify = sev_launch_get_measure, 624 }; 625 626 static void 627 sev_launch_finish(SevGuestState *sev) 628 { 629 int ret, error; 630 Error *local_err = NULL; 631 632 trace_kvm_sev_launch_finish(); 633 ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error); 634 if (ret) { 635 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'", 636 __func__, ret, error, fw_error_to_str(error)); 637 exit(1); 638 } 639 640 sev_set_guest_state(sev, SEV_STATE_RUNNING); 641 642 /* add migration blocker */ 643 error_setg(&sev_mig_blocker, 644 "SEV: Migration is not implemented"); 645 ret = migrate_add_blocker(sev_mig_blocker, &local_err); 646 if (local_err) { 647 error_report_err(local_err); 648 error_free(sev_mig_blocker); 649 exit(1); 650 } 651 } 652 653 static void 654 sev_vm_state_change(void *opaque, int running, RunState state) 655 { 656 SevGuestState *sev = opaque; 657 658 if (running) { 659 if (!sev_check_state(sev, SEV_STATE_RUNNING)) { 660 sev_launch_finish(sev); 661 } 662 } 663 } 664 665 int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) 666 { 667 SevGuestState *sev 668 = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST); 669 char *devname; 670 int ret, fw_error; 671 uint32_t ebx; 672 uint32_t host_cbitpos; 673 struct sev_user_data_status status = {}; 674 675 if (!sev) { 676 return 0; 677 } 678 679 ret = ram_block_discard_disable(true); 680 if (ret) { 681 error_report("%s: cannot disable RAM discard", __func__); 682 return -1; 683 } 684 685 sev_guest = sev; 686 sev->state = SEV_STATE_UNINIT; 687 688 host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); 689 host_cbitpos = ebx & 0x3f; 690 691 if (host_cbitpos != sev->cbitpos) { 692 error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'", 693 __func__, host_cbitpos, sev->cbitpos); 694 goto err; 695 } 696 697 if (sev->reduced_phys_bits < 1) { 698 error_setg(errp, "%s: reduced_phys_bits check failed, it should be >=1," 699 " requested '%d'", __func__, sev->reduced_phys_bits); 700 goto err; 701 } 702 703 sev->me_mask = ~(1UL << sev->cbitpos); 704 705 devname = object_property_get_str(OBJECT(sev), "sev-device", NULL); 706 sev->sev_fd = open(devname, O_RDWR); 707 if (sev->sev_fd < 0) { 708 error_setg(errp, "%s: Failed to open %s '%s'", __func__, 709 devname, strerror(errno)); 710 g_free(devname); 711 goto err; 712 } 713 g_free(devname); 714 715 ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, &status, 716 &fw_error); 717 if (ret) { 718 error_setg(errp, "%s: failed to get platform status ret=%d " 719 "fw_error='%d: %s'", __func__, ret, fw_error, 720 fw_error_to_str(fw_error)); 721 goto err; 722 } 723 sev->build_id = status.build; 724 sev->api_major = status.api_major; 725 sev->api_minor = status.api_minor; 726 727 trace_kvm_sev_init(); 728 ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, &fw_error); 729 if (ret) { 730 error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", 731 __func__, ret, fw_error, fw_error_to_str(fw_error)); 732 goto err; 733 } 734 735 ret = sev_launch_start(sev); 736 if (ret) { 737 error_setg(errp, "%s: failed to create encryption context", __func__); 738 goto err; 739 } 740 741 ram_block_notifier_add(&sev_ram_notifier); 742 qemu_add_machine_init_done_notifier(&sev_machine_done_notify); 743 qemu_add_vm_change_state_handler(sev_vm_state_change, sev); 744 745 cgs->ready = true; 746 747 return 0; 748 err: 749 sev_guest = NULL; 750 ram_block_discard_disable(false); 751 return -1; 752 } 753 754 int 755 sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp) 756 { 757 if (!sev_guest) { 758 return 0; 759 } 760 761 /* if SEV is in update state then encrypt the data else do nothing */ 762 if (sev_check_state(sev_guest, SEV_STATE_LAUNCH_UPDATE)) { 763 int ret = sev_launch_update_data(sev_guest, ptr, len); 764 if (ret < 0) { 765 error_setg(errp, "failed to encrypt pflash rom"); 766 return ret; 767 } 768 } 769 770 return 0; 771 } 772 773 int sev_inject_launch_secret(const char *packet_hdr, const char *secret, 774 uint64_t gpa, Error **errp) 775 { 776 struct kvm_sev_launch_secret input; 777 g_autofree guchar *data = NULL, *hdr = NULL; 778 int error, ret = 1; 779 void *hva; 780 gsize hdr_sz = 0, data_sz = 0; 781 MemoryRegion *mr = NULL; 782 783 if (!sev_guest) { 784 error_setg(errp, "SEV: SEV not enabled."); 785 return 1; 786 } 787 788 /* secret can be injected only in this state */ 789 if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) { 790 error_setg(errp, "SEV: Not in correct state. (LSECRET) %x", 791 sev_guest->state); 792 return 1; 793 } 794 795 hdr = g_base64_decode(packet_hdr, &hdr_sz); 796 if (!hdr || !hdr_sz) { 797 error_setg(errp, "SEV: Failed to decode sequence header"); 798 return 1; 799 } 800 801 data = g_base64_decode(secret, &data_sz); 802 if (!data || !data_sz) { 803 error_setg(errp, "SEV: Failed to decode data"); 804 return 1; 805 } 806 807 hva = gpa2hva(&mr, gpa, data_sz, errp); 808 if (!hva) { 809 error_prepend(errp, "SEV: Failed to calculate guest address: "); 810 return 1; 811 } 812 813 input.hdr_uaddr = (uint64_t)(unsigned long)hdr; 814 input.hdr_len = hdr_sz; 815 816 input.trans_uaddr = (uint64_t)(unsigned long)data; 817 input.trans_len = data_sz; 818 819 input.guest_uaddr = (uint64_t)(unsigned long)hva; 820 input.guest_len = data_sz; 821 822 trace_kvm_sev_launch_secret(gpa, input.guest_uaddr, 823 input.trans_uaddr, input.trans_len); 824 825 ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_LAUNCH_SECRET, 826 &input, &error); 827 if (ret) { 828 error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'", 829 ret, error, fw_error_to_str(error)); 830 return ret; 831 } 832 833 return 0; 834 } 835 836 static void 837 sev_register_types(void) 838 { 839 type_register_static(&sev_guest_info); 840 } 841 842 type_init(sev_register_types); 843