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