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 "sysemu/kvm.h"
28 #include "sysemu/sysemu.h"
29 #include "sysemu/runstate.h"
31 #include "migration/blocker.h"
32 #include "qom/object.h"
33 #include "monitor/monitor.h"
34 #include "exec/confidential-guest-support.h"
35 #include "hw/i386/pc.h"
37 #define TYPE_SEV_GUEST "sev-guest"
38 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState
, SEV_GUEST
)
44 * The SevGuestState object is used for creating and managing a SEV
48 * -object sev-guest,id=sev0 \
49 * -machine ...,memory-encryption=sev0
51 struct SevGuestState
{
52 ConfidentialGuestSupport parent_obj
;
54 /* configuration parameters */
60 uint32_t reduced_phys_bits
;
74 bool reset_data_valid
;
77 #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
78 #define DEFAULT_SEV_DEVICE "/dev/sev"
80 #define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
81 typedef struct __attribute__((__packed__
)) SevInfoBlock
{
82 /* SEV-ES Reset Vector Address */
86 static SevGuestState
*sev_guest
;
87 static Error
*sev_mig_blocker
;
89 static const char *const sev_fw_errlist
[] = {
90 [SEV_RET_SUCCESS
] = "",
91 [SEV_RET_INVALID_PLATFORM_STATE
] = "Platform state is invalid",
92 [SEV_RET_INVALID_GUEST_STATE
] = "Guest state is invalid",
93 [SEV_RET_INAVLID_CONFIG
] = "Platform configuration is invalid",
94 [SEV_RET_INVALID_LEN
] = "Buffer too small",
95 [SEV_RET_ALREADY_OWNED
] = "Platform is already owned",
96 [SEV_RET_INVALID_CERTIFICATE
] = "Certificate is invalid",
97 [SEV_RET_POLICY_FAILURE
] = "Policy is not allowed",
98 [SEV_RET_INACTIVE
] = "Guest is not active",
99 [SEV_RET_INVALID_ADDRESS
] = "Invalid address",
100 [SEV_RET_BAD_SIGNATURE
] = "Bad signature",
101 [SEV_RET_BAD_MEASUREMENT
] = "Bad measurement",
102 [SEV_RET_ASID_OWNED
] = "ASID is already owned",
103 [SEV_RET_INVALID_ASID
] = "Invalid ASID",
104 [SEV_RET_WBINVD_REQUIRED
] = "WBINVD is required",
105 [SEV_RET_DFFLUSH_REQUIRED
] = "DF_FLUSH is required",
106 [SEV_RET_INVALID_GUEST
] = "Guest handle is invalid",
107 [SEV_RET_INVALID_COMMAND
] = "Invalid command",
108 [SEV_RET_ACTIVE
] = "Guest is active",
109 [SEV_RET_HWSEV_RET_PLATFORM
] = "Hardware error",
110 [SEV_RET_HWSEV_RET_UNSAFE
] = "Hardware unsafe",
111 [SEV_RET_UNSUPPORTED
] = "Feature not supported",
112 [SEV_RET_INVALID_PARAM
] = "Invalid parameter",
113 [SEV_RET_RESOURCE_LIMIT
] = "Required firmware resource depleted",
114 [SEV_RET_SECURE_DATA_INVALID
] = "Part-specific integrity check failure",
117 #define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
120 sev_ioctl(int fd
, int cmd
, void *data
, int *error
)
123 struct kvm_sev_cmd input
;
125 memset(&input
, 0x0, sizeof(input
));
129 input
.data
= (__u64
)(unsigned long)data
;
131 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, &input
);
134 *error
= input
.error
;
141 sev_platform_ioctl(int fd
, int cmd
, void *data
, int *error
)
144 struct sev_issue_cmd arg
;
147 arg
.data
= (unsigned long)data
;
148 r
= ioctl(fd
, SEV_ISSUE_CMD
, &arg
);
157 fw_error_to_str(int code
)
159 if (code
< 0 || code
>= SEV_FW_MAX_ERROR
) {
160 return "unknown error";
163 return sev_fw_errlist
[code
];
167 sev_check_state(const SevGuestState
*sev
, SevState state
)
170 return sev
->state
== state
? true : false;
174 sev_set_guest_state(SevGuestState
*sev
, SevState new_state
)
176 assert(new_state
< SEV_STATE__MAX
);
179 trace_kvm_sev_change_state(SevState_str(sev
->state
),
180 SevState_str(new_state
));
181 sev
->state
= new_state
;
185 sev_ram_block_added(RAMBlockNotifier
*n
, void *host
, size_t size
,
189 struct kvm_enc_region range
;
194 * The RAM device presents a memory region that should be treated
195 * as IO region and should not be pinned.
197 mr
= memory_region_from_host(host
, &offset
);
198 if (mr
&& memory_region_is_ram_device(mr
)) {
202 range
.addr
= (__u64
)(unsigned long)host
;
203 range
.size
= max_size
;
205 trace_kvm_memcrypt_register_region(host
, max_size
);
206 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_REG_REGION
, &range
);
208 error_report("%s: failed to register region (%p+%#zx) error '%s'",
209 __func__
, host
, max_size
, strerror(errno
));
215 sev_ram_block_removed(RAMBlockNotifier
*n
, void *host
, size_t size
,
219 struct kvm_enc_region range
;
224 * The RAM device presents a memory region that should be treated
225 * as IO region and should not have been pinned.
227 mr
= memory_region_from_host(host
, &offset
);
228 if (mr
&& memory_region_is_ram_device(mr
)) {
232 range
.addr
= (__u64
)(unsigned long)host
;
233 range
.size
= max_size
;
235 trace_kvm_memcrypt_unregister_region(host
, max_size
);
236 r
= kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_UNREG_REGION
, &range
);
238 error_report("%s: failed to unregister region (%p+%#zx)",
239 __func__
, host
, max_size
);
243 static struct RAMBlockNotifier sev_ram_notifier
= {
244 .ram_block_added
= sev_ram_block_added
,
245 .ram_block_removed
= sev_ram_block_removed
,
249 sev_guest_finalize(Object
*obj
)
254 sev_guest_get_session_file(Object
*obj
, Error
**errp
)
256 SevGuestState
*s
= SEV_GUEST(obj
);
258 return s
->session_file
? g_strdup(s
->session_file
) : NULL
;
262 sev_guest_set_session_file(Object
*obj
, const char *value
, Error
**errp
)
264 SevGuestState
*s
= SEV_GUEST(obj
);
266 s
->session_file
= g_strdup(value
);
270 sev_guest_get_dh_cert_file(Object
*obj
, Error
**errp
)
272 SevGuestState
*s
= SEV_GUEST(obj
);
274 return g_strdup(s
->dh_cert_file
);
278 sev_guest_set_dh_cert_file(Object
*obj
, const char *value
, Error
**errp
)
280 SevGuestState
*s
= SEV_GUEST(obj
);
282 s
->dh_cert_file
= g_strdup(value
);
286 sev_guest_get_sev_device(Object
*obj
, Error
**errp
)
288 SevGuestState
*sev
= SEV_GUEST(obj
);
290 return g_strdup(sev
->sev_device
);
294 sev_guest_set_sev_device(Object
*obj
, const char *value
, Error
**errp
)
296 SevGuestState
*sev
= SEV_GUEST(obj
);
298 sev
->sev_device
= g_strdup(value
);
302 sev_guest_class_init(ObjectClass
*oc
, void *data
)
304 object_class_property_add_str(oc
, "sev-device",
305 sev_guest_get_sev_device
,
306 sev_guest_set_sev_device
);
307 object_class_property_set_description(oc
, "sev-device",
308 "SEV device to use");
309 object_class_property_add_str(oc
, "dh-cert-file",
310 sev_guest_get_dh_cert_file
,
311 sev_guest_set_dh_cert_file
);
312 object_class_property_set_description(oc
, "dh-cert-file",
313 "guest owners DH certificate (encoded with base64)");
314 object_class_property_add_str(oc
, "session-file",
315 sev_guest_get_session_file
,
316 sev_guest_set_session_file
);
317 object_class_property_set_description(oc
, "session-file",
318 "guest owners session parameters (encoded with base64)");
322 sev_guest_instance_init(Object
*obj
)
324 SevGuestState
*sev
= SEV_GUEST(obj
);
326 sev
->sev_device
= g_strdup(DEFAULT_SEV_DEVICE
);
327 sev
->policy
= DEFAULT_GUEST_POLICY
;
328 object_property_add_uint32_ptr(obj
, "policy", &sev
->policy
,
329 OBJ_PROP_FLAG_READWRITE
);
330 object_property_add_uint32_ptr(obj
, "handle", &sev
->handle
,
331 OBJ_PROP_FLAG_READWRITE
);
332 object_property_add_uint32_ptr(obj
, "cbitpos", &sev
->cbitpos
,
333 OBJ_PROP_FLAG_READWRITE
);
334 object_property_add_uint32_ptr(obj
, "reduced-phys-bits",
335 &sev
->reduced_phys_bits
,
336 OBJ_PROP_FLAG_READWRITE
);
340 static const TypeInfo sev_guest_info
= {
341 .parent
= TYPE_CONFIDENTIAL_GUEST_SUPPORT
,
342 .name
= TYPE_SEV_GUEST
,
343 .instance_size
= sizeof(SevGuestState
),
344 .instance_finalize
= sev_guest_finalize
,
345 .class_init
= sev_guest_class_init
,
346 .instance_init
= sev_guest_instance_init
,
347 .interfaces
= (InterfaceInfo
[]) {
348 { TYPE_USER_CREATABLE
},
362 return sev_enabled() && (sev_guest
->policy
& SEV_POLICY_ES
);
366 sev_get_me_mask(void)
368 return sev_guest
? sev_guest
->me_mask
: ~0;
372 sev_get_cbit_position(void)
374 return sev_guest
? sev_guest
->cbitpos
: 0;
378 sev_get_reduced_phys_bits(void)
380 return sev_guest
? sev_guest
->reduced_phys_bits
: 0;
388 info
= g_new0(SevInfo
, 1);
389 info
->enabled
= sev_enabled();
392 info
->api_major
= sev_guest
->api_major
;
393 info
->api_minor
= sev_guest
->api_minor
;
394 info
->build_id
= sev_guest
->build_id
;
395 info
->policy
= sev_guest
->policy
;
396 info
->state
= sev_guest
->state
;
397 info
->handle
= sev_guest
->handle
;
404 sev_get_pdh_info(int fd
, guchar
**pdh
, size_t *pdh_len
, guchar
**cert_chain
,
405 size_t *cert_chain_len
, Error
**errp
)
407 guchar
*pdh_data
= NULL
;
408 guchar
*cert_chain_data
= NULL
;
409 struct sev_user_data_pdh_cert_export export
= {};
412 /* query the certificate length */
413 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
415 if (err
!= SEV_RET_INVALID_LEN
) {
416 error_setg(errp
, "failed to export PDH cert ret=%d fw_err=%d (%s)",
417 r
, err
, fw_error_to_str(err
));
422 pdh_data
= g_new(guchar
, export
.pdh_cert_len
);
423 cert_chain_data
= g_new(guchar
, export
.cert_chain_len
);
424 export
.pdh_cert_address
= (unsigned long)pdh_data
;
425 export
.cert_chain_address
= (unsigned long)cert_chain_data
;
427 r
= sev_platform_ioctl(fd
, SEV_PDH_CERT_EXPORT
, &export
, &err
);
429 error_setg(errp
, "failed to export PDH cert ret=%d fw_err=%d (%s)",
430 r
, err
, fw_error_to_str(err
));
435 *pdh_len
= export
.pdh_cert_len
;
436 *cert_chain
= cert_chain_data
;
437 *cert_chain_len
= export
.cert_chain_len
;
442 g_free(cert_chain_data
);
447 sev_get_capabilities(Error
**errp
)
449 SevCapability
*cap
= NULL
;
450 guchar
*pdh_data
= NULL
;
451 guchar
*cert_chain_data
= NULL
;
452 size_t pdh_len
= 0, cert_chain_len
= 0;
456 if (!kvm_enabled()) {
457 error_setg(errp
, "KVM not enabled");
460 if (kvm_vm_ioctl(kvm_state
, KVM_MEMORY_ENCRYPT_OP
, NULL
) < 0) {
461 error_setg(errp
, "SEV is not enabled in KVM");
465 fd
= open(DEFAULT_SEV_DEVICE
, O_RDWR
);
467 error_setg_errno(errp
, errno
, "Failed to open %s",
472 if (sev_get_pdh_info(fd
, &pdh_data
, &pdh_len
,
473 &cert_chain_data
, &cert_chain_len
, errp
)) {
477 cap
= g_new0(SevCapability
, 1);
478 cap
->pdh
= g_base64_encode(pdh_data
, pdh_len
);
479 cap
->cert_chain
= g_base64_encode(cert_chain_data
, cert_chain_len
);
481 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
482 cap
->cbitpos
= ebx
& 0x3f;
485 * When SEV feature is enabled, we loose one bit in guest physical
488 cap
->reduced_phys_bits
= 1;
492 g_free(cert_chain_data
);
497 SevAttestationReport
*
498 sev_get_attestation_report(const char *mnonce
, Error
**errp
)
500 struct kvm_sev_attestation_report input
= {};
501 SevAttestationReport
*report
= NULL
;
502 SevGuestState
*sev
= sev_guest
;
508 if (!sev_enabled()) {
509 error_setg(errp
, "SEV is not enabled");
513 /* lets decode the mnonce string */
514 buf
= g_base64_decode(mnonce
, &len
);
516 error_setg(errp
, "SEV: failed to decode mnonce input");
520 /* verify the input mnonce length */
521 if (len
!= sizeof(input
.mnonce
)) {
522 error_setg(errp
, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT
")",
523 sizeof(input
.mnonce
), len
);
528 /* Query the report length */
529 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
532 if (err
!= SEV_RET_INVALID_LEN
) {
533 error_setg(errp
, "failed to query the attestation report length "
534 "ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
540 data
= g_malloc(input
.len
);
541 input
.uaddr
= (unsigned long)data
;
542 memcpy(input
.mnonce
, buf
, sizeof(input
.mnonce
));
544 /* Query the report */
545 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_GET_ATTESTATION_REPORT
,
548 error_setg_errno(errp
, errno
, "Failed to get attestation report"
549 " ret=%d fw_err=%d (%s)", ret
, err
, fw_error_to_str(err
));
553 report
= g_new0(SevAttestationReport
, 1);
554 report
->data
= g_base64_encode(data
, input
.len
);
556 trace_kvm_sev_attestation_report(mnonce
, report
->data
);
565 sev_read_file_base64(const char *filename
, guchar
**data
, gsize
*len
)
569 GError
*error
= NULL
;
571 if (!g_file_get_contents(filename
, &base64
, &sz
, &error
)) {
572 error_report("failed to read '%s' (%s)", filename
, error
->message
);
577 *data
= g_base64_decode(base64
, len
);
582 sev_launch_start(SevGuestState
*sev
)
587 struct kvm_sev_launch_start
*start
;
588 guchar
*session
= NULL
, *dh_cert
= NULL
;
590 start
= g_new0(struct kvm_sev_launch_start
, 1);
592 start
->handle
= sev
->handle
;
593 start
->policy
= sev
->policy
;
594 if (sev
->session_file
) {
595 if (sev_read_file_base64(sev
->session_file
, &session
, &sz
) < 0) {
598 start
->session_uaddr
= (unsigned long)session
;
599 start
->session_len
= sz
;
602 if (sev
->dh_cert_file
) {
603 if (sev_read_file_base64(sev
->dh_cert_file
, &dh_cert
, &sz
) < 0) {
606 start
->dh_uaddr
= (unsigned long)dh_cert
;
610 trace_kvm_sev_launch_start(start
->policy
, session
, dh_cert
);
611 rc
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_START
, start
, &fw_error
);
613 error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
614 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
618 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_UPDATE
);
619 sev
->handle
= start
->handle
;
630 sev_launch_update_data(SevGuestState
*sev
, uint8_t *addr
, uint64_t len
)
633 struct kvm_sev_launch_update_data update
;
639 update
.uaddr
= (__u64
)(unsigned long)addr
;
641 trace_kvm_sev_launch_update_data(addr
, len
);
642 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_DATA
,
645 error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
646 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
653 sev_launch_update_vmsa(SevGuestState
*sev
)
657 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_UPDATE_VMSA
, NULL
, &fw_error
);
659 error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
660 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
667 sev_launch_get_measure(Notifier
*notifier
, void *unused
)
669 SevGuestState
*sev
= sev_guest
;
672 struct kvm_sev_launch_measure
*measurement
;
674 if (!sev_check_state(sev
, SEV_STATE_LAUNCH_UPDATE
)) {
678 if (sev_es_enabled()) {
679 /* measure all the VM save areas before getting launch_measure */
680 ret
= sev_launch_update_vmsa(sev
);
686 measurement
= g_new0(struct kvm_sev_launch_measure
, 1);
688 /* query the measurement blob length */
689 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
690 measurement
, &error
);
691 if (!measurement
->len
) {
692 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
693 __func__
, ret
, error
, fw_error_to_str(errno
));
694 goto free_measurement
;
697 data
= g_new0(guchar
, measurement
->len
);
698 measurement
->uaddr
= (unsigned long)data
;
700 /* get the measurement blob */
701 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_MEASURE
,
702 measurement
, &error
);
704 error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
705 __func__
, ret
, error
, fw_error_to_str(errno
));
709 sev_set_guest_state(sev
, SEV_STATE_LAUNCH_SECRET
);
711 /* encode the measurement value and emit the event */
712 sev
->measurement
= g_base64_encode(data
, measurement
->len
);
713 trace_kvm_sev_launch_measurement(sev
->measurement
);
722 sev_get_launch_measurement(void)
725 sev_guest
->state
>= SEV_STATE_LAUNCH_SECRET
) {
726 return g_strdup(sev_guest
->measurement
);
732 static Notifier sev_machine_done_notify
= {
733 .notify
= sev_launch_get_measure
,
737 sev_launch_finish(SevGuestState
*sev
)
740 Error
*local_err
= NULL
;
742 trace_kvm_sev_launch_finish();
743 ret
= sev_ioctl(sev
->sev_fd
, KVM_SEV_LAUNCH_FINISH
, 0, &error
);
745 error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
746 __func__
, ret
, error
, fw_error_to_str(error
));
750 sev_set_guest_state(sev
, SEV_STATE_RUNNING
);
752 /* add migration blocker */
753 error_setg(&sev_mig_blocker
,
754 "SEV: Migration is not implemented");
755 ret
= migrate_add_blocker(sev_mig_blocker
, &local_err
);
757 error_report_err(local_err
);
758 error_free(sev_mig_blocker
);
764 sev_vm_state_change(void *opaque
, bool running
, RunState state
)
766 SevGuestState
*sev
= opaque
;
769 if (!sev_check_state(sev
, SEV_STATE_RUNNING
)) {
770 sev_launch_finish(sev
);
775 int sev_kvm_init(ConfidentialGuestSupport
*cgs
, Error
**errp
)
778 = (SevGuestState
*)object_dynamic_cast(OBJECT(cgs
), TYPE_SEV_GUEST
);
780 int ret
, fw_error
, cmd
;
782 uint32_t host_cbitpos
;
783 struct sev_user_data_status status
= {};
789 ret
= ram_block_discard_disable(true);
791 error_report("%s: cannot disable RAM discard", __func__
);
796 sev
->state
= SEV_STATE_UNINIT
;
798 host_cpuid(0x8000001F, 0, NULL
, &ebx
, NULL
, NULL
);
799 host_cbitpos
= ebx
& 0x3f;
801 if (host_cbitpos
!= sev
->cbitpos
) {
802 error_setg(errp
, "%s: cbitpos check failed, host '%d' requested '%d'",
803 __func__
, host_cbitpos
, sev
->cbitpos
);
807 if (sev
->reduced_phys_bits
< 1) {
808 error_setg(errp
, "%s: reduced_phys_bits check failed, it should be >=1,"
809 " requested '%d'", __func__
, sev
->reduced_phys_bits
);
813 sev
->me_mask
= ~(1UL << sev
->cbitpos
);
815 devname
= object_property_get_str(OBJECT(sev
), "sev-device", NULL
);
816 sev
->sev_fd
= open(devname
, O_RDWR
);
817 if (sev
->sev_fd
< 0) {
818 error_setg(errp
, "%s: Failed to open %s '%s'", __func__
,
819 devname
, strerror(errno
));
825 ret
= sev_platform_ioctl(sev
->sev_fd
, SEV_PLATFORM_STATUS
, &status
,
828 error_setg(errp
, "%s: failed to get platform status ret=%d "
829 "fw_error='%d: %s'", __func__
, ret
, fw_error
,
830 fw_error_to_str(fw_error
));
833 sev
->build_id
= status
.build
;
834 sev
->api_major
= status
.api_major
;
835 sev
->api_minor
= status
.api_minor
;
837 if (sev_es_enabled()) {
838 if (!kvm_kernel_irqchip_allowed()) {
839 error_report("%s: SEV-ES guests require in-kernel irqchip support",
844 if (!(status
.flags
& SEV_STATUS_FLAGS_CONFIG_ES
)) {
845 error_report("%s: guest policy requires SEV-ES, but "
846 "host SEV-ES support unavailable",
850 cmd
= KVM_SEV_ES_INIT
;
855 trace_kvm_sev_init();
856 ret
= sev_ioctl(sev
->sev_fd
, cmd
, NULL
, &fw_error
);
858 error_setg(errp
, "%s: failed to initialize ret=%d fw_error=%d '%s'",
859 __func__
, ret
, fw_error
, fw_error_to_str(fw_error
));
863 ret
= sev_launch_start(sev
);
865 error_setg(errp
, "%s: failed to create encryption context", __func__
);
869 ram_block_notifier_add(&sev_ram_notifier
);
870 qemu_add_machine_init_done_notifier(&sev_machine_done_notify
);
871 qemu_add_vm_change_state_handler(sev_vm_state_change
, sev
);
878 ram_block_discard_disable(false);
883 sev_encrypt_flash(uint8_t *ptr
, uint64_t len
, Error
**errp
)
889 /* if SEV is in update state then encrypt the data else do nothing */
890 if (sev_check_state(sev_guest
, SEV_STATE_LAUNCH_UPDATE
)) {
891 int ret
= sev_launch_update_data(sev_guest
, ptr
, len
);
893 error_setg(errp
, "failed to encrypt pflash rom");
901 int sev_inject_launch_secret(const char *packet_hdr
, const char *secret
,
902 uint64_t gpa
, Error
**errp
)
904 struct kvm_sev_launch_secret input
;
905 g_autofree guchar
*data
= NULL
, *hdr
= NULL
;
908 gsize hdr_sz
= 0, data_sz
= 0;
909 MemoryRegion
*mr
= NULL
;
912 error_setg(errp
, "SEV: SEV not enabled.");
916 /* secret can be injected only in this state */
917 if (!sev_check_state(sev_guest
, SEV_STATE_LAUNCH_SECRET
)) {
918 error_setg(errp
, "SEV: Not in correct state. (LSECRET) %x",
923 hdr
= g_base64_decode(packet_hdr
, &hdr_sz
);
924 if (!hdr
|| !hdr_sz
) {
925 error_setg(errp
, "SEV: Failed to decode sequence header");
929 data
= g_base64_decode(secret
, &data_sz
);
930 if (!data
|| !data_sz
) {
931 error_setg(errp
, "SEV: Failed to decode data");
935 hva
= gpa2hva(&mr
, gpa
, data_sz
, errp
);
937 error_prepend(errp
, "SEV: Failed to calculate guest address: ");
941 input
.hdr_uaddr
= (uint64_t)(unsigned long)hdr
;
942 input
.hdr_len
= hdr_sz
;
944 input
.trans_uaddr
= (uint64_t)(unsigned long)data
;
945 input
.trans_len
= data_sz
;
947 input
.guest_uaddr
= (uint64_t)(unsigned long)hva
;
948 input
.guest_len
= data_sz
;
950 trace_kvm_sev_launch_secret(gpa
, input
.guest_uaddr
,
951 input
.trans_uaddr
, input
.trans_len
);
953 ret
= sev_ioctl(sev_guest
->sev_fd
, KVM_SEV_LAUNCH_SECRET
,
956 error_setg(errp
, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
957 ret
, error
, fw_error_to_str(error
));
965 sev_es_parse_reset_block(SevInfoBlock
*info
, uint32_t *addr
)
967 if (!info
->reset_addr
) {
968 error_report("SEV-ES reset address is zero");
972 *addr
= info
->reset_addr
;
978 sev_es_find_reset_vector(void *flash_ptr
, uint64_t flash_size
,
981 QemuUUID info_guid
, *guid
;
987 * Initialize the address to zero. An address of zero with a successful
988 * return code indicates that SEV-ES is not active.
993 * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
994 * The SEV GUID is located on its own (original implementation) or within
995 * the Firmware GUID Table (new implementation), either of which are
996 * located 32 bytes from the end of the flash.
998 * Check the Firmware GUID Table first.
1000 if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID
, &data
, NULL
)) {
1001 return sev_es_parse_reset_block((SevInfoBlock
*)data
, addr
);
1005 * SEV info block not found in the Firmware GUID Table (or there isn't
1006 * a Firmware GUID Table), fall back to the original implementation.
1008 data
= flash_ptr
+ flash_size
- 0x20;
1010 qemu_uuid_parse(SEV_INFO_BLOCK_GUID
, &info_guid
);
1011 info_guid
= qemu_uuid_bswap(info_guid
); /* GUIDs are LE */
1013 guid
= (QemuUUID
*)(data
- sizeof(info_guid
));
1014 if (!qemu_uuid_is_equal(guid
, &info_guid
)) {
1015 error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
1019 len
= (uint16_t *)((uint8_t *)guid
- sizeof(*len
));
1020 info
= (SevInfoBlock
*)(data
- le16_to_cpu(*len
));
1022 return sev_es_parse_reset_block(info
, addr
);
1025 void sev_es_set_reset_vector(CPUState
*cpu
)
1030 /* Only update if we have valid reset information */
1031 if (!sev_guest
|| !sev_guest
->reset_data_valid
) {
1035 /* Do not update the BSP reset state */
1036 if (cpu
->cpu_index
== 0) {
1043 cpu_x86_load_seg_cache(env
, R_CS
, 0xf000, sev_guest
->reset_cs
, 0xffff,
1044 DESC_P_MASK
| DESC_S_MASK
| DESC_CS_MASK
|
1045 DESC_R_MASK
| DESC_A_MASK
);
1047 env
->eip
= sev_guest
->reset_ip
;
1050 int sev_es_save_reset_vector(void *flash_ptr
, uint64_t flash_size
)
1056 if (!sev_es_enabled()) {
1061 ret
= sev_es_find_reset_vector(flash_ptr
, flash_size
,
1068 sev_guest
->reset_cs
= addr
& 0xffff0000;
1069 sev_guest
->reset_ip
= addr
& 0x0000ffff;
1070 sev_guest
->reset_data_valid
= true;
1073 sev_es_set_reset_vector(cpu
);
1081 sev_register_types(void)
1083 type_register_static(&sev_guest_info
);
1086 type_init(sev_register_types
);