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 "exec/confidential-guest-support.h"
36 #include "hw/i386/pc.h"
38 #define TYPE_SEV_GUEST "sev-guest"
39 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState
, SEV_GUEST
)
45 * The SevGuestState object is used for creating and managing a SEV
49 * -object sev-guest,id=sev0 \
50 * -machine ...,memory-encryption=sev0
52 struct SevGuestState
{
53 ConfidentialGuestSupport parent_obj
;
55 /* configuration parameters */
61 uint32_t reduced_phys_bits
;
75 bool reset_data_valid
;
78 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
79 #define DEFAULT_SEV_DEVICE "/dev/sev"
81 #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
82 typedef struct __attribute__((__packed__
)) SevInfoBlock
{
83 /* SEV-ES Reset Vector Address */
87 #define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454"
88 typedef struct QEMU_PACKED SevHashTableDescriptor
{
89 /* SEV hash table area guest address */
91 /* SEV hash table area size (in bytes) */
93 } SevHashTableDescriptor
;
95 /* hard code sha256 digest size */
98 typedef struct QEMU_PACKED SevHashTableEntry
{
101 uint8_t hash
[HASH_SIZE
];
104 typedef struct QEMU_PACKED SevHashTable
{
107 SevHashTableEntry cmdline
;
108 SevHashTableEntry initrd
;
109 SevHashTableEntry kernel
;
113 static SevGuestState
*sev_guest
;
114 static Error
*sev_mig_blocker
;
116 static const char *const sev_fw_errlist
[] = {
117 [SEV_RET_SUCCESS
] = "",
118 [SEV_RET_INVALID_PLATFORM_STATE
] = "Platform state is invalid",
119 [SEV_RET_INVALID_GUEST_STATE
] = "Guest state is invalid",
120 [SEV_RET_INAVLID_CONFIG
] = "Platform configuration is invalid",
121 [SEV_RET_INVALID_LEN
] = "Buffer too small",
122 [SEV_RET_ALREADY_OWNED
] = "Platform is already owned",
123 [SEV_RET_INVALID_CERTIFICATE
] = "Certificate is invalid",
124 [SEV_RET_POLICY_FAILURE
] = "Policy is not allowed",
125 [SEV_RET_INACTIVE
] = "Guest is not active",
126 [SEV_RET_INVALID_ADDRESS
] = "Invalid address",
127 [SEV_RET_BAD_SIGNATURE
] = "Bad signature",
128 [SEV_RET_BAD_MEASUREMENT
] = "Bad measurement",
129 [SEV_RET_ASID_OWNED
] = "ASID is already owned",
130 [SEV_RET_INVALID_ASID
] = "Invalid ASID",
131 [SEV_RET_WBINVD_REQUIRED
] = "WBINVD is required",
132 [SEV_RET_DFFLUSH_REQUIRED
] = "DF_FLUSH is required",
133 [SEV_RET_INVALID_GUEST
] = "Guest handle is invalid",
134 [SEV_RET_INVALID_COMMAND
] = "Invalid command",
135 [SEV_RET_ACTIVE
] = "Guest is active",
136 [SEV_RET_HWSEV_RET_PLATFORM
] = "Hardware error",
137 [SEV_RET_HWSEV_RET_UNSAFE
] = "Hardware unsafe",
138 [SEV_RET_UNSUPPORTED
] = "Feature not supported",
139 [SEV_RET_INVALID_PARAM
] = "Invalid parameter",
140 [SEV_RET_RESOURCE_LIMIT
] = "Required firmware resource depleted",
141 [SEV_RET_SECURE_DATA_INVALID
] = "Part-specific integrity check failure",
144 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
147 sev_ioctl(int fd
, int cmd
, void *data
, int *error
)
150 struct kvm_sev_cmd input
;
152 memset(&input
, 0x0, sizeof(input
));
156 input
.data
= (__u64
)(unsigned long)data
;
158 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, &input
);
161 *error
= input
.error
;
168 sev_platform_ioctl(int fd
, int cmd
, void *data
, int *error
)
171 struct sev_issue_cmd arg
;
174 arg
.data
= (unsigned long)data
;
175 r
= ioctl(fd
, SEV_ISSUE_CMD
, &arg
);
184 fw_error_to_str(int code
)
186 if (code
< 0 || code
>= SEV_FW_MAX_ERROR
) {
187 return "unknown error";
190 return sev_fw_errlist
[code
];
194 sev_check_state(const SevGuestState
*sev
, SevState state
)
197 return sev
->state
== state
? true : false;
201 sev_set_guest_state(SevGuestState
*sev
, SevState new_state
)
203 assert(new_state
< SEV_STATE__MAX
);
206 trace_kvm_sev_change_state(SevState_str(sev
->state
),
207 SevState_str(new_state
));
208 sev
->state
= new_state
;
212 sev_ram_block_added(RAMBlockNotifier
*n
, void *host
, size_t size
,
216 struct kvm_enc_region range
;
221 * The RAM device presents a memory region that should be treated
222 * as IO region and should not be pinned.
224 mr
= memory_region_from_host(host
, &offset
);
225 if (mr
&& memory_region_is_ram_device(mr
)) {
229 range
.addr
= (__u64
)(unsigned long)host
;
230 range
.size
= max_size
;
232 trace_kvm_memcrypt_register_region(host
, max_size
);
233 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_REG_REGION
, &range
);
235 error_report("%s: failed to register region (%p+%#zx) error '%s'",
236 __func__
, host
, max_size
, strerror(errno
));
242 sev_ram_block_removed(RAMBlockNotifier
*n
, void *host
, size_t size
,
246 struct kvm_enc_region range
;
251 * The RAM device presents a memory region that should be treated
252 * as IO region and should not have been pinned.
254 mr
= memory_region_from_host(host
, &offset
);
255 if (mr
&& memory_region_is_ram_device(mr
)) {
259 range
.addr
= (__u64
)(unsigned long)host
;
260 range
.size
= max_size
;
262 trace_kvm_memcrypt_unregister_region(host
, max_size
);
263 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_UNREG_REGION
, &range
);
265 error_report("%s: failed to unregister region (%p+%#zx)",
266 __func__
, host
, max_size
);
270 static struct RAMBlockNotifier sev_ram_notifier
= {
271 .ram_block_added
= sev_ram_block_added
,
272 .ram_block_removed
= sev_ram_block_removed
,
276 sev_guest_finalize(Object
*obj
)
281 sev_guest_get_session_file(Object
*obj
, Error
**errp
)
283 SevGuestState
*s
= SEV_GUEST(obj
);
285 return s
->session_file
? g_strdup(s
->session_file
) : NULL
;
289 sev_guest_set_session_file(Object
*obj
, const char *value
, Error
**errp
)
291 SevGuestState
*s
= SEV_GUEST(obj
);
293 s
->session_file
= g_strdup(value
);
297 sev_guest_get_dh_cert_file(Object
*obj
, Error
**errp
)
299 SevGuestState
*s
= SEV_GUEST(obj
);
301 return g_strdup(s
->dh_cert_file
);
305 sev_guest_set_dh_cert_file(Object
*obj
, const char *value
, Error
**errp
)
307 SevGuestState
*s
= SEV_GUEST(obj
);
309 s
->dh_cert_file
= g_strdup(value
);
313 sev_guest_get_sev_device(Object
*obj
, Error
**errp
)
315 SevGuestState
*sev
= SEV_GUEST(obj
);
317 return g_strdup(sev
->sev_device
);
321 sev_guest_set_sev_device(Object
*obj
, const char *value
, Error
**errp
)
323 SevGuestState
*sev
= SEV_GUEST(obj
);
325 sev
->sev_device
= g_strdup(value
);
329 sev_guest_class_init(ObjectClass
*oc
, void *data
)
331 object_class_property_add_str(oc
, "sev-device",
332 sev_guest_get_sev_device
,
333 sev_guest_set_sev_device
);
334 object_class_property_set_description(oc
, "sev-device",
335 "SEV device to use");
336 object_class_property_add_str(oc
, "dh-cert-file",
337 sev_guest_get_dh_cert_file
,
338 sev_guest_set_dh_cert_file
);
339 object_class_property_set_description(oc
, "dh-cert-file",
340 "guest owners DH certificate (encoded with base64)");
341 object_class_property_add_str(oc
, "session-file",
342 sev_guest_get_session_file
,
343 sev_guest_set_session_file
);
344 object_class_property_set_description(oc
, "session-file",
345 "guest owners session parameters (encoded with base64)");
349 sev_guest_instance_init(Object
*obj
)
351 SevGuestState
*sev
= SEV_GUEST(obj
);
353 sev
->sev_device
= g_strdup(DEFAULT_SEV_DEVICE
);
354 sev
->policy
= DEFAULT_GUEST_POLICY
;
355 object_property_add_uint32_ptr(obj
, "policy", &sev
->policy
,
356 OBJ_PROP_FLAG_READWRITE
);
357 object_property_add_uint32_ptr(obj
, "handle", &sev
->handle
,
358 OBJ_PROP_FLAG_READWRITE
);
359 object_property_add_uint32_ptr(obj
, "cbitpos", &sev
->cbitpos
,
360 OBJ_PROP_FLAG_READWRITE
);
361 object_property_add_uint32_ptr(obj
, "reduced-phys-bits",
362 &sev
->reduced_phys_bits
,
363 OBJ_PROP_FLAG_READWRITE
);
367 static const TypeInfo sev_guest_info
= {
368 .parent
= TYPE_CONFIDENTIAL_GUEST_SUPPORT
,
369 .name
= TYPE_SEV_GUEST
,
370 .instance_size
= sizeof(SevGuestState
),
371 .instance_finalize
= sev_guest_finalize
,
372 .class_init
= sev_guest_class_init
,
373 .instance_init
= sev_guest_instance_init
,
374 .interfaces
= (InterfaceInfo
[]) {
375 { TYPE_USER_CREATABLE
},
389 return sev_enabled() && (sev_guest
->policy
& SEV_POLICY_ES
);
393 sev_get_me_mask(void)
395 return sev_guest
? sev_guest
->me_mask
: ~0;
399 sev_get_cbit_position(void)
401 return sev_guest
? sev_guest
->cbitpos
: 0;
405 sev_get_reduced_phys_bits(void)
407 return sev_guest
? sev_guest
->reduced_phys_bits
: 0;
415 info
= g_new0(SevInfo
, 1);
416 info
->enabled
= sev_enabled();
419 info
->api_major
= sev_guest
->api_major
;
420 info
->api_minor
= sev_guest
->api_minor
;
421 info
->build_id
= sev_guest
->build_id
;
422 info
->policy
= sev_guest
->policy
;
423 info
->state
= sev_guest
->state
;
424 info
->handle
= sev_guest
->handle
;
431 sev_get_pdh_info(int fd
, guchar
**pdh
, size_t *pdh_len
, guchar
**cert_chain
,
432 size_t *cert_chain_len
, Error
**errp
)
434 guchar
*pdh_data
= NULL
;
435 guchar
*cert_chain_data
= NULL
;
436 struct sev_user_data_pdh_cert_export export
= {};
439 /* query the certificate length */
440 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
442 if (err
!= SEV_RET_INVALID_LEN
) {
443 error_setg(errp
, "failed to export PDH cert ret=%d fw_err=%d (%s)",
444 r
, err
, fw_error_to_str(err
));
449 pdh_data
= g_new(guchar
, export
.pdh_cert_len
);
450 cert_chain_data
= g_new(guchar
, export
.cert_chain_len
);
451 export
.pdh_cert_address
= (unsigned long)pdh_data
;
452 export
.cert_chain_address
= (unsigned long)cert_chain_data
;
454 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
456 error_setg(errp
, "failed to export PDH cert ret=%d fw_err=%d (%s)",
457 r
, err
, fw_error_to_str(err
));
462 *pdh_len
= export
.pdh_cert_len
;
463 *cert_chain
= cert_chain_data
;
464 *cert_chain_len
= export
.cert_chain_len
;
469 g_free(cert_chain_data
);
474 sev_get_capabilities(Error
**errp
)
476 SevCapability
*cap
= NULL
;
477 guchar
*pdh_data
= NULL
;
478 guchar
*cert_chain_data
= NULL
;
479 size_t pdh_len
= 0, cert_chain_len
= 0;
483 if (!kvm_enabled()) {
484 error_setg(errp
, "KVM not enabled");
487 if (kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, NULL
) < 0) {
488 error_setg(errp
, "SEV is not enabled in KVM");
492 fd
= open(DEFAULT_SEV_DEVICE
, O_RDWR
);
494 error_setg_errno(errp
, errno
, "Failed to open %s",
499 if (sev_get_pdh_info(fd
, &pdh_data
, &pdh_len
,
500 &cert_chain_data
, &cert_chain_len
, errp
)) {
504 cap
= g_new0(SevCapability
, 1);
505 cap
->pdh
= g_base64_encode(pdh_data
, pdh_len
);
506 cap
->cert_chain
= g_base64_encode(cert_chain_data
, cert_chain_len
);
508 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
509 cap
->cbitpos
= ebx
& 0x3f;
512 * When SEV feature is enabled, we loose one bit in guest physical
515 cap
->reduced_phys_bits
= 1;
519 g_free(cert_chain_data
);
524 SevAttestationReport
*
525 sev_get_attestation_report(const char *mnonce
, Error
**errp
)
527 struct kvm_sev_attestation_report input
= {};
528 SevAttestationReport
*report
= NULL
;
529 SevGuestState
*sev
= sev_guest
;
535 if (!sev_enabled()) {
536 error_setg(errp
, "SEV is not enabled");
540 /* lets decode the mnonce string */
541 buf
= g_base64_decode(mnonce
, &len
);
543 error_setg(errp
, "SEV: failed to decode mnonce input");
547 /* verify the input mnonce length */
548 if (len
!= sizeof(input
.mnonce
)) {
549 error_setg(errp
, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT
")",
550 sizeof(input
.mnonce
), len
);
555 /* Query the report length */
556 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
559 if (err
!= SEV_RET_INVALID_LEN
) {
560 error_setg(errp
, "failed to query the attestation report length "
561 "ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
567 data
= g_malloc(input
.len
);
568 input
.uaddr
= (unsigned long)data
;
569 memcpy(input
.mnonce
, buf
, sizeof(input
.mnonce
));
571 /* Query the report */
572 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
575 error_setg_errno(errp
, errno
, "Failed to get attestation report"
576 " ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
580 report
= g_new0(SevAttestationReport
, 1);
581 report
->data
= g_base64_encode(data
, input
.len
);
583 trace_kvm_sev_attestation_report(mnonce
, report
->data
);
592 sev_read_file_base64(const char *filename
, guchar
**data
, gsize
*len
)
595 g_autofree gchar
*base64
= NULL
;
596 GError
*error
= NULL
;
598 if (!g_file_get_contents(filename
, &base64
, &sz
, &error
)) {
599 error_report("failed to read '%s' (%s)", filename
, error
->message
);
604 *data
= g_base64_decode(base64
, len
);
609 sev_launch_start(SevGuestState
*sev
)
614 struct kvm_sev_launch_start
*start
;
615 guchar
*session
= NULL
, *dh_cert
= NULL
;
617 start
= g_new0(struct kvm_sev_launch_start
, 1);
619 start
->handle
= sev
->handle
;
620 start
->policy
= sev
->policy
;
621 if (sev
->session_file
) {
622 if (sev_read_file_base64(sev
->session_file
, &session
, &sz
) < 0) {
625 start
->session_uaddr
= (unsigned long)session
;
626 start
->session_len
= sz
;
629 if (sev
->dh_cert_file
) {
630 if (sev_read_file_base64(sev
->dh_cert_file
, &dh_cert
, &sz
) < 0) {
633 start
->dh_uaddr
= (unsigned long)dh_cert
;
637 trace_kvm_sev_launch_start(start
->policy
, session
, dh_cert
);
638 rc
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_START
, start
, &fw_error
);
640 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
641 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
645 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_UPDATE
);
646 sev
->handle
= start
->handle
;
657 sev_launch_update_data(SevGuestState
*sev
, uint8_t *addr
, uint64_t len
)
660 struct kvm_sev_launch_update_data update
;
666 update
.uaddr
= (__u64
)(unsigned long)addr
;
668 trace_kvm_sev_launch_update_data(addr
, len
);
669 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_DATA
,
672 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
673 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
680 sev_launch_update_vmsa(SevGuestState
*sev
)
684 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_VMSA
, NULL
, &fw_error
);
686 error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
687 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
694 sev_launch_get_measure(Notifier
*notifier
, void *unused
)
696 SevGuestState
*sev
= sev_guest
;
699 struct kvm_sev_launch_measure
*measurement
;
701 if (!sev_check_state(sev
, SEV_STATE_LAUNCH_UPDATE
)) {
705 if (sev_es_enabled()) {
706 /* measure all the VM save areas before getting launch_measure */
707 ret
= sev_launch_update_vmsa(sev
);
713 measurement
= g_new0(struct kvm_sev_launch_measure
, 1);
715 /* query the measurement blob length */
716 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
717 measurement
, &error
);
718 if (!measurement
->len
) {
719 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
720 __func__
, ret
, error
, fw_error_to_str(errno
));
721 goto free_measurement
;
724 data
= g_new0(guchar
, measurement
->len
);
725 measurement
->uaddr
= (unsigned long)data
;
727 /* get the measurement blob */
728 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
729 measurement
, &error
);
731 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
732 __func__
, ret
, error
, fw_error_to_str(errno
));
736 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_SECRET
);
738 /* encode the measurement value and emit the event */
739 sev
->measurement
= g_base64_encode(data
, measurement
->len
);
740 trace_kvm_sev_launch_measurement(sev
->measurement
);
749 sev_get_launch_measurement(void)
752 sev_guest
->state
>= SEV_STATE_LAUNCH_SECRET
) {
753 return g_strdup(sev_guest
->measurement
);
759 static Notifier sev_machine_done_notify
= {
760 .notify
= sev_launch_get_measure
,
764 sev_launch_finish(SevGuestState
*sev
)
768 trace_kvm_sev_launch_finish();
769 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_FINISH
, 0, &error
);
771 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
772 __func__
, ret
, error
, fw_error_to_str(error
));
776 sev_set_guest_state(sev
, SEV_STATE_RUNNING
);
778 /* add migration blocker */
779 error_setg(&sev_mig_blocker
,
780 "SEV: Migration is not implemented");
781 migrate_add_blocker(sev_mig_blocker
, &error_fatal
);
785 sev_vm_state_change(void *opaque
, bool running
, RunState state
)
787 SevGuestState
*sev
= opaque
;
790 if (!sev_check_state(sev
, SEV_STATE_RUNNING
)) {
791 sev_launch_finish(sev
);
796 int sev_kvm_init(ConfidentialGuestSupport
*cgs
, Error
**errp
)
799 = (SevGuestState
*)object_dynamic_cast(OBJECT(cgs
), TYPE_SEV_GUEST
);
801 int ret
, fw_error
, cmd
;
803 uint32_t host_cbitpos
;
804 struct sev_user_data_status status
= {};
810 ret
= ram_block_discard_disable(true);
812 error_report("%s: cannot disable RAM discard", __func__
);
817 sev
->state
= SEV_STATE_UNINIT
;
819 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
820 host_cbitpos
= ebx
& 0x3f;
822 if (host_cbitpos
!= sev
->cbitpos
) {
823 error_setg(errp
, "%s: cbitpos check failed, host '%d' requested '%d'",
824 __func__
, host_cbitpos
, sev
->cbitpos
);
828 if (sev
->reduced_phys_bits
< 1) {
829 error_setg(errp
, "%s: reduced_phys_bits check failed, it should be >=1,"
830 " requested '%d'", __func__
, sev
->reduced_phys_bits
);
834 sev
->me_mask
= ~(1UL << sev
->cbitpos
);
836 devname
= object_property_get_str(OBJECT(sev
), "sev-device", NULL
);
837 sev
->sev_fd
= open(devname
, O_RDWR
);
838 if (sev
->sev_fd
< 0) {
839 error_setg(errp
, "%s: Failed to open %s '%s'", __func__
,
840 devname
, strerror(errno
));
846 ret
= sev_platform_ioctl(sev
->sev_fd
, SEV_PLATFORM_STATUS
, &status
,
849 error_setg(errp
, "%s: failed to get platform status ret=%d "
850 "fw_error='%d: %s'", __func__
, ret
, fw_error
,
851 fw_error_to_str(fw_error
));
854 sev
->build_id
= status
.build
;
855 sev
->api_major
= status
.api_major
;
856 sev
->api_minor
= status
.api_minor
;
858 if (sev_es_enabled()) {
859 if (!kvm_kernel_irqchip_allowed()) {
860 error_report("%s: SEV-ES guests require in-kernel irqchip support",
865 if (!(status
.flags
& SEV_STATUS_FLAGS_CONFIG_ES
)) {
866 error_report("%s: guest policy requires SEV-ES, but "
867 "host SEV-ES support unavailable",
871 cmd
= KVM_SEV_ES_INIT
;
876 trace_kvm_sev_init();
877 ret
= sev_ioctl(sev
->sev_fd
, cmd
, NULL
, &fw_error
);
879 error_setg(errp
, "%s: failed to initialize ret=%d fw_error=%d '%s'",
880 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
884 ret
= sev_launch_start(sev
);
886 error_setg(errp
, "%s: failed to create encryption context", __func__
);
890 ram_block_notifier_add(&sev_ram_notifier
);
891 qemu_add_machine_init_done_notifier(&sev_machine_done_notify
);
892 qemu_add_vm_change_state_handler(sev_vm_state_change
, sev
);
899 ram_block_discard_disable(false);
904 sev_encrypt_flash(uint8_t *ptr
, uint64_t len
, Error
**errp
)
910 /* if SEV is in update state then encrypt the data else do nothing */
911 if (sev_check_state(sev_guest
, SEV_STATE_LAUNCH_UPDATE
)) {
912 int ret
= sev_launch_update_data(sev_guest
, ptr
, len
);
914 error_setg(errp
, "failed to encrypt pflash rom");
922 int sev_inject_launch_secret(const char *packet_hdr
, const char *secret
,
923 uint64_t gpa
, Error
**errp
)
925 struct kvm_sev_launch_secret input
;
926 g_autofree guchar
*data
= NULL
, *hdr
= NULL
;
929 gsize hdr_sz
= 0, data_sz
= 0;
930 MemoryRegion
*mr
= NULL
;
933 error_setg(errp
, "SEV: SEV not enabled.");
937 /* secret can be injected only in this state */
938 if (!sev_check_state(sev_guest
, SEV_STATE_LAUNCH_SECRET
)) {
939 error_setg(errp
, "SEV: Not in correct state. (LSECRET) %x",
944 hdr
= g_base64_decode(packet_hdr
, &hdr_sz
);
945 if (!hdr
|| !hdr_sz
) {
946 error_setg(errp
, "SEV: Failed to decode sequence header");
950 data
= g_base64_decode(secret
, &data_sz
);
951 if (!data
|| !data_sz
) {
952 error_setg(errp
, "SEV: Failed to decode data");
956 hva
= gpa2hva(&mr
, gpa
, data_sz
, errp
);
958 error_prepend(errp
, "SEV: Failed to calculate guest address: ");
962 input
.hdr_uaddr
= (uint64_t)(unsigned long)hdr
;
963 input
.hdr_len
= hdr_sz
;
965 input
.trans_uaddr
= (uint64_t)(unsigned long)data
;
966 input
.trans_len
= data_sz
;
968 input
.guest_uaddr
= (uint64_t)(unsigned long)hva
;
969 input
.guest_len
= data_sz
;
971 trace_kvm_sev_launch_secret(gpa
, input
.guest_uaddr
,
972 input
.trans_uaddr
, input
.trans_len
);
974 ret
= sev_ioctl(sev_guest
->sev_fd
, KVM_SEV_LAUNCH_SECRET
,
977 error_setg(errp
, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
978 ret
, error
, fw_error_to_str(error
));
986 sev_es_parse_reset_block(SevInfoBlock
*info
, uint32_t *addr
)
988 if (!info
->reset_addr
) {
989 error_report("SEV-ES reset address is zero");
993 *addr
= info
->reset_addr
;
999 sev_es_find_reset_vector(void *flash_ptr
, uint64_t flash_size
,
1002 QemuUUID info_guid
, *guid
;
1008 * Initialize the address to zero. An address of zero with a successful
1009 * return code indicates that SEV-ES is not active.
1014 * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
1015 * The SEV GUID is located on its own (original implementation) or within
1016 * the Firmware GUID Table (new implementation), either of which are
1017 * located 32 bytes from the end of the flash.
1019 * Check the Firmware GUID Table first.
1021 if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID
, &data
, NULL
)) {
1022 return sev_es_parse_reset_block((SevInfoBlock
*)data
, addr
);
1026 * SEV info block not found in the Firmware GUID Table (or there isn't
1027 * a Firmware GUID Table), fall back to the original implementation.
1029 data
= flash_ptr
+ flash_size
- 0x20;
1031 qemu_uuid_parse(SEV_INFO_BLOCK_GUID
, &info_guid
);
1032 info_guid
= qemu_uuid_bswap(info_guid
); /* GUIDs are LE */
1034 guid
= (QemuUUID
*)(data
- sizeof(info_guid
));
1035 if (!qemu_uuid_is_equal(guid
, &info_guid
)) {
1036 error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
1040 len
= (uint16_t *)((uint8_t *)guid
- sizeof(*len
));
1041 info
= (SevInfoBlock
*)(data
- le16_to_cpu(*len
));
1043 return sev_es_parse_reset_block(info
, addr
);
1046 void sev_es_set_reset_vector(CPUState
*cpu
)
1051 /* Only update if we have valid reset information */
1052 if (!sev_guest
|| !sev_guest
->reset_data_valid
) {
1056 /* Do not update the BSP reset state */
1057 if (cpu
->cpu_index
== 0) {
1064 cpu_x86_load_seg_cache(env
, R_CS
, 0xf000, sev_guest
->reset_cs
, 0xffff,
1065 DESC_P_MASK
| DESC_S_MASK
| DESC_CS_MASK
|
1066 DESC_R_MASK
| DESC_A_MASK
);
1068 env
->eip
= sev_guest
->reset_ip
;
1071 int sev_es_save_reset_vector(void *flash_ptr
, uint64_t flash_size
)
1077 if (!sev_es_enabled()) {
1082 ret
= sev_es_find_reset_vector(flash_ptr
, flash_size
,
1089 sev_guest
->reset_cs
= addr
& 0xffff0000;
1090 sev_guest
->reset_ip
= addr
& 0x0000ffff;
1091 sev_guest
->reset_data_valid
= true;
1094 sev_es_set_reset_vector(cpu
);
1101 static const QemuUUID sev_hash_table_header_guid
= {
1102 .data
= UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
1103 0xd4, 0x11, 0xfd, 0x21)
1106 static const QemuUUID sev_kernel_entry_guid
= {
1107 .data
= UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
1108 0x72, 0xd2, 0x04, 0x5b)
1110 static const QemuUUID sev_initrd_entry_guid
= {
1111 .data
= UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
1112 0x91, 0x69, 0x78, 0x1d)
1114 static const QemuUUID sev_cmdline_entry_guid
= {
1115 .data
= UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
1116 0x4d, 0x36, 0xab, 0x2a)
1120 * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
1121 * which is included in SEV's initial memory measurement.
1123 bool sev_add_kernel_loader_hashes(SevKernelLoaderContext
*ctx
, Error
**errp
)
1126 SevHashTableDescriptor
*area
;
1128 uint8_t cmdline_hash
[HASH_SIZE
];
1129 uint8_t initrd_hash
[HASH_SIZE
];
1130 uint8_t kernel_hash
[HASH_SIZE
];
1132 size_t hash_len
= HASH_SIZE
;
1135 if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID
, &data
, NULL
)) {
1136 error_setg(errp
, "SEV: kernel specified but OVMF has no hash table guid");
1139 area
= (SevHashTableDescriptor
*)data
;
1142 * Calculate hash of kernel command-line with the terminating null byte. If
1143 * the user doesn't supply a command-line via -append, the 1-byte "\0" will
1146 hashp
= cmdline_hash
;
1147 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->cmdline_data
,
1148 ctx
->cmdline_size
, &hashp
, &hash_len
, errp
) < 0) {
1151 assert(hash_len
== HASH_SIZE
);
1154 * Calculate hash of initrd. If the user doesn't supply an initrd via
1155 * -initrd, an empty buffer will be used (ctx->initrd_size == 0).
1157 hashp
= initrd_hash
;
1158 if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256
, ctx
->initrd_data
,
1159 ctx
->initrd_size
, &hashp
, &hash_len
, errp
) < 0) {
1162 assert(hash_len
== HASH_SIZE
);
1164 /* Calculate hash of the kernel */
1165 hashp
= kernel_hash
;
1166 struct iovec iov
[2] = {
1167 { .iov_base
= ctx
->setup_data
, .iov_len
= ctx
->setup_size
},
1168 { .iov_base
= ctx
->kernel_data
, .iov_len
= ctx
->kernel_size
}
1170 if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256
, iov
, ARRAY_SIZE(iov
),
1171 &hashp
, &hash_len
, errp
) < 0) {
1174 assert(hash_len
== HASH_SIZE
);
1177 * Populate the hashes table in the guest's memory at the OVMF-designated
1178 * area for the SEV hashes table
1180 ht
= qemu_map_ram_ptr(NULL
, area
->base
);
1182 ht
->guid
= sev_hash_table_header_guid
;
1183 ht
->len
= sizeof(*ht
);
1185 ht
->cmdline
.guid
= sev_cmdline_entry_guid
;
1186 ht
->cmdline
.len
= sizeof(ht
->cmdline
);
1187 memcpy(ht
->cmdline
.hash
, cmdline_hash
, sizeof(ht
->cmdline
.hash
));
1189 ht
->initrd
.guid
= sev_initrd_entry_guid
;
1190 ht
->initrd
.len
= sizeof(ht
->initrd
);
1191 memcpy(ht
->initrd
.hash
, initrd_hash
, sizeof(ht
->initrd
.hash
));
1193 ht
->kernel
.guid
= sev_kernel_entry_guid
;
1194 ht
->kernel
.len
= sizeof(ht
->kernel
);
1195 memcpy(ht
->kernel
.hash
, kernel_hash
, sizeof(ht
->kernel
.hash
));
1197 /* When calling sev_encrypt_flash, the length has to be 16 byte aligned */
1198 aligned_len
= ROUND_UP(ht
->len
, 16);
1199 if (aligned_len
!= ht
->len
) {
1200 /* zero the excess data so the measurement can be reliably calculated */
1201 memset(ht
->padding
, 0, aligned_len
- ht
->len
);
1204 if (sev_encrypt_flash((uint8_t *)ht
, aligned_len
, errp
) < 0) {
1212 sev_register_types(void)
1214 type_register_static(&sev_guest_info
);
1217 type_init(sev_register_types
);