cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

sev.c (56901B)


      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 "crypto/hash.h"
     27#include "sysemu/kvm.h"
     28#include "sev_i386.h"
     29#include "sysemu/sysemu.h"
     30#include "sysemu/runstate.h"
     31#include "trace.h"
     32#include "migration/blocker.h"
     33#include "qom/object.h"
     34#include "monitor/monitor.h"
     35#include "exec/confidential-guest-support.h"
     36#include "hw/i386/pc.h"
     37
     38#define TYPE_SEV_COMMON "sev-common"
     39OBJECT_DECLARE_SIMPLE_TYPE(SevCommonState, SEV_COMMON)
     40#define TYPE_SEV_GUEST "sev-guest"
     41OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST)
     42#define TYPE_SEV_SNP_GUEST "sev-snp-guest"
     43OBJECT_DECLARE_SIMPLE_TYPE(SevSnpGuestState, SEV_SNP_GUEST)
     44
     45/**
     46 * SevGuestState:
     47 *
     48 * The SevGuestState object is used for creating and managing a SEV
     49 * guest.
     50 *
     51 * # $QEMU \
     52 *         -object sev-guest,id=sev0 \
     53 *         -machine ...,memory-encryption=sev0
     54 */
     55struct SevCommonState {
     56    ConfidentialGuestSupport parent_obj;
     57
     58    /* configuration parameters */
     59    char *sev_device;
     60    uint32_t cbitpos;
     61    uint32_t reduced_phys_bits;
     62
     63    /* runtime state */
     64    uint8_t api_major;
     65    uint8_t api_minor;
     66    uint8_t build_id;
     67    uint64_t me_mask;
     68    int sev_fd;
     69    SevState state;
     70
     71    uint32_t reset_cs;
     72    uint32_t reset_ip;
     73    bool reset_data_valid;
     74};
     75
     76struct SevGuestState {
     77    SevCommonState sev_common;
     78    gchar *measurement;
     79
     80    /* configuration parameters */
     81    uint32_t handle;
     82    uint32_t policy;
     83    char *dh_cert_file;
     84    char *session_file;
     85};
     86
     87struct SevSnpGuestState {
     88    SevCommonState sev_common;
     89
     90    /* configuration parameters */
     91    char *guest_visible_workarounds;
     92    char *id_block;
     93    char *id_auth;
     94    char *host_data;
     95
     96    struct kvm_snp_init kvm_init_conf;
     97    struct kvm_sev_snp_launch_start kvm_start_conf;
     98    struct kvm_sev_snp_launch_finish kvm_finish_conf;
     99};
    100
    101#define DEFAULT_GUEST_POLICY    0x1 /* disable debug */
    102#define DEFAULT_SEV_DEVICE      "/dev/sev"
    103#define DEFAULT_SEV_SNP_POLICY  0x30000
    104
    105#define SEV_INFO_BLOCK_GUID     "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
    106typedef struct __attribute__((__packed__)) SevInfoBlock {
    107    /* SEV-ES Reset Vector Address */
    108    uint32_t reset_addr;
    109} SevInfoBlock;
    110
    111#define SEV_HASH_TABLE_RV_GUID  "7255371f-3a3b-4b04-927b-1da6efa8d454"
    112typedef struct QEMU_PACKED SevHashTableDescriptor {
    113    /* SEV hash table area guest address */
    114    uint32_t base;
    115    /* SEV hash table area size (in bytes) */
    116    uint32_t size;
    117} SevHashTableDescriptor;
    118
    119/* hard code sha256 digest size */
    120#define HASH_SIZE 32
    121
    122typedef struct QEMU_PACKED SevHashTableEntry {
    123    QemuUUID guid;
    124    uint16_t len;
    125    uint8_t hash[HASH_SIZE];
    126} SevHashTableEntry;
    127
    128typedef struct QEMU_PACKED SevHashTable {
    129    QemuUUID guid;
    130    uint16_t len;
    131    SevHashTableEntry cmdline;
    132    SevHashTableEntry initrd;
    133    SevHashTableEntry kernel;
    134    uint8_t padding[];
    135} SevHashTable;
    136
    137static Error *sev_mig_blocker;
    138
    139static const char *const sev_fw_errlist[] = {
    140    [SEV_RET_SUCCESS]                = "",
    141    [SEV_RET_INVALID_PLATFORM_STATE] = "Platform state is invalid",
    142    [SEV_RET_INVALID_GUEST_STATE]    = "Guest state is invalid",
    143    [SEV_RET_INAVLID_CONFIG]         = "Platform configuration is invalid",
    144    [SEV_RET_INVALID_LEN]            = "Buffer too small",
    145    [SEV_RET_ALREADY_OWNED]          = "Platform is already owned",
    146    [SEV_RET_INVALID_CERTIFICATE]    = "Certificate is invalid",
    147    [SEV_RET_POLICY_FAILURE]         = "Policy is not allowed",
    148    [SEV_RET_INACTIVE]               = "Guest is not active",
    149    [SEV_RET_INVALID_ADDRESS]        = "Invalid address",
    150    [SEV_RET_BAD_SIGNATURE]          = "Bad signature",
    151    [SEV_RET_BAD_MEASUREMENT]        = "Bad measurement",
    152    [SEV_RET_ASID_OWNED]             = "ASID is already owned",
    153    [SEV_RET_INVALID_ASID]           = "Invalid ASID",
    154    [SEV_RET_WBINVD_REQUIRED]        = "WBINVD is required",
    155    [SEV_RET_DFFLUSH_REQUIRED]       = "DF_FLUSH is required",
    156    [SEV_RET_INVALID_GUEST]          = "Guest handle is invalid",
    157    [SEV_RET_INVALID_COMMAND]        = "Invalid command",
    158    [SEV_RET_ACTIVE]                 = "Guest is active",
    159    [SEV_RET_HWSEV_RET_PLATFORM]     = "Hardware error",
    160    [SEV_RET_HWSEV_RET_UNSAFE]       = "Hardware unsafe",
    161    [SEV_RET_UNSUPPORTED]            = "Feature not supported",
    162    [SEV_RET_INVALID_PARAM]          = "Invalid parameter",
    163    [SEV_RET_RESOURCE_LIMIT]         = "Required firmware resource depleted",
    164    [SEV_RET_SECURE_DATA_INVALID]    = "Part-specific integrity check failure",
    165    [SEV_RET_INVALID_PAGE_SIZE]      = "RMP page size is incorrect",
    166    [SEV_RET_INVALID_PAGE_STATE]     = "RMP page state is incorrect",
    167    [SEV_RET_INVALID_MDATA_ENTRY]    = "Metadata entry is invalid",
    168    [SEV_RET_INVALID_PAGE_OWNER]     = "Page ownership is incorrect",
    169    [SEV_RET_AEAD_OFLOW]             = "AEAD algorithum would have overflowed",
    170    [SEV_RET_RMP_INIT_REQUIRED]      = "RMP must be initialized",
    171};
    172
    173#define SEV_FW_MAX_ERROR      ARRAY_SIZE(sev_fw_errlist)
    174
    175/* <linux/kvm.h> doesn't expose this, so re-use the max from kvm.c */
    176#define KVM_MAX_CPUID_ENTRIES 100
    177
    178typedef struct KvmCpuidInfo {
    179    struct kvm_cpuid2 cpuid;
    180    struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
    181} KvmCpuidInfo;
    182
    183#define SNP_CPUID_FUNCTION_MAXCOUNT 64
    184#define SNP_CPUID_FUNCTION_UNKNOWN 0xFFFFFFFF
    185
    186typedef struct {
    187    uint32_t eax_in;
    188    uint32_t ecx_in;
    189    uint64_t xcr0_in;
    190    uint64_t xss_in;
    191    uint32_t eax;
    192    uint32_t ebx;
    193    uint32_t ecx;
    194    uint32_t edx;
    195    uint64_t reserved;
    196} __attribute__((packed)) SnpCpuidFunc;
    197
    198typedef struct {
    199    uint32_t count;
    200    uint32_t reserved1;
    201    uint64_t reserved2;
    202    SnpCpuidFunc entries[SNP_CPUID_FUNCTION_MAXCOUNT];
    203} __attribute__((packed)) SnpCpuidInfo;
    204
    205static int
    206sev_ioctl(int fd, int cmd, void *data, int *error)
    207{
    208    int r;
    209    struct kvm_sev_cmd input;
    210
    211    memset(&input, 0x0, sizeof(input));
    212
    213    input.id = cmd;
    214    input.sev_fd = fd;
    215    input.data = (__u64)(unsigned long)data;
    216
    217    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
    218
    219    if (error) {
    220        *error = input.error;
    221    }
    222
    223    return r;
    224}
    225
    226static int
    227sev_platform_ioctl(int fd, int cmd, void *data, int *error)
    228{
    229    int r;
    230    struct sev_issue_cmd arg;
    231
    232    arg.cmd = cmd;
    233    arg.data = (unsigned long)data;
    234    r = ioctl(fd, SEV_ISSUE_CMD, &arg);
    235    if (error) {
    236        *error = arg.error;
    237    }
    238
    239    return r;
    240}
    241
    242static const char *
    243fw_error_to_str(int code)
    244{
    245    if (code < 0 || code >= SEV_FW_MAX_ERROR) {
    246        return "unknown error";
    247    }
    248
    249    return sev_fw_errlist[code];
    250}
    251
    252static bool
    253sev_check_state(const SevCommonState *sev_common, SevState state)
    254{
    255    assert(sev_common);
    256    return sev_common->state == state ? true : false;
    257}
    258
    259static void
    260sev_set_guest_state(SevCommonState *sev_common, SevState new_state)
    261{
    262    assert(new_state < SEV_STATE__MAX);
    263    assert(sev_common);
    264
    265    trace_kvm_sev_change_state(SevState_str(sev_common->state),
    266                               SevState_str(new_state));
    267    sev_common->state = new_state;
    268}
    269
    270static void
    271sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
    272                    size_t max_size)
    273{
    274    int r;
    275    struct kvm_enc_region range;
    276    ram_addr_t offset;
    277    MemoryRegion *mr;
    278
    279    /*
    280     * The RAM device presents a memory region that should be treated
    281     * as IO region and should not be pinned.
    282     */
    283    mr = memory_region_from_host(host, &offset);
    284    if (mr && memory_region_is_ram_device(mr)) {
    285        return;
    286    }
    287
    288    range.addr = (__u64)(unsigned long)host;
    289    range.size = max_size;
    290
    291    trace_kvm_memcrypt_register_region(host, max_size);
    292    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
    293    if (r) {
    294        error_report("%s: failed to register region (%p+%#zx) error '%s'",
    295                     __func__, host, max_size, strerror(errno));
    296        exit(1);
    297    }
    298}
    299
    300static void
    301sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size,
    302                      size_t max_size)
    303{
    304    int r;
    305    struct kvm_enc_region range;
    306    ram_addr_t offset;
    307    MemoryRegion *mr;
    308
    309    /*
    310     * The RAM device presents a memory region that should be treated
    311     * as IO region and should not have been pinned.
    312     */
    313    mr = memory_region_from_host(host, &offset);
    314    if (mr && memory_region_is_ram_device(mr)) {
    315        return;
    316    }
    317
    318    range.addr = (__u64)(unsigned long)host;
    319    range.size = max_size;
    320
    321    trace_kvm_memcrypt_unregister_region(host, max_size);
    322    r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
    323    if (r) {
    324        error_report("%s: failed to unregister region (%p+%#zx)",
    325                     __func__, host, max_size);
    326    }
    327}
    328
    329static struct RAMBlockNotifier sev_ram_notifier = {
    330    .ram_block_added = sev_ram_block_added,
    331    .ram_block_removed = sev_ram_block_removed,
    332};
    333
    334static char *
    335sev_common_get_sev_device(Object *obj, Error **errp)
    336{
    337    return g_strdup(SEV_COMMON(obj)->sev_device);
    338}
    339
    340static void
    341sev_common_set_sev_device(Object *obj, const char *value, Error **errp)
    342{
    343    SEV_COMMON(obj)->sev_device = g_strdup(value);
    344}
    345
    346static void
    347sev_common_class_init(ObjectClass *oc, void *data)
    348{
    349    object_class_property_add_str(oc, "sev-device",
    350                                  sev_common_get_sev_device,
    351                                  sev_common_set_sev_device);
    352    object_class_property_set_description(oc, "sev-device",
    353            "SEV device to use");
    354}
    355
    356static void
    357sev_common_instance_init(Object *obj)
    358{
    359    SevCommonState *sev_common = SEV_COMMON(obj);
    360
    361    sev_common->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
    362
    363    object_property_add_uint32_ptr(obj, "cbitpos", &sev_common->cbitpos,
    364                                   OBJ_PROP_FLAG_READWRITE);
    365    object_property_add_uint32_ptr(obj, "reduced-phys-bits",
    366                                   &sev_common->reduced_phys_bits,
    367                                   OBJ_PROP_FLAG_READWRITE);
    368}
    369
    370/* sev guest info common to sev/sev-es/sev-snp */
    371static const TypeInfo sev_common_info = {
    372    .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT,
    373    .name = TYPE_SEV_COMMON,
    374    .instance_size = sizeof(SevCommonState),
    375    .class_init = sev_common_class_init,
    376    .instance_init = sev_common_instance_init,
    377    .abstract = true,
    378    .interfaces = (InterfaceInfo[]) {
    379        { TYPE_USER_CREATABLE },
    380        { }
    381    }
    382};
    383
    384static char *
    385sev_guest_get_dh_cert_file(Object *obj, Error **errp)
    386{
    387    return g_strdup(SEV_GUEST(obj)->dh_cert_file);
    388}
    389
    390static void
    391sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
    392{
    393    SEV_GUEST(obj)->dh_cert_file = g_strdup(value);
    394}
    395
    396static char *
    397sev_guest_get_session_file(Object *obj, Error **errp)
    398{
    399    SevGuestState *sev_guest = SEV_GUEST(obj);
    400
    401    return sev_guest->session_file ? g_strdup(sev_guest->session_file) : NULL;
    402}
    403
    404static void
    405sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
    406{
    407    SEV_GUEST(obj)->session_file = g_strdup(value);
    408}
    409
    410static void
    411sev_guest_class_init(ObjectClass *oc, void *data)
    412{
    413    object_class_property_add_str(oc, "dh-cert-file",
    414                                  sev_guest_get_dh_cert_file,
    415                                  sev_guest_set_dh_cert_file);
    416    object_class_property_set_description(oc, "dh-cert-file",
    417            "guest owners DH certificate (encoded with base64)");
    418    object_class_property_add_str(oc, "session-file",
    419                                  sev_guest_get_session_file,
    420                                  sev_guest_set_session_file);
    421    object_class_property_set_description(oc, "session-file",
    422            "guest owners session parameters (encoded with base64)");
    423}
    424
    425static void
    426sev_guest_instance_init(Object *obj)
    427{
    428    SevGuestState *sev_guest = SEV_GUEST(obj);
    429
    430    sev_guest->policy = DEFAULT_GUEST_POLICY;
    431    object_property_add_uint32_ptr(obj, "handle", &sev_guest->handle,
    432                                   OBJ_PROP_FLAG_READWRITE);
    433    object_property_add_uint32_ptr(obj, "policy", &sev_guest->policy,
    434                                   OBJ_PROP_FLAG_READWRITE);
    435}
    436
    437/* guest info specific sev/sev-es */
    438static const TypeInfo sev_guest_info = {
    439    .parent = TYPE_SEV_COMMON,
    440    .name = TYPE_SEV_GUEST,
    441    .instance_size = sizeof(SevGuestState),
    442    .instance_init = sev_guest_instance_init,
    443    .class_init = sev_guest_class_init,
    444};
    445
    446static void
    447sev_snp_guest_get_init_flags(Object *obj, Visitor *v, const char *name,
    448                             void *opaque, Error **errp)
    449{
    450    visit_type_uint64(v, name,
    451                      (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_init_conf.flags,
    452                      errp);
    453}
    454
    455static void
    456sev_snp_guest_set_init_flags(Object *obj, Visitor *v, const char *name,
    457                             void *opaque, Error **errp)
    458{
    459    visit_type_uint64(v, name,
    460                      (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_init_conf.flags,
    461                      errp);
    462}
    463
    464static void
    465sev_snp_guest_get_policy(Object *obj, Visitor *v, const char *name,
    466                         void *opaque, Error **errp)
    467{
    468    visit_type_uint64(v, name,
    469                      (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
    470                      errp);
    471}
    472
    473static void
    474sev_snp_guest_set_policy(Object *obj, Visitor *v, const char *name,
    475                         void *opaque, Error **errp)
    476{
    477    visit_type_uint64(v, name,
    478                      (uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
    479                      errp);
    480}
    481
    482static char *
    483sev_snp_guest_get_guest_visible_workarounds(Object *obj, Error **errp)
    484{
    485    return g_strdup(SEV_SNP_GUEST(obj)->guest_visible_workarounds);
    486}
    487
    488static void
    489sev_snp_guest_set_guest_visible_workarounds(Object *obj, const char *value,
    490                                            Error **errp)
    491{
    492    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    493    struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
    494    g_autofree guchar *blob;
    495    gsize len;
    496
    497    if (sev_snp_guest->guest_visible_workarounds) {
    498        g_free(sev_snp_guest->guest_visible_workarounds);
    499    }
    500
    501    /* store the base64 str so we don't need to re-encode in getter */
    502    sev_snp_guest->guest_visible_workarounds = g_strdup(value);
    503
    504    blob = qbase64_decode(sev_snp_guest->guest_visible_workarounds, -1, &len, errp);
    505    if (!blob) {
    506        return;
    507    }
    508
    509    if (len > sizeof(start->gosvw)) {
    510        error_setg(errp, "parameter length of %lu exceeds max of %lu",
    511                   len, sizeof(start->gosvw));
    512        return;
    513    }
    514
    515    memcpy(start->gosvw, blob, len);
    516}
    517
    518static char *
    519sev_snp_guest_get_id_block(Object *obj, Error **errp)
    520{
    521    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    522
    523    return g_strdup(sev_snp_guest->id_block);
    524}
    525
    526static void
    527sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp)
    528{
    529    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    530    struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
    531    gsize len;
    532
    533    if (sev_snp_guest->id_block) {
    534        g_free(sev_snp_guest->id_block);
    535        g_free((guchar *)finish->id_block_uaddr);
    536    }
    537
    538    /* store the base64 str so we don't need to re-encode in getter */
    539    sev_snp_guest->id_block = g_strdup(value);
    540
    541    finish->id_block_uaddr =
    542        (uint64_t)qbase64_decode(sev_snp_guest->id_block, -1, &len, errp);
    543
    544    if (!finish->id_block_uaddr) {
    545        return;
    546    }
    547
    548    if (len > KVM_SEV_SNP_ID_BLOCK_SIZE) {
    549        error_setg(errp, "parameter length of %lu exceeds max of %u",
    550                   len, KVM_SEV_SNP_ID_BLOCK_SIZE);
    551        return;
    552    }
    553
    554    finish->id_block_en = (len) ? 1 : 0;
    555}
    556
    557static char *
    558sev_snp_guest_get_id_auth(Object *obj, Error **errp)
    559{
    560    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    561
    562    return g_strdup(sev_snp_guest->id_auth);
    563}
    564
    565static void
    566sev_snp_guest_set_id_auth(Object *obj, const char *value, Error **errp)
    567{
    568    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    569    struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
    570    gsize len;
    571
    572    if (sev_snp_guest->id_auth) {
    573        g_free(sev_snp_guest->id_auth);
    574        g_free((guchar *)finish->id_auth_uaddr);
    575    }
    576
    577    /* store the base64 str so we don't need to re-encode in getter */
    578    sev_snp_guest->id_auth = g_strdup(value);
    579
    580    finish->id_auth_uaddr =
    581        (uint64_t)qbase64_decode(sev_snp_guest->id_auth, -1, &len, errp);
    582
    583    if (!finish->id_auth_uaddr) {
    584        return;
    585    }
    586
    587    if (len > KVM_SEV_SNP_ID_AUTH_SIZE) {
    588        error_setg(errp, "parameter length of %lu exceeds max of %u",
    589                   len, KVM_SEV_SNP_ID_AUTH_SIZE);
    590        return;
    591    }
    592}
    593
    594static bool
    595sev_snp_guest_get_auth_key_en(Object *obj, Error **errp)
    596{
    597    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    598
    599    return !!sev_snp_guest->kvm_finish_conf.auth_key_en;
    600}
    601
    602static void
    603sev_snp_guest_set_auth_key_en(Object *obj, bool value, Error **errp)
    604{
    605    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    606
    607    sev_snp_guest->kvm_finish_conf.auth_key_en = value;
    608}
    609
    610static char *
    611sev_snp_guest_get_host_data(Object *obj, Error **errp)
    612{
    613    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    614
    615    return g_strdup(sev_snp_guest->host_data);
    616}
    617
    618static void
    619sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp)
    620{
    621    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    622    struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
    623    g_autofree guchar *blob;
    624    gsize len;
    625
    626    if (sev_snp_guest->host_data) {
    627        g_free(sev_snp_guest->host_data);
    628    }
    629
    630    /* store the base64 str so we don't need to re-encode in getter */
    631    sev_snp_guest->host_data = g_strdup(value);
    632
    633    blob = qbase64_decode(sev_snp_guest->host_data, -1, &len, errp);
    634
    635    if (!blob) {
    636        return;
    637    }
    638
    639    if (len > sizeof(finish->host_data)) {
    640        error_setg(errp, "parameter length of %lu exceeds max of %lu",
    641                   len, sizeof(finish->host_data));
    642        return;
    643    }
    644
    645    memcpy(finish->host_data, blob, len);
    646}
    647
    648static void
    649sev_snp_guest_class_init(ObjectClass *oc, void *data)
    650{
    651    object_class_property_add(oc, "init-flags", "uint64",
    652                              sev_snp_guest_get_init_flags,
    653                              sev_snp_guest_set_init_flags, NULL, NULL);
    654    object_class_property_set_description(oc, "init-flags",
    655        "guest initialization flags");
    656    object_class_property_add(oc, "policy", "uint64",
    657                              sev_snp_guest_get_policy,
    658                              sev_snp_guest_set_policy, NULL, NULL);
    659    object_class_property_add_str(oc, "guest-visible-workarounds",
    660                                  sev_snp_guest_get_guest_visible_workarounds,
    661                                  sev_snp_guest_set_guest_visible_workarounds);
    662    object_class_property_add_str(oc, "id-block",
    663                                  sev_snp_guest_get_id_block,
    664                                  sev_snp_guest_set_id_block);
    665    object_class_property_add_str(oc, "id-auth",
    666                                  sev_snp_guest_get_id_auth,
    667                                  sev_snp_guest_set_id_auth);
    668    object_class_property_add_bool(oc, "auth-key-enabled",
    669                                   sev_snp_guest_get_auth_key_en,
    670                                   sev_snp_guest_set_auth_key_en);
    671    object_class_property_add_str(oc, "host-data",
    672                                  sev_snp_guest_get_host_data,
    673                                  sev_snp_guest_set_host_data);
    674}
    675
    676static void
    677sev_snp_guest_instance_init(Object *obj)
    678{
    679    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
    680
    681    /* default init/start/finish params for kvm */
    682    sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
    683}
    684
    685/* guest info specific to sev-snp */
    686static const TypeInfo sev_snp_guest_info = {
    687    .parent = TYPE_SEV_COMMON,
    688    .name = TYPE_SEV_SNP_GUEST,
    689    .instance_size = sizeof(SevSnpGuestState),
    690    .class_init = sev_snp_guest_class_init,
    691    .instance_init = sev_snp_guest_instance_init,
    692};
    693
    694bool
    695sev_enabled(void)
    696{
    697    ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
    698
    699    return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON);
    700}
    701
    702bool
    703sev_snp_enabled(void)
    704{
    705    ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
    706
    707    return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_SNP_GUEST);
    708}
    709
    710bool
    711sev_es_enabled(void)
    712{
    713    ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
    714
    715    return sev_snp_enabled() ||
    716            (sev_enabled() && SEV_GUEST(cgs)->policy & SEV_POLICY_ES);
    717}
    718
    719uint64_t
    720sev_get_me_mask(void)
    721{
    722    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    723
    724    return sev_common ? sev_common->me_mask : ~0;
    725}
    726
    727uint32_t
    728sev_get_cbit_position(void)
    729{
    730    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    731
    732    return sev_common ? sev_common->cbitpos : 0;
    733}
    734
    735uint32_t
    736sev_get_reduced_phys_bits(void)
    737{
    738    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    739
    740    return sev_common ? sev_common->reduced_phys_bits : 0;
    741}
    742
    743SevInfo *
    744sev_get_info(void)
    745{
    746    SevInfo *info;
    747    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    748
    749    info = g_new0(SevInfo, 1);
    750    info->enabled = sev_enabled();
    751
    752    if (info->enabled) {
    753        info->api_major = sev_common->api_major;
    754        info->api_minor = sev_common->api_minor;
    755        info->build_id = sev_common->build_id;
    756        info->state = sev_common->state;
    757
    758        if (sev_snp_enabled()) {
    759            info->sev_type = SEV_GUEST_TYPE_SEV_SNP;
    760            info->u.sev_snp.snp_policy =
    761                object_property_get_uint(OBJECT(sev_common), "policy", NULL);
    762        } else {
    763            info->sev_type = SEV_GUEST_TYPE_SEV;
    764            info->u.sev.handle = SEV_GUEST(sev_common)->handle;
    765            info->u.sev.policy =
    766                (uint32_t)object_property_get_uint(OBJECT(sev_common),
    767                                                   "policy", NULL);
    768        }
    769    }
    770
    771    return info;
    772}
    773
    774static int
    775sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
    776                 size_t *cert_chain_len, Error **errp)
    777{
    778    guchar *pdh_data = NULL;
    779    guchar *cert_chain_data = NULL;
    780    struct sev_user_data_pdh_cert_export export = {};
    781    int err, r;
    782
    783    /* query the certificate length */
    784    r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
    785    if (r < 0) {
    786        if (err != SEV_RET_INVALID_LEN) {
    787            error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
    788                       r, err, fw_error_to_str(err));
    789            return 1;
    790        }
    791    }
    792
    793    pdh_data = g_new(guchar, export.pdh_cert_len);
    794    cert_chain_data = g_new(guchar, export.cert_chain_len);
    795    export.pdh_cert_address = (unsigned long)pdh_data;
    796    export.cert_chain_address = (unsigned long)cert_chain_data;
    797
    798    r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
    799    if (r < 0) {
    800        error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
    801                   r, err, fw_error_to_str(err));
    802        goto e_free;
    803    }
    804
    805    *pdh = pdh_data;
    806    *pdh_len = export.pdh_cert_len;
    807    *cert_chain = cert_chain_data;
    808    *cert_chain_len = export.cert_chain_len;
    809    return 0;
    810
    811e_free:
    812    g_free(pdh_data);
    813    g_free(cert_chain_data);
    814    return 1;
    815}
    816
    817SevCapability *
    818sev_get_capabilities(Error **errp)
    819{
    820    SevCapability *cap = NULL;
    821    guchar *pdh_data = NULL;
    822    guchar *cert_chain_data = NULL;
    823    size_t pdh_len = 0, cert_chain_len = 0;
    824    uint32_t ebx;
    825    int fd;
    826    SevCommonState *sev_common;
    827    char *sev_device;
    828
    829    if (!kvm_enabled()) {
    830        error_setg(errp, "KVM not enabled");
    831        return NULL;
    832    }
    833    if (kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, NULL) < 0) {
    834        error_setg(errp, "SEV is not enabled in KVM");
    835        return NULL;
    836    }
    837
    838    sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    839    if (!sev_common) {
    840        error_setg(errp, "SEV is not configured");
    841        return NULL;
    842    }
    843
    844    sev_device = object_property_get_str(OBJECT(sev_common), "sev-device",
    845                                         &error_abort);
    846    fd = open(sev_device, O_RDWR);
    847    if (fd < 0) {
    848        error_setg_errno(errp, errno, "Failed to open %s",
    849                         DEFAULT_SEV_DEVICE);
    850        g_free(sev_device);
    851        return NULL;
    852    }
    853    g_free(sev_device);
    854
    855    if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
    856                         &cert_chain_data, &cert_chain_len, errp)) {
    857        goto out;
    858    }
    859
    860    cap = g_new0(SevCapability, 1);
    861    cap->pdh = g_base64_encode(pdh_data, pdh_len);
    862    cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len);
    863
    864    host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
    865    cap->cbitpos = ebx & 0x3f;
    866
    867    /*
    868     * When SEV feature is enabled, we loose one bit in guest physical
    869     * addressing.
    870     */
    871    cap->reduced_phys_bits = 1;
    872
    873out:
    874    g_free(pdh_data);
    875    g_free(cert_chain_data);
    876    close(fd);
    877    return cap;
    878}
    879
    880SevAttestationReport *
    881sev_get_attestation_report(const char *mnonce, Error **errp)
    882{
    883    struct kvm_sev_attestation_report input = {};
    884    SevAttestationReport *report = NULL;
    885    SevCommonState *sev_common;
    886    guchar *data;
    887    guchar *buf;
    888    gsize len;
    889    int err = 0, ret;
    890
    891    if (!sev_enabled()) {
    892        error_setg(errp, "SEV is not enabled");
    893        return NULL;
    894    }
    895
    896    /* lets decode the mnonce string */
    897    buf = g_base64_decode(mnonce, &len);
    898    if (!buf) {
    899        error_setg(errp, "SEV: failed to decode mnonce input");
    900        return NULL;
    901    }
    902
    903    /* verify the input mnonce length */
    904    if (len != sizeof(input.mnonce)) {
    905        error_setg(errp, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT ")",
    906                sizeof(input.mnonce), len);
    907        g_free(buf);
    908        return NULL;
    909    }
    910
    911    sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
    912
    913    /* Query the report length */
    914    ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT,
    915            &input, &err);
    916    if (ret < 0) {
    917        if (err != SEV_RET_INVALID_LEN) {
    918            error_setg(errp, "failed to query the attestation report length "
    919                    "ret=%d fw_err=%d (%s)", ret, err, fw_error_to_str(err));
    920            g_free(buf);
    921            return NULL;
    922        }
    923    }
    924
    925    data = g_malloc(input.len);
    926    input.uaddr = (unsigned long)data;
    927    memcpy(input.mnonce, buf, sizeof(input.mnonce));
    928
    929    /* Query the report */
    930    ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT,
    931            &input, &err);
    932    if (ret) {
    933        error_setg_errno(errp, errno, "Failed to get attestation report"
    934                " ret=%d fw_err=%d (%s)", ret, err, fw_error_to_str(err));
    935        goto e_free_data;
    936    }
    937
    938    report = g_new0(SevAttestationReport, 1);
    939    report->data = g_base64_encode(data, input.len);
    940
    941    trace_kvm_sev_attestation_report(mnonce, report->data);
    942
    943e_free_data:
    944    g_free(data);
    945    g_free(buf);
    946    return report;
    947}
    948
    949static int
    950sev_read_file_base64(const char *filename, guchar **data, gsize *len)
    951{
    952    gsize sz;
    953    g_autofree gchar *base64 = NULL;
    954    GError *error = NULL;
    955
    956    if (!g_file_get_contents(filename, &base64, &sz, &error)) {
    957        error_report("failed to read '%s' (%s)", filename, error->message);
    958        g_error_free(error);
    959        return -1;
    960    }
    961
    962    *data = g_base64_decode(base64, len);
    963    return 0;
    964}
    965
    966static int
    967sev_snp_launch_start(SevSnpGuestState *sev_snp_guest)
    968{
    969    int fw_error, rc;
    970    SevCommonState *sev_common = SEV_COMMON(sev_snp_guest);
    971    struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
    972
    973    trace_kvm_sev_snp_launch_start(start->policy, sev_snp_guest->guest_visible_workarounds);
    974
    975    rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START,
    976                   start, &fw_error);
    977    if (rc < 0) {
    978        error_report("%s: SNP_LAUNCH_START ret=%d fw_error=%d '%s'",
    979                __func__, rc, fw_error, fw_error_to_str(fw_error));
    980        return 1;
    981    }
    982
    983    sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE);
    984
    985    return 0;
    986}
    987
    988static int
    989sev_launch_start(SevGuestState *sev_guest)
    990{
    991    gsize sz;
    992    int ret = 1;
    993    int fw_error, rc;
    994    struct kvm_sev_launch_start *start;
    995    guchar *session = NULL, *dh_cert = NULL;
    996    SevCommonState *sev_common = SEV_COMMON(sev_guest);
    997
    998    start = g_new0(struct kvm_sev_launch_start, 1);
    999
   1000    start->handle = sev_guest->handle;
   1001    start->policy = sev_guest->policy;
   1002    if (sev_guest->session_file) {
   1003        if (sev_read_file_base64(sev_guest->session_file, &session, &sz) < 0) {
   1004            goto out;
   1005        }
   1006        start->session_uaddr = (unsigned long)session;
   1007        start->session_len = sz;
   1008    }
   1009
   1010    if (sev_guest->dh_cert_file) {
   1011        if (sev_read_file_base64(sev_guest->dh_cert_file, &dh_cert, &sz) < 0) {
   1012            goto out;
   1013        }
   1014        start->dh_uaddr = (unsigned long)dh_cert;
   1015        start->dh_len = sz;
   1016    }
   1017
   1018    trace_kvm_sev_launch_start(start->policy, session, dh_cert);
   1019    rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
   1020    if (rc < 0) {
   1021        error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
   1022                __func__, ret, fw_error, fw_error_to_str(fw_error));
   1023        goto out;
   1024    }
   1025
   1026    sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE);
   1027    sev_guest->handle = start->handle;
   1028    ret = 0;
   1029
   1030out:
   1031    g_free(start);
   1032    g_free(session);
   1033    g_free(dh_cert);
   1034    return ret;
   1035}
   1036
   1037static const char *
   1038snp_page_type_to_str(int type)
   1039{
   1040    switch (type) {
   1041    case KVM_SEV_SNP_PAGE_TYPE_NORMAL: return "Normal";
   1042    case KVM_SEV_SNP_PAGE_TYPE_VMSA: return "Vmsa";
   1043    case KVM_SEV_SNP_PAGE_TYPE_ZERO: return "Zero";
   1044    case KVM_SEV_SNP_PAGE_TYPE_UNMEASURED: return "Unmeasured";
   1045    case KVM_SEV_SNP_PAGE_TYPE_SECRETS: return "Secrets";
   1046    case KVM_SEV_SNP_PAGE_TYPE_CPUID: return "Cpuid";
   1047    default: return "unknown";
   1048    }
   1049}
   1050
   1051static int
   1052sev_snp_launch_update(SevSnpGuestState *sev_snp_guest, hwaddr gpa, uint8_t *addr,
   1053                      uint64_t len, int type)
   1054{
   1055    int ret, fw_error;
   1056    struct kvm_sev_snp_launch_update update = {0};
   1057
   1058    if (!addr || !len) {
   1059        error_report("%s: SNP_LAUNCH_UPDATE called with invalid address / length: %lx / %lx",
   1060                __func__, gpa, len);
   1061        return 1;
   1062    }
   1063
   1064    update.uaddr = (__u64)(unsigned long)addr;
   1065    update.start_gfn = gpa >> TARGET_PAGE_BITS;
   1066    update.len = len;
   1067    update.page_type = type;
   1068    trace_kvm_sev_snp_launch_update(addr, gpa, len, snp_page_type_to_str(type));
   1069    ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd,
   1070                    KVM_SEV_SNP_LAUNCH_UPDATE,
   1071                    &update, &fw_error);
   1072    if (ret) {
   1073        error_report("%s: SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
   1074                __func__, ret, fw_error, fw_error_to_str(fw_error));
   1075    }
   1076
   1077    return ret;
   1078}
   1079
   1080static int
   1081sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len)
   1082{
   1083    int ret, fw_error;
   1084    struct kvm_sev_launch_update_data update;
   1085
   1086    if (!addr || !len) {
   1087        return 1;
   1088    }
   1089
   1090    update.uaddr = (__u64)(unsigned long)addr;
   1091    update.len = len;
   1092    trace_kvm_sev_launch_update_data(addr, len);
   1093    ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
   1094                    &update, &fw_error);
   1095    if (ret) {
   1096        error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
   1097                __func__, ret, fw_error, fw_error_to_str(fw_error));
   1098    }
   1099
   1100    return ret;
   1101}
   1102
   1103static int
   1104sev_launch_update_vmsa(SevGuestState *sev_guest)
   1105{
   1106    int ret, fw_error;
   1107
   1108    ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA,
   1109                    NULL, &fw_error);
   1110    if (ret) {
   1111        error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
   1112                __func__, ret, fw_error, fw_error_to_str(fw_error));
   1113    }
   1114
   1115    return ret;
   1116}
   1117
   1118static void
   1119sev_launch_get_measure(Notifier *notifier, void *unused)
   1120{
   1121    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
   1122    SevGuestState *sev_guest = SEV_GUEST(sev_common);
   1123    int ret, error;
   1124    guchar *data;
   1125    struct kvm_sev_launch_measure *measurement;
   1126
   1127    if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
   1128        return;
   1129    }
   1130
   1131    if (sev_es_enabled()) {
   1132        /* measure all the VM save areas before getting launch_measure */
   1133        ret = sev_launch_update_vmsa(sev_guest);
   1134        if (ret) {
   1135            exit(1);
   1136        }
   1137    }
   1138
   1139    measurement = g_new0(struct kvm_sev_launch_measure, 1);
   1140
   1141    /* query the measurement blob length */
   1142    ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE,
   1143                    measurement, &error);
   1144    if (!measurement->len) {
   1145        error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
   1146                     __func__, ret, error, fw_error_to_str(errno));
   1147        goto free_measurement;
   1148    }
   1149
   1150    data = g_new0(guchar, measurement->len);
   1151    measurement->uaddr = (unsigned long)data;
   1152
   1153    /* get the measurement blob */
   1154    ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE,
   1155                    measurement, &error);
   1156    if (ret) {
   1157        error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
   1158                     __func__, ret, error, fw_error_to_str(errno));
   1159        goto free_data;
   1160    }
   1161
   1162    sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_SECRET);
   1163
   1164    /* encode the measurement value and emit the event */
   1165    sev_guest->measurement = g_base64_encode(data, measurement->len);
   1166    trace_kvm_sev_launch_measurement(sev_guest->measurement);
   1167
   1168free_data:
   1169    g_free(data);
   1170free_measurement:
   1171    g_free(measurement);
   1172}
   1173
   1174char *
   1175sev_get_launch_measurement(void)
   1176{
   1177    ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
   1178    SevGuestState *sev_guest =
   1179        (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
   1180
   1181    if (sev_guest &&
   1182        SEV_COMMON(sev_guest)->state >= SEV_STATE_LAUNCH_SECRET) {
   1183        return g_strdup(sev_guest->measurement);
   1184    }
   1185
   1186    return NULL;
   1187}
   1188
   1189static Notifier sev_machine_done_notify = {
   1190    .notify = sev_launch_get_measure,
   1191};
   1192
   1193static void
   1194sev_launch_finish(SevGuestState *sev_guest)
   1195{
   1196    int ret, error;
   1197
   1198    trace_kvm_sev_launch_finish();
   1199    ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_FINISH, 0,
   1200                    &error);
   1201    if (ret) {
   1202        error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
   1203                     __func__, ret, error, fw_error_to_str(error));
   1204        exit(1);
   1205    }
   1206
   1207    sev_set_guest_state(SEV_COMMON(sev_guest), SEV_STATE_RUNNING);
   1208
   1209    /* add migration blocker */
   1210    error_setg(&sev_mig_blocker,
   1211               "SEV: Migration is not implemented");
   1212    migrate_add_blocker(sev_mig_blocker, &error_fatal);
   1213}
   1214
   1215static int
   1216sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info,
   1217                        const KvmCpuidInfo *kvm_cpuid_info)
   1218{
   1219    size_t i;
   1220
   1221    if (kvm_cpuid_info->cpuid.nent > SNP_CPUID_FUNCTION_MAXCOUNT) {
   1222        error_report("SEV-SNP: CPUID entry count (%d) exceeds max (%d)",
   1223                     kvm_cpuid_info->cpuid.nent, SNP_CPUID_FUNCTION_MAXCOUNT);
   1224        return -1;
   1225    }
   1226
   1227    memset(snp_cpuid_info, 0, sizeof(*snp_cpuid_info));
   1228
   1229    for (i = 0; i < kvm_cpuid_info->cpuid.nent; i++) {
   1230        const struct kvm_cpuid_entry2 *kvm_cpuid_entry;
   1231        SnpCpuidFunc *snp_cpuid_entry;
   1232
   1233        kvm_cpuid_entry = &kvm_cpuid_info->entries[i];
   1234        snp_cpuid_entry = &snp_cpuid_info->entries[i];
   1235
   1236        snp_cpuid_entry->eax_in = kvm_cpuid_entry->function;
   1237        if (kvm_cpuid_entry->flags == KVM_CPUID_FLAG_SIGNIFCANT_INDEX) {
   1238            snp_cpuid_entry->ecx_in = kvm_cpuid_entry->index;
   1239        }
   1240        snp_cpuid_entry->eax = kvm_cpuid_entry->eax;
   1241        snp_cpuid_entry->ebx = kvm_cpuid_entry->ebx;
   1242        snp_cpuid_entry->ecx = kvm_cpuid_entry->ecx;
   1243        snp_cpuid_entry->edx = kvm_cpuid_entry->edx;
   1244
   1245        /* CachePC: disable AES-NI */
   1246        snp_cpuid_entry->ecx &= ~(1 << 25);
   1247
   1248        /*
   1249         * Guest kernels will calculate EBX themselves using the 0xD
   1250         * subfunctions corresponding to the individual XSAVE areas, so only
   1251         * encode the base XSAVE size in the initial leaves, corresponding
   1252         * to the initial XCR0=1 state.
   1253         */
   1254        if (snp_cpuid_entry->eax_in == 0xD &&
   1255            (snp_cpuid_entry->ecx_in == 0x0 || snp_cpuid_entry->ecx_in == 0x1)) {
   1256            snp_cpuid_entry->ebx = 0x240;
   1257            snp_cpuid_entry->xcr0_in = 1;
   1258            snp_cpuid_entry->xss_in = 0;
   1259        }
   1260    }
   1261
   1262    snp_cpuid_info->count = i;
   1263
   1264    return 0;
   1265}
   1266
   1267static void
   1268sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old,
   1269                                SnpCpuidInfo *new)
   1270{
   1271    size_t i;
   1272
   1273    if (old->count != new->count) {
   1274        error_report("SEV-SNP: CPUID validation failed due to count mismatch, provided: %d, expected: %d",
   1275                     old->count, new->count);
   1276    }
   1277
   1278    for (i = 0; i < old->count; i++) {
   1279        SnpCpuidFunc *old_func, *new_func;
   1280
   1281        old_func = &old->entries[i];
   1282        new_func = &new->entries[i];
   1283
   1284        if (memcmp(old_func, new_func, sizeof(SnpCpuidFunc))) {
   1285            error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x.\n"
   1286                         "provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n"
   1287                         "expected: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x",
   1288                         old_func->eax_in, old_func->ecx_in,
   1289                         old_func->eax, old_func->ebx, old_func->ecx, old_func->edx,
   1290                         new_func->eax, new_func->ebx, new_func->ecx, new_func->edx);
   1291        }
   1292    }
   1293}
   1294
   1295static int
   1296snp_launch_update_cpuid(SevSnpGuestState *sev_snp, uint32_t cpuid_addr,
   1297                            void *hva, uint32_t cpuid_len)
   1298{
   1299    KvmCpuidInfo kvm_cpuid_info = {0};
   1300    SnpCpuidInfo snp_cpuid_info;
   1301    CPUState *cs = first_cpu;
   1302    int ret;
   1303    uint32_t i = 0;
   1304
   1305    assert(sizeof(snp_cpuid_info) <= cpuid_len);
   1306
   1307    /* get the cpuid list from KVM */
   1308    do {
   1309        kvm_cpuid_info.cpuid.nent = ++i;
   1310        ret = kvm_vcpu_ioctl(cs, KVM_GET_CPUID2, &kvm_cpuid_info);
   1311    } while (ret == -E2BIG);
   1312
   1313    if (ret) {
   1314        error_report("SEV-SNP: unable to query CPUID values for CPU: '%s'",
   1315                     strerror(-ret));
   1316        return 1;
   1317    }
   1318
   1319    ret = sev_snp_cpuid_info_fill(&snp_cpuid_info, &kvm_cpuid_info);
   1320    if (ret) {
   1321        error_report("SEV-SNP: failed to generate CPUID table information");
   1322        return 1;
   1323    }
   1324
   1325    memcpy(hva, &snp_cpuid_info, sizeof(snp_cpuid_info));
   1326
   1327    ret = sev_snp_launch_update(sev_snp, cpuid_addr, hva, cpuid_len,
   1328                                    KVM_SEV_SNP_PAGE_TYPE_CPUID);
   1329    if (ret) {
   1330        sev_snp_cpuid_report_mismatches(&snp_cpuid_info, hva);
   1331        error_report("SEV-SNP: failed update CPUID page");
   1332        return 1;
   1333    }
   1334
   1335    return 0;
   1336}
   1337
   1338static int
   1339snp_metadata_desc_to_page_type(int desc_type)
   1340{
   1341    switch(desc_type) {
   1342    /* Add the umeasured prevalidated pages as a zero page */
   1343    case SEV_DESC_TYPE_SNP_SEC_MEM: return KVM_SEV_SNP_PAGE_TYPE_ZERO;
   1344    case SEV_DESC_TYPE_SNP_SECRETS: return KVM_SEV_SNP_PAGE_TYPE_SECRETS;
   1345    case SEV_DESC_TYPE_CPUID: return KVM_SEV_SNP_PAGE_TYPE_CPUID;
   1346    default: return -1;
   1347    }
   1348}
   1349
   1350static void
   1351snp_populate_metadata_pages(SevSnpGuestState *sev_snp,
   1352                            OvmfSevMetadata *metadata)
   1353{
   1354    OvmfSevMetadataDesc *desc;
   1355    int type, ret, i;
   1356    void *hva;
   1357    MemoryRegion *mr = NULL;
   1358
   1359    for (i = 0; i < metadata->num_desc; i++) {
   1360        desc = &metadata->descs[i];
   1361
   1362        type = snp_metadata_desc_to_page_type(desc->type);
   1363        if (type < 0) {
   1364            error_report("%s: Invalid memory type '%d'\n", __func__, desc->type);
   1365            exit(1);
   1366        }
   1367
   1368        hva = gpa2hva(&mr, desc->base, desc->len, NULL);
   1369        if (!hva) {
   1370            error_report("%s: Failed to get HVA for GPA 0x%x sz 0x%x\n",
   1371                         __func__, desc->base, desc->len);
   1372            exit(1);
   1373        }
   1374
   1375        if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
   1376            ret = snp_launch_update_cpuid(sev_snp, desc->base, hva, desc->len);
   1377        } else {
   1378            ret = sev_snp_launch_update(sev_snp, desc->base, hva, desc->len,
   1379                                        type);
   1380        }
   1381
   1382        if (ret) {
   1383            error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d\n",
   1384                         __func__, desc->base, desc->len, desc->type);
   1385            exit(1);
   1386        }
   1387    }
   1388}
   1389
   1390static void
   1391sev_snp_launch_finish(SevSnpGuestState *sev_snp)
   1392{
   1393    int ret, error;
   1394    Error *local_err = NULL;
   1395    OvmfSevMetadata *metadata;
   1396    struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf;
   1397
   1398    /*
   1399     * To boot the SNP guest, the hypervisor is required to populate the CPUID
   1400     * and Secrets page before finalizing the launch flow. The location of
   1401     * the secrets and CPUID page is available through the OVMF metadata GUID.
   1402     */
   1403    metadata = pc_system_get_ovmf_sev_metadata_ptr();
   1404    if (metadata == NULL) {
   1405        error_report("%s: Failed to locate SEV metadata header\n", __func__);
   1406        exit(1);
   1407    }
   1408
   1409    /* Populate all the metadata pages */
   1410    snp_populate_metadata_pages(sev_snp, metadata);
   1411
   1412    trace_kvm_sev_snp_launch_finish(sev_snp->id_block, sev_snp->id_auth,
   1413                                    sev_snp->host_data);
   1414    ret = sev_ioctl(SEV_COMMON(sev_snp)->sev_fd, KVM_SEV_SNP_LAUNCH_FINISH,
   1415                    finish, &error);
   1416    if (ret) {
   1417        error_report("%s: SNP_LAUNCH_FINISH ret=%d fw_error=%d '%s'",
   1418                     __func__, ret, error, fw_error_to_str(error));
   1419        exit(1);
   1420    }
   1421
   1422    sev_set_guest_state(SEV_COMMON(sev_snp), SEV_STATE_RUNNING);
   1423
   1424    /* add migration blocker */
   1425    error_setg(&sev_mig_blocker,
   1426               "SEV-SNP: Migration is not implemented");
   1427    ret = migrate_add_blocker(sev_mig_blocker, &local_err);
   1428    if (local_err) {
   1429        error_report_err(local_err);
   1430        error_free(sev_mig_blocker);
   1431        exit(1);
   1432    }
   1433}
   1434
   1435
   1436static void
   1437sev_vm_state_change(void *opaque, bool running, RunState state)
   1438{
   1439    SevCommonState *sev_common = opaque;
   1440
   1441    if (running) {
   1442        if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) {
   1443            if (sev_snp_enabled()) {
   1444                sev_snp_launch_finish(SEV_SNP_GUEST(sev_common));
   1445            } else {
   1446                sev_launch_finish(SEV_GUEST(sev_common));
   1447            }
   1448        }
   1449    }
   1450}
   1451
   1452int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
   1453{
   1454    SevCommonState *sev_common = SEV_COMMON(cgs);
   1455    char *devname;
   1456    int ret, fw_error, cmd;
   1457    uint32_t ebx;
   1458    uint32_t host_cbitpos;
   1459    struct sev_user_data_status status = {};
   1460    void *init_args = NULL;
   1461
   1462    if (!sev_common) {
   1463        return 0;
   1464    }
   1465
   1466    ret = ram_block_discard_disable(true);
   1467    if (ret) {
   1468        error_report("%s: cannot disable RAM discard", __func__);
   1469        return -1;
   1470    }
   1471
   1472    sev_common->state = SEV_STATE_UNINIT;
   1473
   1474    host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
   1475    host_cbitpos = ebx & 0x3f;
   1476
   1477    if (host_cbitpos != sev_common->cbitpos) {
   1478        error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
   1479                   __func__, host_cbitpos, sev_common->cbitpos);
   1480        goto err;
   1481    }
   1482
   1483    if (sev_common->reduced_phys_bits < 1) {
   1484        error_setg(errp, "%s: reduced_phys_bits check failed, it should be >=1,"
   1485                   " requested '%d'", __func__, sev_common->reduced_phys_bits);
   1486        goto err;
   1487    }
   1488
   1489    sev_common->me_mask = ~(1UL << sev_common->cbitpos);
   1490
   1491    devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL);
   1492    sev_common->sev_fd = open(devname, O_RDWR);
   1493    if (sev_common->sev_fd < 0) {
   1494        error_setg(errp, "%s: Failed to open %s '%s'", __func__,
   1495                   devname, strerror(errno));
   1496        g_free(devname);
   1497        goto err;
   1498    }
   1499    g_free(devname);
   1500
   1501    ret = sev_platform_ioctl(sev_common->sev_fd, SEV_PLATFORM_STATUS, &status,
   1502                             &fw_error);
   1503    if (ret) {
   1504        error_setg(errp, "%s: failed to get platform status ret=%d "
   1505                   "fw_error='%d: %s'", __func__, ret, fw_error,
   1506                   fw_error_to_str(fw_error));
   1507        goto err;
   1508    }
   1509    sev_common->build_id = status.build;
   1510    sev_common->api_major = status.api_major;
   1511    sev_common->api_minor = status.api_minor;
   1512
   1513    if (sev_snp_enabled()) {
   1514        SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common);
   1515        if (!kvm_kernel_irqchip_allowed()) {
   1516            error_setg(errp, "%s: SEV-SNP guests require in-kernel irqchip support",
   1517                       __func__);
   1518            goto err;
   1519        }
   1520
   1521        cmd = KVM_SEV_SNP_INIT;
   1522        init_args = (void *)&sev_snp_guest->kvm_init_conf;
   1523        trace_kvm_sev_init("SEV-SNP", sev_snp_guest->kvm_init_conf.flags);
   1524    } else if (sev_es_enabled()) {
   1525        if (!kvm_kernel_irqchip_allowed()) {
   1526            error_report("%s: SEV-ES guests require in-kernel irqchip support",
   1527                         __func__);
   1528            goto err;
   1529        }
   1530
   1531        if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
   1532            error_report("%s: guest policy requires SEV-ES, but "
   1533                         "host SEV-ES support unavailable",
   1534                         __func__);
   1535            goto err;
   1536        }
   1537        cmd = KVM_SEV_ES_INIT;
   1538        trace_kvm_sev_init("SEV-ES", 0);
   1539    } else {
   1540        cmd = KVM_SEV_INIT;
   1541        trace_kvm_sev_init("SEV", 0);
   1542    }
   1543
   1544    ret = sev_ioctl(sev_common->sev_fd, cmd, init_args, &fw_error);
   1545    if (ret) {
   1546        error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
   1547                   __func__, ret, fw_error, fw_error_to_str(fw_error));
   1548        goto err;
   1549    }
   1550
   1551    if (sev_snp_enabled()) {
   1552        ret = sev_snp_launch_start(SEV_SNP_GUEST(sev_common));
   1553    } else {
   1554        ret = sev_launch_start(SEV_GUEST(sev_common));
   1555    }
   1556
   1557    if (ret) {
   1558        error_setg(errp, "%s: failed to create encryption context", __func__);
   1559        goto err;
   1560    }
   1561
   1562    ram_block_notifier_add(&sev_ram_notifier);
   1563
   1564    /*
   1565     * The machine done notify event is used by the SEV guest to get the
   1566     * measurement of the encrypted images. When SEV-SNP is enabled, the
   1567     * measurement is part of the attestation. So skip registering the
   1568     * notifier.
   1569     */
   1570    if (!sev_snp_enabled()) {
   1571        qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
   1572    }
   1573
   1574    qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common);
   1575
   1576    cgs->ready = true;
   1577
   1578    return 0;
   1579err:
   1580    ram_block_discard_disable(false);
   1581    return -1;
   1582}
   1583
   1584int
   1585sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
   1586{
   1587    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
   1588
   1589    if (!sev_common) {
   1590        return 0;
   1591    }
   1592
   1593    /* if SEV is in update state then encrypt the data else do nothing */
   1594    if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
   1595        int ret;
   1596
   1597        if (sev_snp_enabled()) {
   1598            ret = sev_snp_launch_update(SEV_SNP_GUEST(sev_common), gpa, ptr,
   1599                                        len, KVM_SEV_SNP_PAGE_TYPE_NORMAL);
   1600        } else {
   1601            ret = sev_launch_update_data(SEV_GUEST(sev_common), ptr, len);
   1602        }
   1603        if (ret < 0) {
   1604            error_setg(errp, "failed to encrypt pflash rom");
   1605            return ret;
   1606        }
   1607    }
   1608
   1609    return 0;
   1610}
   1611
   1612int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
   1613                             uint64_t gpa, Error **errp)
   1614{
   1615    struct kvm_sev_launch_secret input;
   1616    g_autofree guchar *data = NULL, *hdr = NULL;
   1617    int error, ret = 1;
   1618    void *hva;
   1619    gsize hdr_sz = 0, data_sz = 0;
   1620    MemoryRegion *mr = NULL;
   1621    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
   1622
   1623    if (!sev_common) {
   1624        error_setg(errp, "SEV: SEV not enabled.");
   1625        return 1;
   1626    }
   1627
   1628    /* secret can be injected only in this state */
   1629    if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_SECRET)) {
   1630        error_setg(errp, "SEV: Not in correct state. (LSECRET) %x",
   1631                   sev_common->state);
   1632        return 1;
   1633    }
   1634
   1635    hdr = g_base64_decode(packet_hdr, &hdr_sz);
   1636    if (!hdr || !hdr_sz) {
   1637        error_setg(errp, "SEV: Failed to decode sequence header");
   1638        return 1;
   1639    }
   1640
   1641    data = g_base64_decode(secret, &data_sz);
   1642    if (!data || !data_sz) {
   1643        error_setg(errp, "SEV: Failed to decode data");
   1644        return 1;
   1645    }
   1646
   1647    hva = gpa2hva(&mr, gpa, data_sz, errp);
   1648    if (!hva) {
   1649        error_prepend(errp, "SEV: Failed to calculate guest address: ");
   1650        return 1;
   1651    }
   1652
   1653    input.hdr_uaddr = (uint64_t)(unsigned long)hdr;
   1654    input.hdr_len = hdr_sz;
   1655
   1656    input.trans_uaddr = (uint64_t)(unsigned long)data;
   1657    input.trans_len = data_sz;
   1658
   1659    input.guest_uaddr = (uint64_t)(unsigned long)hva;
   1660    input.guest_len = data_sz;
   1661
   1662    trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
   1663                                input.trans_uaddr, input.trans_len);
   1664
   1665    ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_SECRET,
   1666                    &input, &error);
   1667    if (ret) {
   1668        error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
   1669                     ret, error, fw_error_to_str(error));
   1670        return ret;
   1671    }
   1672
   1673    return 0;
   1674}
   1675
   1676static int
   1677sev_es_parse_reset_block(SevInfoBlock *info, uint32_t *addr)
   1678{
   1679    if (!info->reset_addr) {
   1680        error_report("SEV-ES reset address is zero");
   1681        return 1;
   1682    }
   1683
   1684    *addr = info->reset_addr;
   1685
   1686    return 0;
   1687}
   1688
   1689static int
   1690sev_es_find_reset_vector(void *flash_ptr, uint64_t flash_size,
   1691                         uint32_t *addr)
   1692{
   1693    QemuUUID info_guid, *guid;
   1694    SevInfoBlock *info;
   1695    uint8_t *data;
   1696    uint16_t *len;
   1697
   1698    /*
   1699     * Initialize the address to zero. An address of zero with a successful
   1700     * return code indicates that SEV-ES is not active.
   1701     */
   1702    *addr = 0;
   1703
   1704    /*
   1705     * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
   1706     * The SEV GUID is located on its own (original implementation) or within
   1707     * the Firmware GUID Table (new implementation), either of which are
   1708     * located 32 bytes from the end of the flash.
   1709     *
   1710     * Check the Firmware GUID Table first.
   1711     */
   1712    if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID, &data, NULL)) {
   1713        return sev_es_parse_reset_block((SevInfoBlock *)data, addr);
   1714    }
   1715
   1716    /*
   1717     * SEV info block not found in the Firmware GUID Table (or there isn't
   1718     * a Firmware GUID Table), fall back to the original implementation.
   1719     */
   1720    data = flash_ptr + flash_size - 0x20;
   1721
   1722    qemu_uuid_parse(SEV_INFO_BLOCK_GUID, &info_guid);
   1723    info_guid = qemu_uuid_bswap(info_guid); /* GUIDs are LE */
   1724
   1725    guid = (QemuUUID *)(data - sizeof(info_guid));
   1726    if (!qemu_uuid_is_equal(guid, &info_guid)) {
   1727        error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
   1728        return 1;
   1729    }
   1730
   1731    len = (uint16_t *)((uint8_t *)guid - sizeof(*len));
   1732    info = (SevInfoBlock *)(data - le16_to_cpu(*len));
   1733
   1734    return sev_es_parse_reset_block(info, addr);
   1735}
   1736
   1737void sev_es_set_reset_vector(CPUState *cpu)
   1738{
   1739    X86CPU *x86;
   1740    CPUX86State *env;
   1741    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
   1742
   1743    /* Only update if we have valid reset information */
   1744    if (!sev_common || !sev_common->reset_data_valid) {
   1745        return;
   1746    }
   1747
   1748    /* Do not update the BSP reset state */
   1749    if (cpu->cpu_index == 0) {
   1750        return;
   1751    }
   1752
   1753    x86 = X86_CPU(cpu);
   1754    env = &x86->env;
   1755
   1756    cpu_x86_load_seg_cache(env, R_CS, 0xf000, sev_common->reset_cs, 0xffff,
   1757                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
   1758                           DESC_R_MASK | DESC_A_MASK);
   1759
   1760    env->eip = sev_common->reset_ip;
   1761}
   1762
   1763int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
   1764{
   1765    CPUState *cpu;
   1766    uint32_t addr;
   1767    int ret;
   1768    SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
   1769
   1770    if (!sev_es_enabled()) {
   1771        return 0;
   1772    }
   1773
   1774    addr = 0;
   1775    ret = sev_es_find_reset_vector(flash_ptr, flash_size,
   1776                                   &addr);
   1777    if (ret) {
   1778        return ret;
   1779    }
   1780
   1781    if (addr) {
   1782        sev_common->reset_cs = addr & 0xffff0000;
   1783        sev_common->reset_ip = addr & 0x0000ffff;
   1784        sev_common->reset_data_valid = true;
   1785
   1786        CPU_FOREACH(cpu) {
   1787            sev_es_set_reset_vector(cpu);
   1788        }
   1789    }
   1790
   1791    return 0;
   1792}
   1793
   1794static const QemuUUID sev_hash_table_header_guid = {
   1795    .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
   1796                    0xd4, 0x11, 0xfd, 0x21)
   1797};
   1798
   1799static const QemuUUID sev_kernel_entry_guid = {
   1800    .data = UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
   1801                    0x72, 0xd2, 0x04, 0x5b)
   1802};
   1803static const QemuUUID sev_initrd_entry_guid = {
   1804    .data = UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
   1805                    0x91, 0x69, 0x78, 0x1d)
   1806};
   1807static const QemuUUID sev_cmdline_entry_guid = {
   1808    .data = UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
   1809                    0x4d, 0x36, 0xab, 0x2a)
   1810};
   1811
   1812/*
   1813 * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
   1814 * which is included in SEV's initial memory measurement.
   1815 */
   1816bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
   1817{
   1818    uint8_t *data;
   1819    SevHashTableDescriptor *area;
   1820    SevHashTable *ht;
   1821    uint8_t cmdline_hash[HASH_SIZE];
   1822    uint8_t initrd_hash[HASH_SIZE];
   1823    uint8_t kernel_hash[HASH_SIZE];
   1824    uint8_t *hashp;
   1825    size_t hash_len = HASH_SIZE;
   1826    int aligned_len;
   1827
   1828    if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
   1829        error_setg(errp, "SEV: kernel specified but OVMF has no hash table guid");
   1830        return false;
   1831    }
   1832
   1833    if (sev_snp_enabled()) {
   1834        return false;
   1835    }
   1836
   1837    area = (SevHashTableDescriptor *)data;
   1838
   1839    /*
   1840     * Calculate hash of kernel command-line with the terminating null byte. If
   1841     * the user doesn't supply a command-line via -append, the 1-byte "\0" will
   1842     * be used.
   1843     */
   1844    hashp = cmdline_hash;
   1845    if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->cmdline_data,
   1846                           ctx->cmdline_size, &hashp, &hash_len, errp) < 0) {
   1847        return false;
   1848    }
   1849    assert(hash_len == HASH_SIZE);
   1850
   1851    /*
   1852     * Calculate hash of initrd. If the user doesn't supply an initrd via
   1853     * -initrd, an empty buffer will be used (ctx->initrd_size == 0).
   1854     */
   1855    hashp = initrd_hash;
   1856    if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->initrd_data,
   1857                           ctx->initrd_size, &hashp, &hash_len, errp) < 0) {
   1858        return false;
   1859    }
   1860    assert(hash_len == HASH_SIZE);
   1861
   1862    /* Calculate hash of the kernel */
   1863    hashp = kernel_hash;
   1864    struct iovec iov[2] = {
   1865        { .iov_base = ctx->setup_data, .iov_len = ctx->setup_size },
   1866        { .iov_base = ctx->kernel_data, .iov_len = ctx->kernel_size }
   1867    };
   1868    if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256, iov, ARRAY_SIZE(iov),
   1869                            &hashp, &hash_len, errp) < 0) {
   1870        return false;
   1871    }
   1872    assert(hash_len == HASH_SIZE);
   1873
   1874    /*
   1875     * Populate the hashes table in the guest's memory at the OVMF-designated
   1876     * area for the SEV hashes table
   1877     */
   1878    ht = qemu_map_ram_ptr(NULL, area->base);
   1879
   1880    ht->guid = sev_hash_table_header_guid;
   1881    ht->len = sizeof(*ht);
   1882
   1883    ht->cmdline.guid = sev_cmdline_entry_guid;
   1884    ht->cmdline.len = sizeof(ht->cmdline);
   1885    memcpy(ht->cmdline.hash, cmdline_hash, sizeof(ht->cmdline.hash));
   1886
   1887    ht->initrd.guid = sev_initrd_entry_guid;
   1888    ht->initrd.len = sizeof(ht->initrd);
   1889    memcpy(ht->initrd.hash, initrd_hash, sizeof(ht->initrd.hash));
   1890
   1891    ht->kernel.guid = sev_kernel_entry_guid;
   1892    ht->kernel.len = sizeof(ht->kernel);
   1893    memcpy(ht->kernel.hash, kernel_hash, sizeof(ht->kernel.hash));
   1894
   1895    /* When calling sev_encrypt_flash, the length has to be 16 byte aligned */
   1896    aligned_len = ROUND_UP(ht->len, 16);
   1897    if (aligned_len != ht->len) {
   1898        /* zero the excess data so the measurement can be reliably calculated */
   1899        memset(ht->padding, 0, aligned_len - ht->len);
   1900    }
   1901
   1902    if (sev_encrypt_flash(area->base, (uint8_t *)ht, aligned_len, errp) < 0) {
   1903        return false;
   1904    }
   1905
   1906    return true;
   1907}
   1908
   1909static void
   1910sev_register_types(void)
   1911{
   1912    type_register_static(&sev_common_info);
   1913    type_register_static(&sev_guest_info);
   1914    type_register_static(&sev_snp_guest_info);
   1915}
   1916
   1917type_init(sev_register_types);