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 "exec/confidential-guest-support.h"
38 #include "hw/i386/pc.h"
39 #include "exec/address-spaces.h"
41 #define TYPE_SEV_GUEST "sev-guest"
42 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState
, SEV_GUEST
)
48 * The SevGuestState object is used for creating and managing a SEV
52 * -object sev-guest,id=sev0 \
53 * -machine ...,memory-encryption=sev0
55 struct SevGuestState
{
56 ConfidentialGuestSupport parent_obj
;
58 /* configuration parameters */
64 uint32_t reduced_phys_bits
;
78 bool reset_data_valid
;
81 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
82 #define DEFAULT_SEV_DEVICE "/dev/sev"
84 #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
85 typedef struct __attribute__((__packed__
)) SevInfoBlock
{
86 /* SEV-ES Reset Vector Address */
90 #define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454"
91 typedef struct QEMU_PACKED SevHashTableDescriptor
{
92 /* SEV hash table area guest address */
94 /* SEV hash table area size (in bytes) */
96 } SevHashTableDescriptor
;
98 /* hard code sha256 digest size */
101 typedef struct QEMU_PACKED SevHashTableEntry
{
104 uint8_t hash
[HASH_SIZE
];
107 typedef struct QEMU_PACKED SevHashTable
{
110 SevHashTableEntry cmdline
;
111 SevHashTableEntry initrd
;
112 SevHashTableEntry kernel
;
116 * Data encrypted by sev_encrypt_flash() must be padded to a multiple of
119 typedef struct QEMU_PACKED PaddedSevHashTable
{
121 uint8_t padding
[ROUND_UP(sizeof(SevHashTable
), 16) - sizeof(SevHashTable
)];
122 } PaddedSevHashTable
;
124 QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable
) % 16 != 0);
126 static SevGuestState
*sev_guest
;
127 static Error
*sev_mig_blocker
;
129 static const char *const sev_fw_errlist
[] = {
130 [SEV_RET_SUCCESS
] = "",
131 [SEV_RET_INVALID_PLATFORM_STATE
] = "Platform state is invalid",
132 [SEV_RET_INVALID_GUEST_STATE
] = "Guest state is invalid",
133 [SEV_RET_INAVLID_CONFIG
] = "Platform configuration is invalid",
134 [SEV_RET_INVALID_LEN
] = "Buffer too small",
135 [SEV_RET_ALREADY_OWNED
] = "Platform is already owned",
136 [SEV_RET_INVALID_CERTIFICATE
] = "Certificate is invalid",
137 [SEV_RET_POLICY_FAILURE
] = "Policy is not allowed",
138 [SEV_RET_INACTIVE
] = "Guest is not active",
139 [SEV_RET_INVALID_ADDRESS
] = "Invalid address",
140 [SEV_RET_BAD_SIGNATURE
] = "Bad signature",
141 [SEV_RET_BAD_MEASUREMENT
] = "Bad measurement",
142 [SEV_RET_ASID_OWNED
] = "ASID is already owned",
143 [SEV_RET_INVALID_ASID
] = "Invalid ASID",
144 [SEV_RET_WBINVD_REQUIRED
] = "WBINVD is required",
145 [SEV_RET_DFFLUSH_REQUIRED
] = "DF_FLUSH is required",
146 [SEV_RET_INVALID_GUEST
] = "Guest handle is invalid",
147 [SEV_RET_INVALID_COMMAND
] = "Invalid command",
148 [SEV_RET_ACTIVE
] = "Guest is active",
149 [SEV_RET_HWSEV_RET_PLATFORM
] = "Hardware error",
150 [SEV_RET_HWSEV_RET_UNSAFE
] = "Hardware unsafe",
151 [SEV_RET_UNSUPPORTED
] = "Feature not supported",
152 [SEV_RET_INVALID_PARAM
] = "Invalid parameter",
153 [SEV_RET_RESOURCE_LIMIT
] = "Required firmware resource depleted",
154 [SEV_RET_SECURE_DATA_INVALID
] = "Part-specific integrity check failure",
157 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
160 sev_ioctl(int fd
, int cmd
, void *data
, int *error
)
163 struct kvm_sev_cmd input
;
165 memset(&input
, 0x0, sizeof(input
));
169 input
.data
= (__u64
)(unsigned long)data
;
171 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, &input
);
174 *error
= input
.error
;
181 sev_platform_ioctl(int fd
, int cmd
, void *data
, int *error
)
184 struct sev_issue_cmd arg
;
187 arg
.data
= (unsigned long)data
;
188 r
= ioctl(fd
, SEV_ISSUE_CMD
, &arg
);
197 fw_error_to_str(int code
)
199 if (code
< 0 || code
>= SEV_FW_MAX_ERROR
) {
200 return "unknown error";
203 return sev_fw_errlist
[code
];
207 sev_check_state(const SevGuestState
*sev
, SevState state
)
210 return sev
->state
== state
? true : false;
214 sev_set_guest_state(SevGuestState
*sev
, SevState new_state
)
216 assert(new_state
< SEV_STATE__MAX
);
219 trace_kvm_sev_change_state(SevState_str(sev
->state
),
220 SevState_str(new_state
));
221 sev
->state
= new_state
;
225 sev_ram_block_added(RAMBlockNotifier
*n
, void *host
, size_t size
,
229 struct kvm_enc_region range
;
234 * The RAM device presents a memory region that should be treated
235 * as IO region and should not be pinned.
237 mr
= memory_region_from_host(host
, &offset
);
238 if (mr
&& memory_region_is_ram_device(mr
)) {
242 range
.addr
= (__u64
)(unsigned long)host
;
243 range
.size
= max_size
;
245 trace_kvm_memcrypt_register_region(host
, max_size
);
246 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_REG_REGION
, &range
);
248 error_report("%s: failed to register region (%p+%#zx) error '%s'",
249 __func__
, host
, max_size
, strerror(errno
));
255 sev_ram_block_removed(RAMBlockNotifier
*n
, void *host
, size_t size
,
259 struct kvm_enc_region range
;
264 * The RAM device presents a memory region that should be treated
265 * as IO region and should not have been pinned.
267 mr
= memory_region_from_host(host
, &offset
);
268 if (mr
&& memory_region_is_ram_device(mr
)) {
272 range
.addr
= (__u64
)(unsigned long)host
;
273 range
.size
= max_size
;
275 trace_kvm_memcrypt_unregister_region(host
, max_size
);
276 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_UNREG_REGION
, &range
);
278 error_report("%s: failed to unregister region (%p+%#zx)",
279 __func__
, host
, max_size
);
283 static struct RAMBlockNotifier sev_ram_notifier
= {
284 .ram_block_added
= sev_ram_block_added
,
285 .ram_block_removed
= sev_ram_block_removed
,
289 sev_guest_finalize(Object
*obj
)
294 sev_guest_get_session_file(Object
*obj
, Error
**errp
)
296 SevGuestState
*s
= SEV_GUEST(obj
);
298 return s
->session_file
? g_strdup(s
->session_file
) : NULL
;
302 sev_guest_set_session_file(Object
*obj
, const char *value
, Error
**errp
)
304 SevGuestState
*s
= SEV_GUEST(obj
);
306 s
->session_file
= g_strdup(value
);
310 sev_guest_get_dh_cert_file(Object
*obj
, Error
**errp
)
312 SevGuestState
*s
= SEV_GUEST(obj
);
314 return g_strdup(s
->dh_cert_file
);
318 sev_guest_set_dh_cert_file(Object
*obj
, const char *value
, Error
**errp
)
320 SevGuestState
*s
= SEV_GUEST(obj
);
322 s
->dh_cert_file
= g_strdup(value
);
326 sev_guest_get_sev_device(Object
*obj
, Error
**errp
)
328 SevGuestState
*sev
= SEV_GUEST(obj
);
330 return g_strdup(sev
->sev_device
);
334 sev_guest_set_sev_device(Object
*obj
, const char *value
, Error
**errp
)
336 SevGuestState
*sev
= SEV_GUEST(obj
);
338 sev
->sev_device
= g_strdup(value
);
341 static bool sev_guest_get_kernel_hashes(Object
*obj
, Error
**errp
)
343 SevGuestState
*sev
= SEV_GUEST(obj
);
345 return sev
->kernel_hashes
;
348 static void sev_guest_set_kernel_hashes(Object
*obj
, bool value
, Error
**errp
)
350 SevGuestState
*sev
= SEV_GUEST(obj
);
352 sev
->kernel_hashes
= value
;
356 sev_guest_class_init(ObjectClass
*oc
, void *data
)
358 object_class_property_add_str(oc
, "sev-device",
359 sev_guest_get_sev_device
,
360 sev_guest_set_sev_device
);
361 object_class_property_set_description(oc
, "sev-device",
362 "SEV device to use");
363 object_class_property_add_str(oc
, "dh-cert-file",
364 sev_guest_get_dh_cert_file
,
365 sev_guest_set_dh_cert_file
);
366 object_class_property_set_description(oc
, "dh-cert-file",
367 "guest owners DH certificate (encoded with base64)");
368 object_class_property_add_str(oc
, "session-file",
369 sev_guest_get_session_file
,
370 sev_guest_set_session_file
);
371 object_class_property_set_description(oc
, "session-file",
372 "guest owners session parameters (encoded with base64)");
373 object_class_property_add_bool(oc
, "kernel-hashes",
374 sev_guest_get_kernel_hashes
,
375 sev_guest_set_kernel_hashes
);
376 object_class_property_set_description(oc
, "kernel-hashes",
377 "add kernel hashes to guest firmware for measured Linux boot");
381 sev_guest_instance_init(Object
*obj
)
383 SevGuestState
*sev
= SEV_GUEST(obj
);
385 sev
->sev_device
= g_strdup(DEFAULT_SEV_DEVICE
);
386 sev
->policy
= DEFAULT_GUEST_POLICY
;
387 object_property_add_uint32_ptr(obj
, "policy", &sev
->policy
,
388 OBJ_PROP_FLAG_READWRITE
);
389 object_property_add_uint32_ptr(obj
, "handle", &sev
->handle
,
390 OBJ_PROP_FLAG_READWRITE
);
391 object_property_add_uint32_ptr(obj
, "cbitpos", &sev
->cbitpos
,
392 OBJ_PROP_FLAG_READWRITE
);
393 object_property_add_uint32_ptr(obj
, "reduced-phys-bits",
394 &sev
->reduced_phys_bits
,
395 OBJ_PROP_FLAG_READWRITE
);
399 static const TypeInfo sev_guest_info
= {
400 .parent
= TYPE_CONFIDENTIAL_GUEST_SUPPORT
,
401 .name
= TYPE_SEV_GUEST
,
402 .instance_size
= sizeof(SevGuestState
),
403 .instance_finalize
= sev_guest_finalize
,
404 .class_init
= sev_guest_class_init
,
405 .instance_init
= sev_guest_instance_init
,
406 .interfaces
= (InterfaceInfo
[]) {
407 { TYPE_USER_CREATABLE
},
421 return sev_enabled() && (sev_guest
->policy
& SEV_POLICY_ES
);
425 sev_get_cbit_position(void)
427 return sev_guest
? sev_guest
->cbitpos
: 0;
431 sev_get_reduced_phys_bits(void)
433 return sev_guest
? sev_guest
->reduced_phys_bits
: 0;
436 static SevInfo
*sev_get_info(void)
440 info
= g_new0(SevInfo
, 1);
441 info
->enabled
= sev_enabled();
444 info
->api_major
= sev_guest
->api_major
;
445 info
->api_minor
= sev_guest
->api_minor
;
446 info
->build_id
= sev_guest
->build_id
;
447 info
->policy
= sev_guest
->policy
;
448 info
->state
= sev_guest
->state
;
449 info
->handle
= sev_guest
->handle
;
455 SevInfo
*qmp_query_sev(Error
**errp
)
459 info
= sev_get_info();
461 error_setg(errp
, "SEV feature is not available");
468 void hmp_info_sev(Monitor
*mon
, const QDict
*qdict
)
470 SevInfo
*info
= sev_get_info();
472 if (info
&& info
->enabled
) {
473 monitor_printf(mon
, "handle: %d\n", info
->handle
);
474 monitor_printf(mon
, "state: %s\n", SevState_str(info
->state
));
475 monitor_printf(mon
, "build: %d\n", info
->build_id
);
476 monitor_printf(mon
, "api version: %d.%d\n",
477 info
->api_major
, info
->api_minor
);
478 monitor_printf(mon
, "debug: %s\n",
479 info
->policy
& SEV_POLICY_NODBG
? "off" : "on");
480 monitor_printf(mon
, "key-sharing: %s\n",
481 info
->policy
& SEV_POLICY_NOKS
? "off" : "on");
483 monitor_printf(mon
, "SEV is not enabled\n");
486 qapi_free_SevInfo(info
);
490 sev_get_pdh_info(int fd
, guchar
**pdh
, size_t *pdh_len
, guchar
**cert_chain
,
491 size_t *cert_chain_len
, Error
**errp
)
493 guchar
*pdh_data
= NULL
;
494 guchar
*cert_chain_data
= NULL
;
495 struct sev_user_data_pdh_cert_export export
= {};
498 /* query the certificate length */
499 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
501 if (err
!= SEV_RET_INVALID_LEN
) {
502 error_setg(errp
, "SEV: Failed to export PDH cert"
503 " ret=%d fw_err=%d (%s)",
504 r
, err
, fw_error_to_str(err
));
509 pdh_data
= g_new(guchar
, export
.pdh_cert_len
);
510 cert_chain_data
= g_new(guchar
, export
.cert_chain_len
);
511 export
.pdh_cert_address
= (unsigned long)pdh_data
;
512 export
.cert_chain_address
= (unsigned long)cert_chain_data
;
514 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
516 error_setg(errp
, "SEV: Failed to export PDH cert ret=%d fw_err=%d (%s)",
517 r
, err
, fw_error_to_str(err
));
522 *pdh_len
= export
.pdh_cert_len
;
523 *cert_chain
= cert_chain_data
;
524 *cert_chain_len
= export
.cert_chain_len
;
529 g_free(cert_chain_data
);
533 static int sev_get_cpu0_id(int fd
, guchar
**id
, size_t *id_len
, Error
**errp
)
536 struct sev_user_data_get_id2 get_id2
= {};
539 /* query the ID length */
540 r
= sev_platform_ioctl(fd
, SEV_GET_ID2
, &get_id2
, &err
);
541 if (r
< 0 && err
!= SEV_RET_INVALID_LEN
) {
542 error_setg(errp
, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
543 r
, err
, fw_error_to_str(err
));
547 id_data
= g_new(guchar
, get_id2
.length
);
548 get_id2
.address
= (unsigned long)id_data
;
550 r
= sev_platform_ioctl(fd
, SEV_GET_ID2
, &get_id2
, &err
);
552 error_setg(errp
, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
553 r
, err
, fw_error_to_str(err
));
558 *id_len
= get_id2
.length
;
566 static SevCapability
*sev_get_capabilities(Error
**errp
)
568 SevCapability
*cap
= NULL
;
569 guchar
*pdh_data
= NULL
;
570 guchar
*cert_chain_data
= NULL
;
571 guchar
*cpu0_id_data
= NULL
;
572 size_t pdh_len
= 0, cert_chain_len
= 0, cpu0_id_len
= 0;
576 if (!kvm_enabled()) {
577 error_setg(errp
, "KVM not enabled");
580 if (kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, NULL
) < 0) {
581 error_setg(errp
, "SEV is not enabled in KVM");
585 fd
= open(DEFAULT_SEV_DEVICE
, O_RDWR
);
587 error_setg_errno(errp
, errno
, "SEV: Failed to open %s",
592 if (sev_get_pdh_info(fd
, &pdh_data
, &pdh_len
,
593 &cert_chain_data
, &cert_chain_len
, errp
)) {
597 if (sev_get_cpu0_id(fd
, &cpu0_id_data
, &cpu0_id_len
, errp
)) {
601 cap
= g_new0(SevCapability
, 1);
602 cap
->pdh
= g_base64_encode(pdh_data
, pdh_len
);
603 cap
->cert_chain
= g_base64_encode(cert_chain_data
, cert_chain_len
);
604 cap
->cpu0_id
= g_base64_encode(cpu0_id_data
, cpu0_id_len
);
606 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
607 cap
->cbitpos
= ebx
& 0x3f;
610 * When SEV feature is enabled, we loose one bit in guest physical
613 cap
->reduced_phys_bits
= 1;
616 g_free(cpu0_id_data
);
618 g_free(cert_chain_data
);
623 SevCapability
*qmp_query_sev_capabilities(Error
**errp
)
625 return sev_get_capabilities(errp
);
628 static SevAttestationReport
*sev_get_attestation_report(const char *mnonce
,
631 struct kvm_sev_attestation_report input
= {};
632 SevAttestationReport
*report
= NULL
;
633 SevGuestState
*sev
= sev_guest
;
634 g_autofree guchar
*data
= NULL
;
635 g_autofree guchar
*buf
= NULL
;
639 if (!sev_enabled()) {
640 error_setg(errp
, "SEV is not enabled");
644 /* lets decode the mnonce string */
645 buf
= g_base64_decode(mnonce
, &len
);
647 error_setg(errp
, "SEV: failed to decode mnonce input");
651 /* verify the input mnonce length */
652 if (len
!= sizeof(input
.mnonce
)) {
653 error_setg(errp
, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT
")",
654 sizeof(input
.mnonce
), len
);
658 /* Query the report length */
659 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
662 if (err
!= SEV_RET_INVALID_LEN
) {
663 error_setg(errp
, "SEV: Failed to query the attestation report"
664 " length ret=%d fw_err=%d (%s)",
665 ret
, err
, fw_error_to_str(err
));
670 data
= g_malloc(input
.len
);
671 input
.uaddr
= (unsigned long)data
;
672 memcpy(input
.mnonce
, buf
, sizeof(input
.mnonce
));
674 /* Query the report */
675 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
678 error_setg_errno(errp
, errno
, "SEV: Failed to get attestation report"
679 " ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
683 report
= g_new0(SevAttestationReport
, 1);
684 report
->data
= g_base64_encode(data
, input
.len
);
686 trace_kvm_sev_attestation_report(mnonce
, report
->data
);
691 SevAttestationReport
*qmp_query_sev_attestation_report(const char *mnonce
,
694 return sev_get_attestation_report(mnonce
, errp
);
698 sev_read_file_base64(const char *filename
, guchar
**data
, gsize
*len
)
701 g_autofree gchar
*base64
= NULL
;
702 GError
*error
= NULL
;
704 if (!g_file_get_contents(filename
, &base64
, &sz
, &error
)) {
705 error_report("SEV: Failed to read '%s' (%s)", filename
, error
->message
);
710 *data
= g_base64_decode(base64
, len
);
715 sev_launch_start(SevGuestState
*sev
)
720 struct kvm_sev_launch_start start
= {
721 .handle
= sev
->handle
, .policy
= sev
->policy
723 guchar
*session
= NULL
, *dh_cert
= NULL
;
725 if (sev
->session_file
) {
726 if (sev_read_file_base64(sev
->session_file
, &session
, &sz
) < 0) {
729 start
.session_uaddr
= (unsigned long)session
;
730 start
.session_len
= sz
;
733 if (sev
->dh_cert_file
) {
734 if (sev_read_file_base64(sev
->dh_cert_file
, &dh_cert
, &sz
) < 0) {
737 start
.dh_uaddr
= (unsigned long)dh_cert
;
741 trace_kvm_sev_launch_start(start
.policy
, session
, dh_cert
);
742 rc
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_START
, &start
, &fw_error
);
744 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
745 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
749 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_UPDATE
);
750 sev
->handle
= start
.handle
;
760 sev_launch_update_data(SevGuestState
*sev
, uint8_t *addr
, uint64_t len
)
763 struct kvm_sev_launch_update_data update
;
769 update
.uaddr
= (__u64
)(unsigned long)addr
;
771 trace_kvm_sev_launch_update_data(addr
, len
);
772 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_DATA
,
775 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
776 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
783 sev_launch_update_vmsa(SevGuestState
*sev
)
787 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_VMSA
, NULL
, &fw_error
);
789 error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
790 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
797 sev_launch_get_measure(Notifier
*notifier
, void *unused
)
799 SevGuestState
*sev
= sev_guest
;
801 g_autofree guchar
*data
= NULL
;
802 struct kvm_sev_launch_measure measurement
= {};
804 if (!sev_check_state(sev
, SEV_STATE_LAUNCH_UPDATE
)) {
808 if (sev_es_enabled()) {
809 /* measure all the VM save areas before getting launch_measure */
810 ret
= sev_launch_update_vmsa(sev
);
816 /* query the measurement blob length */
817 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
818 &measurement
, &error
);
819 if (!measurement
.len
) {
820 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
821 __func__
, ret
, error
, fw_error_to_str(errno
));
825 data
= g_new0(guchar
, measurement
.len
);
826 measurement
.uaddr
= (unsigned long)data
;
828 /* get the measurement blob */
829 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
830 &measurement
, &error
);
832 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
833 __func__
, ret
, error
, fw_error_to_str(errno
));
837 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_SECRET
);
839 /* encode the measurement value and emit the event */
840 sev
->measurement
= g_base64_encode(data
, measurement
.len
);
841 trace_kvm_sev_launch_measurement(sev
->measurement
);
844 static char *sev_get_launch_measurement(void)
847 sev_guest
->state
>= SEV_STATE_LAUNCH_SECRET
) {
848 return g_strdup(sev_guest
->measurement
);
854 SevLaunchMeasureInfo
*qmp_query_sev_launch_measure(Error
**errp
)
857 SevLaunchMeasureInfo
*info
;
859 data
= sev_get_launch_measurement();
861 error_setg(errp
, "SEV launch measurement is not available");
865 info
= g_malloc0(sizeof(*info
));
871 static Notifier sev_machine_done_notify
= {
872 .notify
= sev_launch_get_measure
,
876 sev_launch_finish(SevGuestState
*sev
)
880 trace_kvm_sev_launch_finish();
881 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_FINISH
, 0, &error
);
883 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
884 __func__
, ret
, error
, fw_error_to_str(error
));
888 sev_set_guest_state(sev
, SEV_STATE_RUNNING
);
890 /* add migration blocker */
891 error_setg(&sev_mig_blocker
,
892 "SEV: Migration is not implemented");
893 migrate_add_blocker(sev_mig_blocker
, &error_fatal
);
897 sev_vm_state_change(void *opaque
, bool running
, RunState state
)
899 SevGuestState
*sev
= opaque
;
902 if (!sev_check_state(sev
, SEV_STATE_RUNNING
)) {
903 sev_launch_finish(sev
);
908 int sev_kvm_init(ConfidentialGuestSupport
*cgs
, Error
**errp
)
911 = (SevGuestState
*)object_dynamic_cast(OBJECT(cgs
), TYPE_SEV_GUEST
);
913 int ret
, fw_error
, cmd
;
915 uint32_t host_cbitpos
;
916 struct sev_user_data_status status
= {};
922 ret
= ram_block_discard_disable(true);
924 error_report("%s: cannot disable RAM discard", __func__
);
929 sev
->state
= SEV_STATE_UNINIT
;
931 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
932 host_cbitpos
= ebx
& 0x3f;
934 if (host_cbitpos
!= sev
->cbitpos
) {
935 error_setg(errp
, "%s: cbitpos check failed, host '%d' requested '%d'",
936 __func__
, host_cbitpos
, sev
->cbitpos
);
940 if (sev
->reduced_phys_bits
< 1) {
941 error_setg(errp
, "%s: reduced_phys_bits check failed, it should be >=1,"
942 " requested '%d'", __func__
, sev
->reduced_phys_bits
);
946 devname
= object_property_get_str(OBJECT(sev
), "sev-device", NULL
);
947 sev
->sev_fd
= open(devname
, O_RDWR
);
948 if (sev
->sev_fd
< 0) {
949 error_setg(errp
, "%s: Failed to open %s '%s'", __func__
,
950 devname
, strerror(errno
));
956 ret
= sev_platform_ioctl(sev
->sev_fd
, SEV_PLATFORM_STATUS
, &status
,
959 error_setg(errp
, "%s: failed to get platform status ret=%d "
960 "fw_error='%d: %s'", __func__
, ret
, fw_error
,
961 fw_error_to_str(fw_error
));
964 sev
->build_id
= status
.build
;
965 sev
->api_major
= status
.api_major
;
966 sev
->api_minor
= status
.api_minor
;
968 if (sev_es_enabled()) {
969 if (!kvm_kernel_irqchip_allowed()) {
970 error_report("%s: SEV-ES guests require in-kernel irqchip support",
975 if (!(status
.flags
& SEV_STATUS_FLAGS_CONFIG_ES
)) {
976 error_report("%s: guest policy requires SEV-ES, but "
977 "host SEV-ES support unavailable",
981 cmd
= KVM_SEV_ES_INIT
;
986 trace_kvm_sev_init();
987 ret
= sev_ioctl(sev
->sev_fd
, cmd
, NULL
, &fw_error
);
989 error_setg(errp
, "%s: failed to initialize ret=%d fw_error=%d '%s'",
990 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
994 ret
= sev_launch_start(sev
);
996 error_setg(errp
, "%s: failed to create encryption context", __func__
);
1000 ram_block_notifier_add(&sev_ram_notifier
);
1001 qemu_add_machine_init_done_notifier(&sev_machine_done_notify
);
1002 qemu_add_vm_change_state_handler(sev_vm_state_change
, sev
);
1009 ram_block_discard_disable(false);
1014 sev_encrypt_flash(uint8_t *ptr
, uint64_t len
, Error
**errp
)
1020 /* if SEV is in update state then encrypt the data else do nothing */
1021 if (sev_check_state(sev_guest
, SEV_STATE_LAUNCH_UPDATE
)) {
1022 int ret
= sev_launch_update_data(sev_guest
, ptr
, len
);
1024 error_setg(errp
, "SEV: Failed to encrypt pflash rom");
1032 int sev_inject_launch_secret(const char *packet_hdr
, const char *secret
,
1033 uint64_t gpa
, Error
**errp
)
1035 struct kvm_sev_launch_secret input
;
1036 g_autofree guchar
*data
= NULL
, *hdr
= NULL
;
1039 gsize hdr_sz
= 0, data_sz
= 0;
1040 MemoryRegion
*mr
= NULL
;
1043 error_setg(errp
, "SEV not enabled for guest");
1047 /* secret can be injected only in this state */
1048 if (!sev_check_state(sev_guest
, SEV_STATE_LAUNCH_SECRET
)) {
1049 error_setg(errp
, "SEV: Not in correct state. (LSECRET) %x",
1054 hdr
= g_base64_decode(packet_hdr
, &hdr_sz
);
1055 if (!hdr
|| !hdr_sz
) {
1056 error_setg(errp
, "SEV: Failed to decode sequence header");
1060 data
= g_base64_decode(secret
, &data_sz
);
1061 if (!data
|| !data_sz
) {
1062 error_setg(errp
, "SEV: Failed to decode data");
1066 hva
= gpa2hva(&mr
, gpa
, data_sz
, errp
);
1068 error_prepend(errp
, "SEV: Failed to calculate guest address: ");
1072 input
.hdr_uaddr
= (uint64_t)(unsigned long)hdr
;
1073 input
.hdr_len
= hdr_sz
;
1075 input
.trans_uaddr
= (uint64_t)(unsigned long)data
;
1076 input
.trans_len
= data_sz
;
1078 input
.guest_uaddr
= (uint64_t)(unsigned long)hva
;
1079 input
.guest_len
= data_sz
;
1081 trace_kvm_sev_launch_secret(gpa
, input
.guest_uaddr
,
1082 input
.trans_uaddr
, input
.trans_len
);
1084 ret
= sev_ioctl(sev_guest
->sev_fd
, KVM_SEV_LAUNCH_SECRET
,
1087 error_setg(errp
, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
1088 ret
, error
, fw_error_to_str(error
));
1095 #define SEV_SECRET_GUID "4c2eb361-7d9b-4cc3-8081-127c90d3d294"
1096 struct sev_secret_area
{
1101 void qmp_sev_inject_launch_secret(const char *packet_hdr
,
1103 bool has_gpa
, uint64_t gpa
,
1106 if (!sev_enabled()) {
1107 error_setg(errp
, "SEV not enabled for guest");
1112 struct sev_secret_area
*area
;
1114 if (!pc_system_ovmf_table_find(SEV_SECRET_GUID
, &data
, NULL
)) {
1115 error_setg(errp
, "SEV: no secret area found in OVMF,"
1116 " gpa must be specified.");
1119 area
= (struct sev_secret_area
*)data
;
1123 sev_inject_launch_secret(packet_hdr
, secret
, gpa
, errp
);
1127 sev_es_parse_reset_block(SevInfoBlock
*info
, uint32_t *addr
)
1129 if (!info
->reset_addr
) {
1130 error_report("SEV-ES reset address is zero");
1134 *addr
= info
->reset_addr
;
1140 sev_es_find_reset_vector(void *flash_ptr
, uint64_t flash_size
,
1143 QemuUUID info_guid
, *guid
;
1149 * Initialize the address to zero. An address of zero with a successful
1150 * return code indicates that SEV-ES is not active.
1155 * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
1156 * The SEV GUID is located on its own (original implementation) or within
1157 * the Firmware GUID Table (new implementation), either of which are
1158 * located 32 bytes from the end of the flash.
1160 * Check the Firmware GUID Table first.
1162 if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID
, &data
, NULL
)) {
1163 return sev_es_parse_reset_block((SevInfoBlock
*)data
, addr
);
1167 * SEV info block not found in the Firmware GUID Table (or there isn't
1168 * a Firmware GUID Table), fall back to the original implementation.
1170 data
= flash_ptr
+ flash_size
- 0x20;
1172 qemu_uuid_parse(SEV_INFO_BLOCK_GUID
, &info_guid
);
1173 info_guid
= qemu_uuid_bswap(info_guid
); /* GUIDs are LE */
1175 guid
= (QemuUUID
*)(data
- sizeof(info_guid
));
1176 if (!qemu_uuid_is_equal(guid
, &info_guid
)) {
1177 error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
1181 len
= (uint16_t *)((uint8_t *)guid
- sizeof(*len
));
1182 info
= (SevInfoBlock
*)(data
- le16_to_cpu(*len
));
1184 return sev_es_parse_reset_block(info
, addr
);
1187 void sev_es_set_reset_vector(CPUState
*cpu
)
1192 /* Only update if we have valid reset information */
1193 if (!sev_guest
|| !sev_guest
->reset_data_valid
) {
1197 /* Do not update the BSP reset state */
1198 if (cpu
->cpu_index
== 0) {
1205 cpu_x86_load_seg_cache(env
, R_CS
, 0xf000, sev_guest
->reset_cs
, 0xffff,
1206 DESC_P_MASK
| DESC_S_MASK
| DESC_CS_MASK
|
1207 DESC_R_MASK
| DESC_A_MASK
);
1209 env
->eip
= sev_guest
->reset_ip
;
1212 int sev_es_save_reset_vector(void *flash_ptr
, uint64_t flash_size
)
1218 if (!sev_es_enabled()) {
1223 ret
= sev_es_find_reset_vector(flash_ptr
, flash_size
,
1230 sev_guest
->reset_cs
= addr
& 0xffff0000;
1231 sev_guest
->reset_ip
= addr
& 0x0000ffff;
1232 sev_guest
->reset_data_valid
= true;
1235 sev_es_set_reset_vector(cpu
);
1242 static const QemuUUID sev_hash_table_header_guid
= {
1243 .data
= UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
1244 0xd4, 0x11, 0xfd, 0x21)
1247 static const QemuUUID sev_kernel_entry_guid
= {
1248 .data
= UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
1249 0x72, 0xd2, 0x04, 0x5b)
1251 static const QemuUUID sev_initrd_entry_guid
= {
1252 .data
= UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
1253 0x91, 0x69, 0x78, 0x1d)
1255 static const QemuUUID sev_cmdline_entry_guid
= {
1256 .data
= UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
1257 0x4d, 0x36, 0xab, 0x2a)
1261 * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
1262 * which is included in SEV's initial memory measurement.
1264 bool sev_add_kernel_loader_hashes(SevKernelLoaderContext
*ctx
, Error
**errp
)
1267 SevHashTableDescriptor
*area
;
1269 PaddedSevHashTable
*padded_ht
;
1270 uint8_t cmdline_hash
[HASH_SIZE
];
1271 uint8_t initrd_hash
[HASH_SIZE
];
1272 uint8_t kernel_hash
[HASH_SIZE
];
1274 size_t hash_len
= HASH_SIZE
;
1275 hwaddr mapped_len
= sizeof(*padded_ht
);
1276 MemTxAttrs attrs
= { 0 };
1280 * Only add the kernel hashes if the sev-guest configuration explicitly
1281 * stated kernel-hashes=on.
1283 if (!sev_guest
->kernel_hashes
) {
1287 if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID
, &data
, NULL
)) {
1288 error_setg(errp
, "SEV: kernel specified but guest firmware "
1289 "has no hashes table GUID");
1292 area
= (SevHashTableDescriptor
*)data
;
1293 if (!area
->base
|| area
->size
< sizeof(PaddedSevHashTable
)) {
1294 error_setg(errp
, "SEV: guest firmware hashes table area is invalid "
1295 "(base=0x%x size=0x%x)", area
->base
, area
->size
);
1300 * Calculate hash of kernel command-line with the terminating null byte. If
1301 * the user doesn't supply a command-line via -append, the 1-byte "\0" will
1304 hashp
= cmdline_hash
;
1305 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->cmdline_data
,
1306 ctx
->cmdline_size
, &hashp
, &hash_len
, errp
) < 0) {
1309 assert(hash_len
== HASH_SIZE
);
1312 * Calculate hash of initrd. If the user doesn't supply an initrd via
1313 * -initrd, an empty buffer will be used (ctx->initrd_size == 0).
1315 hashp
= initrd_hash
;
1316 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->initrd_data
,
1317 ctx
->initrd_size
, &hashp
, &hash_len
, errp
) < 0) {
1320 assert(hash_len
== HASH_SIZE
);
1322 /* Calculate hash of the kernel */
1323 hashp
= kernel_hash
;
1324 struct iovec iov
[2] = {
1325 { .iov_base
= ctx
->setup_data
, .iov_len
= ctx
->setup_size
},
1326 { .iov_base
= ctx
->kernel_data
, .iov_len
= ctx
->kernel_size
}
1328 if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256
, iov
, ARRAY_SIZE(iov
),
1329 &hashp
, &hash_len
, errp
) < 0) {
1332 assert(hash_len
== HASH_SIZE
);
1335 * Populate the hashes table in the guest's memory at the OVMF-designated
1336 * area for the SEV hashes table
1338 padded_ht
= address_space_map(&address_space_memory
, area
->base
,
1339 &mapped_len
, true, attrs
);
1340 if (!padded_ht
|| mapped_len
!= sizeof(*padded_ht
)) {
1341 error_setg(errp
, "SEV: cannot map hashes table guest memory area");
1344 ht
= &padded_ht
->ht
;
1346 ht
->guid
= sev_hash_table_header_guid
;
1347 ht
->len
= sizeof(*ht
);
1349 ht
->cmdline
.guid
= sev_cmdline_entry_guid
;
1350 ht
->cmdline
.len
= sizeof(ht
->cmdline
);
1351 memcpy(ht
->cmdline
.hash
, cmdline_hash
, sizeof(ht
->cmdline
.hash
));
1353 ht
->initrd
.guid
= sev_initrd_entry_guid
;
1354 ht
->initrd
.len
= sizeof(ht
->initrd
);
1355 memcpy(ht
->initrd
.hash
, initrd_hash
, sizeof(ht
->initrd
.hash
));
1357 ht
->kernel
.guid
= sev_kernel_entry_guid
;
1358 ht
->kernel
.len
= sizeof(ht
->kernel
);
1359 memcpy(ht
->kernel
.hash
, kernel_hash
, sizeof(ht
->kernel
.hash
));
1361 /* zero the excess data so the measurement can be reliably calculated */
1362 memset(padded_ht
->padding
, 0, sizeof(padded_ht
->padding
));
1364 if (sev_encrypt_flash((uint8_t *)padded_ht
, sizeof(*padded_ht
), errp
) < 0) {
1368 address_space_unmap(&address_space_memory
, padded_ht
,
1369 mapped_len
, true, mapped_len
);
1375 sev_register_types(void)
1377 type_register_static(&sev_guest_info
);
1380 type_init(sev_register_types
);