4 * Copyright Advanced Micro Devices 2016-2018
7 * Brijesh Singh <brijesh.singh@amd.com>
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.
14 #include "qemu/osdep.h"
16 #include <linux/kvm.h>
17 #include <linux/psp-sev.h>
19 #include <sys/ioctl.h>
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"
29 #include "sysemu/sysemu.h"
30 #include "sysemu/runstate.h"
32 #include "migration/blocker.h"
33 #include "qom/object.h"
34 #include "monitor/monitor.h"
35 #include "monitor/hmp-target.h"
36 #include "qapi/qapi-commands-misc-target.h"
37 #include "qapi/qmp/qerror.h"
38 #include "exec/confidential-guest-support.h"
39 #include "hw/i386/pc.h"
40 #include "exec/address-spaces.h"
42 #define TYPE_SEV_GUEST "sev-guest"
43 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState
, SEV_GUEST
)
49 * The SevGuestState object is used for creating and managing a SEV
53 * -object sev-guest,id=sev0 \
54 * -machine ...,memory-encryption=sev0
56 struct SevGuestState
{
57 ConfidentialGuestSupport parent_obj
;
59 /* configuration parameters */
65 uint32_t reduced_phys_bits
;
79 bool reset_data_valid
;
82 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
83 #define DEFAULT_SEV_DEVICE "/dev/sev"
85 #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
86 typedef struct __attribute__((__packed__
)) SevInfoBlock
{
87 /* SEV-ES Reset Vector Address */
91 #define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454"
92 typedef struct QEMU_PACKED SevHashTableDescriptor
{
93 /* SEV hash table area guest address */
95 /* SEV hash table area size (in bytes) */
97 } SevHashTableDescriptor
;
99 /* hard code sha256 digest size */
102 typedef struct QEMU_PACKED SevHashTableEntry
{
105 uint8_t hash
[HASH_SIZE
];
108 typedef struct QEMU_PACKED SevHashTable
{
111 SevHashTableEntry cmdline
;
112 SevHashTableEntry initrd
;
113 SevHashTableEntry kernel
;
117 * Data encrypted by sev_encrypt_flash() must be padded to a multiple of
120 typedef struct QEMU_PACKED PaddedSevHashTable
{
122 uint8_t padding
[ROUND_UP(sizeof(SevHashTable
), 16) - sizeof(SevHashTable
)];
123 } PaddedSevHashTable
;
125 QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable
) % 16 != 0);
127 static SevGuestState
*sev_guest
;
128 static Error
*sev_mig_blocker
;
130 static const char *const sev_fw_errlist
[] = {
131 [SEV_RET_SUCCESS
] = "",
132 [SEV_RET_INVALID_PLATFORM_STATE
] = "Platform state is invalid",
133 [SEV_RET_INVALID_GUEST_STATE
] = "Guest state is invalid",
134 [SEV_RET_INAVLID_CONFIG
] = "Platform configuration is invalid",
135 [SEV_RET_INVALID_LEN
] = "Buffer too small",
136 [SEV_RET_ALREADY_OWNED
] = "Platform is already owned",
137 [SEV_RET_INVALID_CERTIFICATE
] = "Certificate is invalid",
138 [SEV_RET_POLICY_FAILURE
] = "Policy is not allowed",
139 [SEV_RET_INACTIVE
] = "Guest is not active",
140 [SEV_RET_INVALID_ADDRESS
] = "Invalid address",
141 [SEV_RET_BAD_SIGNATURE
] = "Bad signature",
142 [SEV_RET_BAD_MEASUREMENT
] = "Bad measurement",
143 [SEV_RET_ASID_OWNED
] = "ASID is already owned",
144 [SEV_RET_INVALID_ASID
] = "Invalid ASID",
145 [SEV_RET_WBINVD_REQUIRED
] = "WBINVD is required",
146 [SEV_RET_DFFLUSH_REQUIRED
] = "DF_FLUSH is required",
147 [SEV_RET_INVALID_GUEST
] = "Guest handle is invalid",
148 [SEV_RET_INVALID_COMMAND
] = "Invalid command",
149 [SEV_RET_ACTIVE
] = "Guest is active",
150 [SEV_RET_HWSEV_RET_PLATFORM
] = "Hardware error",
151 [SEV_RET_HWSEV_RET_UNSAFE
] = "Hardware unsafe",
152 [SEV_RET_UNSUPPORTED
] = "Feature not supported",
153 [SEV_RET_INVALID_PARAM
] = "Invalid parameter",
154 [SEV_RET_RESOURCE_LIMIT
] = "Required firmware resource depleted",
155 [SEV_RET_SECURE_DATA_INVALID
] = "Part-specific integrity check failure",
158 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
161 sev_ioctl(int fd
, int cmd
, void *data
, int *error
)
164 struct kvm_sev_cmd input
;
166 memset(&input
, 0x0, sizeof(input
));
170 input
.data
= (__u64
)(unsigned long)data
;
172 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, &input
);
175 *error
= input
.error
;
182 sev_platform_ioctl(int fd
, int cmd
, void *data
, int *error
)
185 struct sev_issue_cmd arg
;
188 arg
.data
= (unsigned long)data
;
189 r
= ioctl(fd
, SEV_ISSUE_CMD
, &arg
);
198 fw_error_to_str(int code
)
200 if (code
< 0 || code
>= SEV_FW_MAX_ERROR
) {
201 return "unknown error";
204 return sev_fw_errlist
[code
];
208 sev_check_state(const SevGuestState
*sev
, SevState state
)
211 return sev
->state
== state
? true : false;
215 sev_set_guest_state(SevGuestState
*sev
, SevState new_state
)
217 assert(new_state
< SEV_STATE__MAX
);
220 trace_kvm_sev_change_state(SevState_str(sev
->state
),
221 SevState_str(new_state
));
222 sev
->state
= new_state
;
226 sev_ram_block_added(RAMBlockNotifier
*n
, void *host
, size_t size
,
230 struct kvm_enc_region range
;
235 * The RAM device presents a memory region that should be treated
236 * as IO region and should not be pinned.
238 mr
= memory_region_from_host(host
, &offset
);
239 if (mr
&& memory_region_is_ram_device(mr
)) {
243 range
.addr
= (__u64
)(unsigned long)host
;
244 range
.size
= max_size
;
246 trace_kvm_memcrypt_register_region(host
, max_size
);
247 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_REG_REGION
, &range
);
249 error_report("%s: failed to register region (%p+%#zx) error '%s'",
250 __func__
, host
, max_size
, strerror(errno
));
256 sev_ram_block_removed(RAMBlockNotifier
*n
, void *host
, size_t size
,
260 struct kvm_enc_region range
;
265 * The RAM device presents a memory region that should be treated
266 * as IO region and should not have been pinned.
268 mr
= memory_region_from_host(host
, &offset
);
269 if (mr
&& memory_region_is_ram_device(mr
)) {
273 range
.addr
= (__u64
)(unsigned long)host
;
274 range
.size
= max_size
;
276 trace_kvm_memcrypt_unregister_region(host
, max_size
);
277 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_UNREG_REGION
, &range
);
279 error_report("%s: failed to unregister region (%p+%#zx)",
280 __func__
, host
, max_size
);
284 static struct RAMBlockNotifier sev_ram_notifier
= {
285 .ram_block_added
= sev_ram_block_added
,
286 .ram_block_removed
= sev_ram_block_removed
,
290 sev_guest_finalize(Object
*obj
)
295 sev_guest_get_session_file(Object
*obj
, Error
**errp
)
297 SevGuestState
*s
= SEV_GUEST(obj
);
299 return s
->session_file
? g_strdup(s
->session_file
) : NULL
;
303 sev_guest_set_session_file(Object
*obj
, const char *value
, Error
**errp
)
305 SevGuestState
*s
= SEV_GUEST(obj
);
307 s
->session_file
= g_strdup(value
);
311 sev_guest_get_dh_cert_file(Object
*obj
, Error
**errp
)
313 SevGuestState
*s
= SEV_GUEST(obj
);
315 return g_strdup(s
->dh_cert_file
);
319 sev_guest_set_dh_cert_file(Object
*obj
, const char *value
, Error
**errp
)
321 SevGuestState
*s
= SEV_GUEST(obj
);
323 s
->dh_cert_file
= g_strdup(value
);
327 sev_guest_get_sev_device(Object
*obj
, Error
**errp
)
329 SevGuestState
*sev
= SEV_GUEST(obj
);
331 return g_strdup(sev
->sev_device
);
335 sev_guest_set_sev_device(Object
*obj
, const char *value
, Error
**errp
)
337 SevGuestState
*sev
= SEV_GUEST(obj
);
339 sev
->sev_device
= g_strdup(value
);
342 static bool sev_guest_get_kernel_hashes(Object
*obj
, Error
**errp
)
344 SevGuestState
*sev
= SEV_GUEST(obj
);
346 return sev
->kernel_hashes
;
349 static void sev_guest_set_kernel_hashes(Object
*obj
, bool value
, Error
**errp
)
351 SevGuestState
*sev
= SEV_GUEST(obj
);
353 sev
->kernel_hashes
= value
;
357 sev_guest_class_init(ObjectClass
*oc
, void *data
)
359 object_class_property_add_str(oc
, "sev-device",
360 sev_guest_get_sev_device
,
361 sev_guest_set_sev_device
);
362 object_class_property_set_description(oc
, "sev-device",
363 "SEV device to use");
364 object_class_property_add_str(oc
, "dh-cert-file",
365 sev_guest_get_dh_cert_file
,
366 sev_guest_set_dh_cert_file
);
367 object_class_property_set_description(oc
, "dh-cert-file",
368 "guest owners DH certificate (encoded with base64)");
369 object_class_property_add_str(oc
, "session-file",
370 sev_guest_get_session_file
,
371 sev_guest_set_session_file
);
372 object_class_property_set_description(oc
, "session-file",
373 "guest owners session parameters (encoded with base64)");
374 object_class_property_add_bool(oc
, "kernel-hashes",
375 sev_guest_get_kernel_hashes
,
376 sev_guest_set_kernel_hashes
);
377 object_class_property_set_description(oc
, "kernel-hashes",
378 "add kernel hashes to guest firmware for measured Linux boot");
382 sev_guest_instance_init(Object
*obj
)
384 SevGuestState
*sev
= SEV_GUEST(obj
);
386 sev
->sev_device
= g_strdup(DEFAULT_SEV_DEVICE
);
387 sev
->policy
= DEFAULT_GUEST_POLICY
;
388 object_property_add_uint32_ptr(obj
, "policy", &sev
->policy
,
389 OBJ_PROP_FLAG_READWRITE
);
390 object_property_add_uint32_ptr(obj
, "handle", &sev
->handle
,
391 OBJ_PROP_FLAG_READWRITE
);
392 object_property_add_uint32_ptr(obj
, "cbitpos", &sev
->cbitpos
,
393 OBJ_PROP_FLAG_READWRITE
);
394 object_property_add_uint32_ptr(obj
, "reduced-phys-bits",
395 &sev
->reduced_phys_bits
,
396 OBJ_PROP_FLAG_READWRITE
);
400 static const TypeInfo sev_guest_info
= {
401 .parent
= TYPE_CONFIDENTIAL_GUEST_SUPPORT
,
402 .name
= TYPE_SEV_GUEST
,
403 .instance_size
= sizeof(SevGuestState
),
404 .instance_finalize
= sev_guest_finalize
,
405 .class_init
= sev_guest_class_init
,
406 .instance_init
= sev_guest_instance_init
,
407 .interfaces
= (InterfaceInfo
[]) {
408 { TYPE_USER_CREATABLE
},
422 return sev_enabled() && (sev_guest
->policy
& SEV_POLICY_ES
);
426 sev_get_cbit_position(void)
428 return sev_guest
? sev_guest
->cbitpos
: 0;
432 sev_get_reduced_phys_bits(void)
434 return sev_guest
? sev_guest
->reduced_phys_bits
: 0;
437 static SevInfo
*sev_get_info(void)
441 info
= g_new0(SevInfo
, 1);
442 info
->enabled
= sev_enabled();
445 info
->api_major
= sev_guest
->api_major
;
446 info
->api_minor
= sev_guest
->api_minor
;
447 info
->build_id
= sev_guest
->build_id
;
448 info
->policy
= sev_guest
->policy
;
449 info
->state
= sev_guest
->state
;
450 info
->handle
= sev_guest
->handle
;
456 SevInfo
*qmp_query_sev(Error
**errp
)
460 info
= sev_get_info();
462 error_setg(errp
, "SEV feature is not available");
469 void hmp_info_sev(Monitor
*mon
, const QDict
*qdict
)
471 SevInfo
*info
= sev_get_info();
473 if (info
&& info
->enabled
) {
474 monitor_printf(mon
, "handle: %d\n", info
->handle
);
475 monitor_printf(mon
, "state: %s\n", SevState_str(info
->state
));
476 monitor_printf(mon
, "build: %d\n", info
->build_id
);
477 monitor_printf(mon
, "api version: %d.%d\n",
478 info
->api_major
, info
->api_minor
);
479 monitor_printf(mon
, "debug: %s\n",
480 info
->policy
& SEV_POLICY_NODBG
? "off" : "on");
481 monitor_printf(mon
, "key-sharing: %s\n",
482 info
->policy
& SEV_POLICY_NOKS
? "off" : "on");
484 monitor_printf(mon
, "SEV is not enabled\n");
487 qapi_free_SevInfo(info
);
491 sev_get_pdh_info(int fd
, guchar
**pdh
, size_t *pdh_len
, guchar
**cert_chain
,
492 size_t *cert_chain_len
, Error
**errp
)
494 guchar
*pdh_data
= NULL
;
495 guchar
*cert_chain_data
= NULL
;
496 struct sev_user_data_pdh_cert_export export
= {};
499 /* query the certificate length */
500 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
502 if (err
!= SEV_RET_INVALID_LEN
) {
503 error_setg(errp
, "SEV: Failed to export PDH cert"
504 " ret=%d fw_err=%d (%s)",
505 r
, err
, fw_error_to_str(err
));
510 pdh_data
= g_new(guchar
, export
.pdh_cert_len
);
511 cert_chain_data
= g_new(guchar
, export
.cert_chain_len
);
512 export
.pdh_cert_address
= (unsigned long)pdh_data
;
513 export
.cert_chain_address
= (unsigned long)cert_chain_data
;
515 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
517 error_setg(errp
, "SEV: Failed to export PDH cert ret=%d fw_err=%d (%s)",
518 r
, err
, fw_error_to_str(err
));
523 *pdh_len
= export
.pdh_cert_len
;
524 *cert_chain
= cert_chain_data
;
525 *cert_chain_len
= export
.cert_chain_len
;
530 g_free(cert_chain_data
);
534 static int sev_get_cpu0_id(int fd
, guchar
**id
, size_t *id_len
, Error
**errp
)
537 struct sev_user_data_get_id2 get_id2
= {};
540 /* query the ID length */
541 r
= sev_platform_ioctl(fd
, SEV_GET_ID2
, &get_id2
, &err
);
542 if (r
< 0 && err
!= SEV_RET_INVALID_LEN
) {
543 error_setg(errp
, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
544 r
, err
, fw_error_to_str(err
));
548 id_data
= g_new(guchar
, get_id2
.length
);
549 get_id2
.address
= (unsigned long)id_data
;
551 r
= sev_platform_ioctl(fd
, SEV_GET_ID2
, &get_id2
, &err
);
553 error_setg(errp
, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
554 r
, err
, fw_error_to_str(err
));
559 *id_len
= get_id2
.length
;
567 static SevCapability
*sev_get_capabilities(Error
**errp
)
569 SevCapability
*cap
= NULL
;
570 guchar
*pdh_data
= NULL
;
571 guchar
*cert_chain_data
= NULL
;
572 guchar
*cpu0_id_data
= NULL
;
573 size_t pdh_len
= 0, cert_chain_len
= 0, cpu0_id_len
= 0;
577 if (!kvm_enabled()) {
578 error_setg(errp
, "KVM not enabled");
581 if (kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, NULL
) < 0) {
582 error_setg(errp
, "SEV is not enabled in KVM");
586 fd
= open(DEFAULT_SEV_DEVICE
, O_RDWR
);
588 error_setg_errno(errp
, errno
, "SEV: Failed to open %s",
593 if (sev_get_pdh_info(fd
, &pdh_data
, &pdh_len
,
594 &cert_chain_data
, &cert_chain_len
, errp
)) {
598 if (sev_get_cpu0_id(fd
, &cpu0_id_data
, &cpu0_id_len
, errp
)) {
602 cap
= g_new0(SevCapability
, 1);
603 cap
->pdh
= g_base64_encode(pdh_data
, pdh_len
);
604 cap
->cert_chain
= g_base64_encode(cert_chain_data
, cert_chain_len
);
605 cap
->cpu0_id
= g_base64_encode(cpu0_id_data
, cpu0_id_len
);
607 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
608 cap
->cbitpos
= ebx
& 0x3f;
611 * When SEV feature is enabled, we loose one bit in guest physical
614 cap
->reduced_phys_bits
= 1;
617 g_free(cpu0_id_data
);
619 g_free(cert_chain_data
);
624 SevCapability
*qmp_query_sev_capabilities(Error
**errp
)
626 return sev_get_capabilities(errp
);
629 static SevAttestationReport
*sev_get_attestation_report(const char *mnonce
,
632 struct kvm_sev_attestation_report input
= {};
633 SevAttestationReport
*report
= NULL
;
634 SevGuestState
*sev
= sev_guest
;
635 g_autofree guchar
*data
= NULL
;
636 g_autofree guchar
*buf
= NULL
;
640 if (!sev_enabled()) {
641 error_setg(errp
, "SEV is not enabled");
645 /* lets decode the mnonce string */
646 buf
= g_base64_decode(mnonce
, &len
);
648 error_setg(errp
, "SEV: failed to decode mnonce input");
652 /* verify the input mnonce length */
653 if (len
!= sizeof(input
.mnonce
)) {
654 error_setg(errp
, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT
")",
655 sizeof(input
.mnonce
), len
);
659 /* Query the report length */
660 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
663 if (err
!= SEV_RET_INVALID_LEN
) {
664 error_setg(errp
, "SEV: Failed to query the attestation report"
665 " length ret=%d fw_err=%d (%s)",
666 ret
, err
, fw_error_to_str(err
));
671 data
= g_malloc(input
.len
);
672 input
.uaddr
= (unsigned long)data
;
673 memcpy(input
.mnonce
, buf
, sizeof(input
.mnonce
));
675 /* Query the report */
676 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
679 error_setg_errno(errp
, errno
, "SEV: Failed to get attestation report"
680 " ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
684 report
= g_new0(SevAttestationReport
, 1);
685 report
->data
= g_base64_encode(data
, input
.len
);
687 trace_kvm_sev_attestation_report(mnonce
, report
->data
);
692 SevAttestationReport
*qmp_query_sev_attestation_report(const char *mnonce
,
695 return sev_get_attestation_report(mnonce
, errp
);
699 sev_read_file_base64(const char *filename
, guchar
**data
, gsize
*len
)
702 g_autofree gchar
*base64
= NULL
;
703 GError
*error
= NULL
;
705 if (!g_file_get_contents(filename
, &base64
, &sz
, &error
)) {
706 error_report("SEV: Failed to read '%s' (%s)", filename
, error
->message
);
711 *data
= g_base64_decode(base64
, len
);
716 sev_launch_start(SevGuestState
*sev
)
721 struct kvm_sev_launch_start start
= {
722 .handle
= sev
->handle
, .policy
= sev
->policy
724 guchar
*session
= NULL
, *dh_cert
= NULL
;
726 if (sev
->session_file
) {
727 if (sev_read_file_base64(sev
->session_file
, &session
, &sz
) < 0) {
730 start
.session_uaddr
= (unsigned long)session
;
731 start
.session_len
= sz
;
734 if (sev
->dh_cert_file
) {
735 if (sev_read_file_base64(sev
->dh_cert_file
, &dh_cert
, &sz
) < 0) {
738 start
.dh_uaddr
= (unsigned long)dh_cert
;
742 trace_kvm_sev_launch_start(start
.policy
, session
, dh_cert
);
743 rc
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_START
, &start
, &fw_error
);
745 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
746 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
750 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_UPDATE
);
751 sev
->handle
= start
.handle
;
761 sev_launch_update_data(SevGuestState
*sev
, uint8_t *addr
, uint64_t len
)
764 struct kvm_sev_launch_update_data update
;
770 update
.uaddr
= (__u64
)(unsigned long)addr
;
772 trace_kvm_sev_launch_update_data(addr
, len
);
773 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_DATA
,
776 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
777 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
784 sev_launch_update_vmsa(SevGuestState
*sev
)
788 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_VMSA
, NULL
, &fw_error
);
790 error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
791 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
798 sev_launch_get_measure(Notifier
*notifier
, void *unused
)
800 SevGuestState
*sev
= sev_guest
;
802 g_autofree guchar
*data
= NULL
;
803 struct kvm_sev_launch_measure measurement
= {};
805 if (!sev_check_state(sev
, SEV_STATE_LAUNCH_UPDATE
)) {
809 if (sev_es_enabled()) {
810 /* measure all the VM save areas before getting launch_measure */
811 ret
= sev_launch_update_vmsa(sev
);
817 /* query the measurement blob length */
818 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
819 &measurement
, &error
);
820 if (!measurement
.len
) {
821 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
822 __func__
, ret
, error
, fw_error_to_str(errno
));
826 data
= g_new0(guchar
, measurement
.len
);
827 measurement
.uaddr
= (unsigned long)data
;
829 /* get the measurement blob */
830 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
831 &measurement
, &error
);
833 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
834 __func__
, ret
, error
, fw_error_to_str(errno
));
838 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_SECRET
);
840 /* encode the measurement value and emit the event */
841 sev
->measurement
= g_base64_encode(data
, measurement
.len
);
842 trace_kvm_sev_launch_measurement(sev
->measurement
);
845 static char *sev_get_launch_measurement(void)
848 sev_guest
->state
>= SEV_STATE_LAUNCH_SECRET
) {
849 return g_strdup(sev_guest
->measurement
);
855 SevLaunchMeasureInfo
*qmp_query_sev_launch_measure(Error
**errp
)
858 SevLaunchMeasureInfo
*info
;
860 data
= sev_get_launch_measurement();
862 error_setg(errp
, "SEV launch measurement is not available");
866 info
= g_malloc0(sizeof(*info
));
872 static Notifier sev_machine_done_notify
= {
873 .notify
= sev_launch_get_measure
,
877 sev_launch_finish(SevGuestState
*sev
)
881 trace_kvm_sev_launch_finish();
882 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_FINISH
, 0, &error
);
884 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
885 __func__
, ret
, error
, fw_error_to_str(error
));
889 sev_set_guest_state(sev
, SEV_STATE_RUNNING
);
891 /* add migration blocker */
892 error_setg(&sev_mig_blocker
,
893 "SEV: Migration is not implemented");
894 migrate_add_blocker(sev_mig_blocker
, &error_fatal
);
898 sev_vm_state_change(void *opaque
, bool running
, RunState state
)
900 SevGuestState
*sev
= opaque
;
903 if (!sev_check_state(sev
, SEV_STATE_RUNNING
)) {
904 sev_launch_finish(sev
);
909 int sev_kvm_init(ConfidentialGuestSupport
*cgs
, Error
**errp
)
912 = (SevGuestState
*)object_dynamic_cast(OBJECT(cgs
), TYPE_SEV_GUEST
);
914 int ret
, fw_error
, cmd
;
916 uint32_t host_cbitpos
;
917 struct sev_user_data_status status
= {};
923 ret
= ram_block_discard_disable(true);
925 error_report("%s: cannot disable RAM discard", __func__
);
930 sev
->state
= SEV_STATE_UNINIT
;
932 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
933 host_cbitpos
= ebx
& 0x3f;
935 if (host_cbitpos
!= sev
->cbitpos
) {
936 error_setg(errp
, "%s: cbitpos check failed, host '%d' requested '%d'",
937 __func__
, host_cbitpos
, sev
->cbitpos
);
941 if (sev
->reduced_phys_bits
< 1) {
942 error_setg(errp
, "%s: reduced_phys_bits check failed, it should be >=1,"
943 " requested '%d'", __func__
, sev
->reduced_phys_bits
);
947 devname
= object_property_get_str(OBJECT(sev
), "sev-device", NULL
);
948 sev
->sev_fd
= open(devname
, O_RDWR
);
949 if (sev
->sev_fd
< 0) {
950 error_setg(errp
, "%s: Failed to open %s '%s'", __func__
,
951 devname
, strerror(errno
));
957 ret
= sev_platform_ioctl(sev
->sev_fd
, SEV_PLATFORM_STATUS
, &status
,
960 error_setg(errp
, "%s: failed to get platform status ret=%d "
961 "fw_error='%d: %s'", __func__
, ret
, fw_error
,
962 fw_error_to_str(fw_error
));
965 sev
->build_id
= status
.build
;
966 sev
->api_major
= status
.api_major
;
967 sev
->api_minor
= status
.api_minor
;
969 if (sev_es_enabled()) {
970 if (!kvm_kernel_irqchip_allowed()) {
971 error_report("%s: SEV-ES guests require in-kernel irqchip support",
976 if (!(status
.flags
& SEV_STATUS_FLAGS_CONFIG_ES
)) {
977 error_report("%s: guest policy requires SEV-ES, but "
978 "host SEV-ES support unavailable",
982 cmd
= KVM_SEV_ES_INIT
;
987 trace_kvm_sev_init();
988 ret
= sev_ioctl(sev
->sev_fd
, cmd
, NULL
, &fw_error
);
990 error_setg(errp
, "%s: failed to initialize ret=%d fw_error=%d '%s'",
991 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
995 ret
= sev_launch_start(sev
);
997 error_setg(errp
, "%s: failed to create encryption context", __func__
);
1001 ram_block_notifier_add(&sev_ram_notifier
);
1002 qemu_add_machine_init_done_notifier(&sev_machine_done_notify
);
1003 qemu_add_vm_change_state_handler(sev_vm_state_change
, sev
);
1010 ram_block_discard_disable(false);
1015 sev_encrypt_flash(uint8_t *ptr
, uint64_t len
, Error
**errp
)
1021 /* if SEV is in update state then encrypt the data else do nothing */
1022 if (sev_check_state(sev_guest
, SEV_STATE_LAUNCH_UPDATE
)) {
1023 int ret
= sev_launch_update_data(sev_guest
, ptr
, len
);
1025 error_setg(errp
, "SEV: Failed to encrypt pflash rom");
1033 int sev_inject_launch_secret(const char *packet_hdr
, const char *secret
,
1034 uint64_t gpa
, Error
**errp
)
1036 struct kvm_sev_launch_secret input
;
1037 g_autofree guchar
*data
= NULL
, *hdr
= NULL
;
1040 gsize hdr_sz
= 0, data_sz
= 0;
1041 MemoryRegion
*mr
= NULL
;
1044 error_setg(errp
, "SEV not enabled for guest");
1048 /* secret can be injected only in this state */
1049 if (!sev_check_state(sev_guest
, SEV_STATE_LAUNCH_SECRET
)) {
1050 error_setg(errp
, "SEV: Not in correct state. (LSECRET) %x",
1055 hdr
= g_base64_decode(packet_hdr
, &hdr_sz
);
1056 if (!hdr
|| !hdr_sz
) {
1057 error_setg(errp
, "SEV: Failed to decode sequence header");
1061 data
= g_base64_decode(secret
, &data_sz
);
1062 if (!data
|| !data_sz
) {
1063 error_setg(errp
, "SEV: Failed to decode data");
1067 hva
= gpa2hva(&mr
, gpa
, data_sz
, errp
);
1069 error_prepend(errp
, "SEV: Failed to calculate guest address: ");
1073 input
.hdr_uaddr
= (uint64_t)(unsigned long)hdr
;
1074 input
.hdr_len
= hdr_sz
;
1076 input
.trans_uaddr
= (uint64_t)(unsigned long)data
;
1077 input
.trans_len
= data_sz
;
1079 input
.guest_uaddr
= (uint64_t)(unsigned long)hva
;
1080 input
.guest_len
= data_sz
;
1082 trace_kvm_sev_launch_secret(gpa
, input
.guest_uaddr
,
1083 input
.trans_uaddr
, input
.trans_len
);
1085 ret
= sev_ioctl(sev_guest
->sev_fd
, KVM_SEV_LAUNCH_SECRET
,
1088 error_setg(errp
, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
1089 ret
, error
, fw_error_to_str(error
));
1096 #define SEV_SECRET_GUID "4c2eb361-7d9b-4cc3-8081-127c90d3d294"
1097 struct sev_secret_area
{
1102 void qmp_sev_inject_launch_secret(const char *packet_hdr
,
1104 bool has_gpa
, uint64_t gpa
,
1107 if (!sev_enabled()) {
1108 error_setg(errp
, "SEV not enabled for guest");
1113 struct sev_secret_area
*area
;
1115 if (!pc_system_ovmf_table_find(SEV_SECRET_GUID
, &data
, NULL
)) {
1116 error_setg(errp
, "SEV: no secret area found in OVMF,"
1117 " gpa must be specified.");
1120 area
= (struct sev_secret_area
*)data
;
1124 sev_inject_launch_secret(packet_hdr
, secret
, gpa
, errp
);
1128 sev_es_parse_reset_block(SevInfoBlock
*info
, uint32_t *addr
)
1130 if (!info
->reset_addr
) {
1131 error_report("SEV-ES reset address is zero");
1135 *addr
= info
->reset_addr
;
1141 sev_es_find_reset_vector(void *flash_ptr
, uint64_t flash_size
,
1144 QemuUUID info_guid
, *guid
;
1150 * Initialize the address to zero. An address of zero with a successful
1151 * return code indicates that SEV-ES is not active.
1156 * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
1157 * The SEV GUID is located on its own (original implementation) or within
1158 * the Firmware GUID Table (new implementation), either of which are
1159 * located 32 bytes from the end of the flash.
1161 * Check the Firmware GUID Table first.
1163 if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID
, &data
, NULL
)) {
1164 return sev_es_parse_reset_block((SevInfoBlock
*)data
, addr
);
1168 * SEV info block not found in the Firmware GUID Table (or there isn't
1169 * a Firmware GUID Table), fall back to the original implementation.
1171 data
= flash_ptr
+ flash_size
- 0x20;
1173 qemu_uuid_parse(SEV_INFO_BLOCK_GUID
, &info_guid
);
1174 info_guid
= qemu_uuid_bswap(info_guid
); /* GUIDs are LE */
1176 guid
= (QemuUUID
*)(data
- sizeof(info_guid
));
1177 if (!qemu_uuid_is_equal(guid
, &info_guid
)) {
1178 error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
1182 len
= (uint16_t *)((uint8_t *)guid
- sizeof(*len
));
1183 info
= (SevInfoBlock
*)(data
- le16_to_cpu(*len
));
1185 return sev_es_parse_reset_block(info
, addr
);
1188 void sev_es_set_reset_vector(CPUState
*cpu
)
1193 /* Only update if we have valid reset information */
1194 if (!sev_guest
|| !sev_guest
->reset_data_valid
) {
1198 /* Do not update the BSP reset state */
1199 if (cpu
->cpu_index
== 0) {
1206 cpu_x86_load_seg_cache(env
, R_CS
, 0xf000, sev_guest
->reset_cs
, 0xffff,
1207 DESC_P_MASK
| DESC_S_MASK
| DESC_CS_MASK
|
1208 DESC_R_MASK
| DESC_A_MASK
);
1210 env
->eip
= sev_guest
->reset_ip
;
1213 int sev_es_save_reset_vector(void *flash_ptr
, uint64_t flash_size
)
1219 if (!sev_es_enabled()) {
1224 ret
= sev_es_find_reset_vector(flash_ptr
, flash_size
,
1231 sev_guest
->reset_cs
= addr
& 0xffff0000;
1232 sev_guest
->reset_ip
= addr
& 0x0000ffff;
1233 sev_guest
->reset_data_valid
= true;
1236 sev_es_set_reset_vector(cpu
);
1243 static const QemuUUID sev_hash_table_header_guid
= {
1244 .data
= UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
1245 0xd4, 0x11, 0xfd, 0x21)
1248 static const QemuUUID sev_kernel_entry_guid
= {
1249 .data
= UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
1250 0x72, 0xd2, 0x04, 0x5b)
1252 static const QemuUUID sev_initrd_entry_guid
= {
1253 .data
= UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
1254 0x91, 0x69, 0x78, 0x1d)
1256 static const QemuUUID sev_cmdline_entry_guid
= {
1257 .data
= UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
1258 0x4d, 0x36, 0xab, 0x2a)
1262 * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
1263 * which is included in SEV's initial memory measurement.
1265 bool sev_add_kernel_loader_hashes(SevKernelLoaderContext
*ctx
, Error
**errp
)
1268 SevHashTableDescriptor
*area
;
1270 PaddedSevHashTable
*padded_ht
;
1271 uint8_t cmdline_hash
[HASH_SIZE
];
1272 uint8_t initrd_hash
[HASH_SIZE
];
1273 uint8_t kernel_hash
[HASH_SIZE
];
1275 size_t hash_len
= HASH_SIZE
;
1276 hwaddr mapped_len
= sizeof(*padded_ht
);
1277 MemTxAttrs attrs
= { 0 };
1281 * Only add the kernel hashes if the sev-guest configuration explicitly
1282 * stated kernel-hashes=on.
1284 if (!sev_guest
->kernel_hashes
) {
1288 if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID
, &data
, NULL
)) {
1289 error_setg(errp
, "SEV: kernel specified but guest firmware "
1290 "has no hashes table GUID");
1293 area
= (SevHashTableDescriptor
*)data
;
1294 if (!area
->base
|| area
->size
< sizeof(PaddedSevHashTable
)) {
1295 error_setg(errp
, "SEV: guest firmware hashes table area is invalid "
1296 "(base=0x%x size=0x%x)", area
->base
, area
->size
);
1301 * Calculate hash of kernel command-line with the terminating null byte. If
1302 * the user doesn't supply a command-line via -append, the 1-byte "\0" will
1305 hashp
= cmdline_hash
;
1306 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->cmdline_data
,
1307 ctx
->cmdline_size
, &hashp
, &hash_len
, errp
) < 0) {
1310 assert(hash_len
== HASH_SIZE
);
1313 * Calculate hash of initrd. If the user doesn't supply an initrd via
1314 * -initrd, an empty buffer will be used (ctx->initrd_size == 0).
1316 hashp
= initrd_hash
;
1317 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->initrd_data
,
1318 ctx
->initrd_size
, &hashp
, &hash_len
, errp
) < 0) {
1321 assert(hash_len
== HASH_SIZE
);
1323 /* Calculate hash of the kernel */
1324 hashp
= kernel_hash
;
1325 struct iovec iov
[2] = {
1326 { .iov_base
= ctx
->setup_data
, .iov_len
= ctx
->setup_size
},
1327 { .iov_base
= ctx
->kernel_data
, .iov_len
= ctx
->kernel_size
}
1329 if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256
, iov
, ARRAY_SIZE(iov
),
1330 &hashp
, &hash_len
, errp
) < 0) {
1333 assert(hash_len
== HASH_SIZE
);
1336 * Populate the hashes table in the guest's memory at the OVMF-designated
1337 * area for the SEV hashes table
1339 padded_ht
= address_space_map(&address_space_memory
, area
->base
,
1340 &mapped_len
, true, attrs
);
1341 if (!padded_ht
|| mapped_len
!= sizeof(*padded_ht
)) {
1342 error_setg(errp
, "SEV: cannot map hashes table guest memory area");
1345 ht
= &padded_ht
->ht
;
1347 ht
->guid
= sev_hash_table_header_guid
;
1348 ht
->len
= sizeof(*ht
);
1350 ht
->cmdline
.guid
= sev_cmdline_entry_guid
;
1351 ht
->cmdline
.len
= sizeof(ht
->cmdline
);
1352 memcpy(ht
->cmdline
.hash
, cmdline_hash
, sizeof(ht
->cmdline
.hash
));
1354 ht
->initrd
.guid
= sev_initrd_entry_guid
;
1355 ht
->initrd
.len
= sizeof(ht
->initrd
);
1356 memcpy(ht
->initrd
.hash
, initrd_hash
, sizeof(ht
->initrd
.hash
));
1358 ht
->kernel
.guid
= sev_kernel_entry_guid
;
1359 ht
->kernel
.len
= sizeof(ht
->kernel
);
1360 memcpy(ht
->kernel
.hash
, kernel_hash
, sizeof(ht
->kernel
.hash
));
1362 /* zero the excess data so the measurement can be reliably calculated */
1363 memset(padded_ht
->padding
, 0, sizeof(padded_ht
->padding
));
1365 if (sev_encrypt_flash((uint8_t *)padded_ht
, sizeof(*padded_ht
), errp
) < 0) {
1369 address_space_unmap(&address_space_memory
, padded_ht
,
1370 mapped_len
, true, mapped_len
);
1376 sev_register_types(void)
1378 type_register_static(&sev_guest_info
);
1381 type_init(sev_register_types
);