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