xref: /openbmc/qemu/target/i386/sev.c (revision d177892d)
1 /*
2  * QEMU SEV support
3  *
4  * Copyright Advanced Micro Devices 2016-2018
5  *
6  * Author:
7  *      Brijesh Singh <brijesh.singh@amd.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13 
14 #include "qemu/osdep.h"
15 
16 #include <linux/kvm.h>
17 #include <linux/psp-sev.h>
18 
19 #include <sys/ioctl.h>
20 
21 #include "qapi/error.h"
22 #include "qom/object_interfaces.h"
23 #include "qemu/base64.h"
24 #include "qemu/module.h"
25 #include "qemu/uuid.h"
26 #include "sysemu/kvm.h"
27 #include "sev_i386.h"
28 #include "sysemu/sysemu.h"
29 #include "sysemu/runstate.h"
30 #include "trace.h"
31 #include "migration/blocker.h"
32 #include "qom/object.h"
33 #include "exec/address-spaces.h"
34 #include "monitor/monitor.h"
35 #include "exec/confidential-guest-support.h"
36 #include "hw/i386/pc.h"
37 
38 #define TYPE_SEV_GUEST "sev-guest"
39 OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST)
40 
41 
42 /**
43  * SevGuestState:
44  *
45  * The SevGuestState object is used for creating and managing a SEV
46  * guest.
47  *
48  * # $QEMU \
49  *         -object sev-guest,id=sev0 \
50  *         -machine ...,memory-encryption=sev0
51  */
52 struct SevGuestState {
53     ConfidentialGuestSupport parent_obj;
54 
55     /* configuration parameters */
56     char *sev_device;
57     uint32_t policy;
58     char *dh_cert_file;
59     char *session_file;
60     uint32_t cbitpos;
61     uint32_t reduced_phys_bits;
62 
63     /* runtime state */
64     uint32_t handle;
65     uint8_t api_major;
66     uint8_t api_minor;
67     uint8_t build_id;
68     uint64_t me_mask;
69     int sev_fd;
70     SevState state;
71     gchar *measurement;
72 
73     uint32_t reset_cs;
74     uint32_t reset_ip;
75     bool reset_data_valid;
76 };
77 
78 #define DEFAULT_GUEST_POLICY    0x1 /* disable debug */
79 #define DEFAULT_SEV_DEVICE      "/dev/sev"
80 
81 #define SEV_INFO_BLOCK_GUID     "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
82 typedef struct __attribute__((__packed__)) SevInfoBlock {
83     /* SEV-ES Reset Vector Address */
84     uint32_t reset_addr;
85 } SevInfoBlock;
86 
87 static SevGuestState *sev_guest;
88 static Error *sev_mig_blocker;
89 
90 static const char *const sev_fw_errlist[] = {
91     "",
92     "Platform state is invalid",
93     "Guest state is invalid",
94     "Platform configuration is invalid",
95     "Buffer too small",
96     "Platform is already owned",
97     "Certificate is invalid",
98     "Policy is not allowed",
99     "Guest is not active",
100     "Invalid address",
101     "Bad signature",
102     "Bad measurement",
103     "Asid is already owned",
104     "Invalid ASID",
105     "WBINVD is required",
106     "DF_FLUSH is required",
107     "Guest handle is invalid",
108     "Invalid command",
109     "Guest is active",
110     "Hardware error",
111     "Hardware unsafe",
112     "Feature not supported",
113     "Invalid parameter"
114 };
115 
116 #define SEV_FW_MAX_ERROR      ARRAY_SIZE(sev_fw_errlist)
117 
118 static int
119 sev_ioctl(int fd, int cmd, void *data, int *error)
120 {
121     int r;
122     struct kvm_sev_cmd input;
123 
124     memset(&input, 0x0, sizeof(input));
125 
126     input.id = cmd;
127     input.sev_fd = fd;
128     input.data = (__u64)(unsigned long)data;
129 
130     r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
131 
132     if (error) {
133         *error = input.error;
134     }
135 
136     return r;
137 }
138 
139 static int
140 sev_platform_ioctl(int fd, int cmd, void *data, int *error)
141 {
142     int r;
143     struct sev_issue_cmd arg;
144 
145     arg.cmd = cmd;
146     arg.data = (unsigned long)data;
147     r = ioctl(fd, SEV_ISSUE_CMD, &arg);
148     if (error) {
149         *error = arg.error;
150     }
151 
152     return r;
153 }
154 
155 static const char *
156 fw_error_to_str(int code)
157 {
158     if (code < 0 || code >= SEV_FW_MAX_ERROR) {
159         return "unknown error";
160     }
161 
162     return sev_fw_errlist[code];
163 }
164 
165 static bool
166 sev_check_state(const SevGuestState *sev, SevState state)
167 {
168     assert(sev);
169     return sev->state == state ? true : false;
170 }
171 
172 static void
173 sev_set_guest_state(SevGuestState *sev, SevState new_state)
174 {
175     assert(new_state < SEV_STATE__MAX);
176     assert(sev);
177 
178     trace_kvm_sev_change_state(SevState_str(sev->state),
179                                SevState_str(new_state));
180     sev->state = new_state;
181 }
182 
183 static void
184 sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
185 {
186     int r;
187     struct kvm_enc_region range;
188     ram_addr_t offset;
189     MemoryRegion *mr;
190 
191     /*
192      * The RAM device presents a memory region that should be treated
193      * as IO region and should not be pinned.
194      */
195     mr = memory_region_from_host(host, &offset);
196     if (mr && memory_region_is_ram_device(mr)) {
197         return;
198     }
199 
200     range.addr = (__u64)(unsigned long)host;
201     range.size = size;
202 
203     trace_kvm_memcrypt_register_region(host, size);
204     r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
205     if (r) {
206         error_report("%s: failed to register region (%p+%#zx) error '%s'",
207                      __func__, host, size, strerror(errno));
208         exit(1);
209     }
210 }
211 
212 static void
213 sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
214 {
215     int r;
216     struct kvm_enc_region range;
217     ram_addr_t offset;
218     MemoryRegion *mr;
219 
220     /*
221      * The RAM device presents a memory region that should be treated
222      * as IO region and should not have been pinned.
223      */
224     mr = memory_region_from_host(host, &offset);
225     if (mr && memory_region_is_ram_device(mr)) {
226         return;
227     }
228 
229     range.addr = (__u64)(unsigned long)host;
230     range.size = size;
231 
232     trace_kvm_memcrypt_unregister_region(host, size);
233     r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
234     if (r) {
235         error_report("%s: failed to unregister region (%p+%#zx)",
236                      __func__, host, size);
237     }
238 }
239 
240 static struct RAMBlockNotifier sev_ram_notifier = {
241     .ram_block_added = sev_ram_block_added,
242     .ram_block_removed = sev_ram_block_removed,
243 };
244 
245 static void
246 sev_guest_finalize(Object *obj)
247 {
248 }
249 
250 static char *
251 sev_guest_get_session_file(Object *obj, Error **errp)
252 {
253     SevGuestState *s = SEV_GUEST(obj);
254 
255     return s->session_file ? g_strdup(s->session_file) : NULL;
256 }
257 
258 static void
259 sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
260 {
261     SevGuestState *s = SEV_GUEST(obj);
262 
263     s->session_file = g_strdup(value);
264 }
265 
266 static char *
267 sev_guest_get_dh_cert_file(Object *obj, Error **errp)
268 {
269     SevGuestState *s = SEV_GUEST(obj);
270 
271     return g_strdup(s->dh_cert_file);
272 }
273 
274 static void
275 sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
276 {
277     SevGuestState *s = SEV_GUEST(obj);
278 
279     s->dh_cert_file = g_strdup(value);
280 }
281 
282 static char *
283 sev_guest_get_sev_device(Object *obj, Error **errp)
284 {
285     SevGuestState *sev = SEV_GUEST(obj);
286 
287     return g_strdup(sev->sev_device);
288 }
289 
290 static void
291 sev_guest_set_sev_device(Object *obj, const char *value, Error **errp)
292 {
293     SevGuestState *sev = SEV_GUEST(obj);
294 
295     sev->sev_device = g_strdup(value);
296 }
297 
298 static void
299 sev_guest_class_init(ObjectClass *oc, void *data)
300 {
301     object_class_property_add_str(oc, "sev-device",
302                                   sev_guest_get_sev_device,
303                                   sev_guest_set_sev_device);
304     object_class_property_set_description(oc, "sev-device",
305             "SEV device to use");
306     object_class_property_add_str(oc, "dh-cert-file",
307                                   sev_guest_get_dh_cert_file,
308                                   sev_guest_set_dh_cert_file);
309     object_class_property_set_description(oc, "dh-cert-file",
310             "guest owners DH certificate (encoded with base64)");
311     object_class_property_add_str(oc, "session-file",
312                                   sev_guest_get_session_file,
313                                   sev_guest_set_session_file);
314     object_class_property_set_description(oc, "session-file",
315             "guest owners session parameters (encoded with base64)");
316 }
317 
318 static void
319 sev_guest_instance_init(Object *obj)
320 {
321     SevGuestState *sev = SEV_GUEST(obj);
322 
323     sev->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
324     sev->policy = DEFAULT_GUEST_POLICY;
325     object_property_add_uint32_ptr(obj, "policy", &sev->policy,
326                                    OBJ_PROP_FLAG_READWRITE);
327     object_property_add_uint32_ptr(obj, "handle", &sev->handle,
328                                    OBJ_PROP_FLAG_READWRITE);
329     object_property_add_uint32_ptr(obj, "cbitpos", &sev->cbitpos,
330                                    OBJ_PROP_FLAG_READWRITE);
331     object_property_add_uint32_ptr(obj, "reduced-phys-bits",
332                                    &sev->reduced_phys_bits,
333                                    OBJ_PROP_FLAG_READWRITE);
334 }
335 
336 /* sev guest info */
337 static const TypeInfo sev_guest_info = {
338     .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT,
339     .name = TYPE_SEV_GUEST,
340     .instance_size = sizeof(SevGuestState),
341     .instance_finalize = sev_guest_finalize,
342     .class_init = sev_guest_class_init,
343     .instance_init = sev_guest_instance_init,
344     .interfaces = (InterfaceInfo[]) {
345         { TYPE_USER_CREATABLE },
346         { }
347     }
348 };
349 
350 bool
351 sev_enabled(void)
352 {
353     return !!sev_guest;
354 }
355 
356 bool
357 sev_es_enabled(void)
358 {
359     return sev_enabled() && (sev_guest->policy & SEV_POLICY_ES);
360 }
361 
362 uint64_t
363 sev_get_me_mask(void)
364 {
365     return sev_guest ? sev_guest->me_mask : ~0;
366 }
367 
368 uint32_t
369 sev_get_cbit_position(void)
370 {
371     return sev_guest ? sev_guest->cbitpos : 0;
372 }
373 
374 uint32_t
375 sev_get_reduced_phys_bits(void)
376 {
377     return sev_guest ? sev_guest->reduced_phys_bits : 0;
378 }
379 
380 SevInfo *
381 sev_get_info(void)
382 {
383     SevInfo *info;
384 
385     info = g_new0(SevInfo, 1);
386     info->enabled = sev_enabled();
387 
388     if (info->enabled) {
389         info->api_major = sev_guest->api_major;
390         info->api_minor = sev_guest->api_minor;
391         info->build_id = sev_guest->build_id;
392         info->policy = sev_guest->policy;
393         info->state = sev_guest->state;
394         info->handle = sev_guest->handle;
395     }
396 
397     return info;
398 }
399 
400 static int
401 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
402                  size_t *cert_chain_len, Error **errp)
403 {
404     guchar *pdh_data = NULL;
405     guchar *cert_chain_data = NULL;
406     struct sev_user_data_pdh_cert_export export = {};
407     int err, r;
408 
409     /* query the certificate length */
410     r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
411     if (r < 0) {
412         if (err != SEV_RET_INVALID_LEN) {
413             error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
414                        r, err, fw_error_to_str(err));
415             return 1;
416         }
417     }
418 
419     pdh_data = g_new(guchar, export.pdh_cert_len);
420     cert_chain_data = g_new(guchar, export.cert_chain_len);
421     export.pdh_cert_address = (unsigned long)pdh_data;
422     export.cert_chain_address = (unsigned long)cert_chain_data;
423 
424     r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
425     if (r < 0) {
426         error_setg(errp, "failed to export PDH cert ret=%d fw_err=%d (%s)",
427                    r, err, fw_error_to_str(err));
428         goto e_free;
429     }
430 
431     *pdh = pdh_data;
432     *pdh_len = export.pdh_cert_len;
433     *cert_chain = cert_chain_data;
434     *cert_chain_len = export.cert_chain_len;
435     return 0;
436 
437 e_free:
438     g_free(pdh_data);
439     g_free(cert_chain_data);
440     return 1;
441 }
442 
443 SevCapability *
444 sev_get_capabilities(Error **errp)
445 {
446     SevCapability *cap = NULL;
447     guchar *pdh_data = NULL;
448     guchar *cert_chain_data = NULL;
449     size_t pdh_len = 0, cert_chain_len = 0;
450     uint32_t ebx;
451     int fd;
452 
453     if (!kvm_enabled()) {
454         error_setg(errp, "KVM not enabled");
455         return NULL;
456     }
457     if (kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, NULL) < 0) {
458         error_setg(errp, "SEV is not enabled in KVM");
459         return NULL;
460     }
461 
462     fd = open(DEFAULT_SEV_DEVICE, O_RDWR);
463     if (fd < 0) {
464         error_setg_errno(errp, errno, "Failed to open %s",
465                          DEFAULT_SEV_DEVICE);
466         return NULL;
467     }
468 
469     if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
470                          &cert_chain_data, &cert_chain_len, errp)) {
471         goto out;
472     }
473 
474     cap = g_new0(SevCapability, 1);
475     cap->pdh = g_base64_encode(pdh_data, pdh_len);
476     cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len);
477 
478     host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
479     cap->cbitpos = ebx & 0x3f;
480 
481     /*
482      * When SEV feature is enabled, we loose one bit in guest physical
483      * addressing.
484      */
485     cap->reduced_phys_bits = 1;
486 
487 out:
488     g_free(pdh_data);
489     g_free(cert_chain_data);
490     close(fd);
491     return cap;
492 }
493 
494 static int
495 sev_read_file_base64(const char *filename, guchar **data, gsize *len)
496 {
497     gsize sz;
498     gchar *base64;
499     GError *error = NULL;
500 
501     if (!g_file_get_contents(filename, &base64, &sz, &error)) {
502         error_report("failed to read '%s' (%s)", filename, error->message);
503         g_error_free(error);
504         return -1;
505     }
506 
507     *data = g_base64_decode(base64, len);
508     return 0;
509 }
510 
511 static int
512 sev_launch_start(SevGuestState *sev)
513 {
514     gsize sz;
515     int ret = 1;
516     int fw_error, rc;
517     struct kvm_sev_launch_start *start;
518     guchar *session = NULL, *dh_cert = NULL;
519 
520     start = g_new0(struct kvm_sev_launch_start, 1);
521 
522     start->handle = sev->handle;
523     start->policy = sev->policy;
524     if (sev->session_file) {
525         if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) {
526             goto out;
527         }
528         start->session_uaddr = (unsigned long)session;
529         start->session_len = sz;
530     }
531 
532     if (sev->dh_cert_file) {
533         if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) {
534             goto out;
535         }
536         start->dh_uaddr = (unsigned long)dh_cert;
537         start->dh_len = sz;
538     }
539 
540     trace_kvm_sev_launch_start(start->policy, session, dh_cert);
541     rc = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error);
542     if (rc < 0) {
543         error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
544                 __func__, ret, fw_error, fw_error_to_str(fw_error));
545         goto out;
546     }
547 
548     sev_set_guest_state(sev, SEV_STATE_LAUNCH_UPDATE);
549     sev->handle = start->handle;
550     ret = 0;
551 
552 out:
553     g_free(start);
554     g_free(session);
555     g_free(dh_cert);
556     return ret;
557 }
558 
559 static int
560 sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len)
561 {
562     int ret, fw_error;
563     struct kvm_sev_launch_update_data update;
564 
565     if (!addr || !len) {
566         return 1;
567     }
568 
569     update.uaddr = (__u64)(unsigned long)addr;
570     update.len = len;
571     trace_kvm_sev_launch_update_data(addr, len);
572     ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
573                     &update, &fw_error);
574     if (ret) {
575         error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
576                 __func__, ret, fw_error, fw_error_to_str(fw_error));
577     }
578 
579     return ret;
580 }
581 
582 static int
583 sev_launch_update_vmsa(SevGuestState *sev)
584 {
585     int ret, fw_error;
586 
587     ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL, &fw_error);
588     if (ret) {
589         error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
590                 __func__, ret, fw_error, fw_error_to_str(fw_error));
591     }
592 
593     return ret;
594 }
595 
596 static void
597 sev_launch_get_measure(Notifier *notifier, void *unused)
598 {
599     SevGuestState *sev = sev_guest;
600     int ret, error;
601     guchar *data;
602     struct kvm_sev_launch_measure *measurement;
603 
604     if (!sev_check_state(sev, SEV_STATE_LAUNCH_UPDATE)) {
605         return;
606     }
607 
608     if (sev_es_enabled()) {
609         /* measure all the VM save areas before getting launch_measure */
610         ret = sev_launch_update_vmsa(sev);
611         if (ret) {
612             exit(1);
613         }
614     }
615 
616     measurement = g_new0(struct kvm_sev_launch_measure, 1);
617 
618     /* query the measurement blob length */
619     ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE,
620                     measurement, &error);
621     if (!measurement->len) {
622         error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
623                      __func__, ret, error, fw_error_to_str(errno));
624         goto free_measurement;
625     }
626 
627     data = g_new0(guchar, measurement->len);
628     measurement->uaddr = (unsigned long)data;
629 
630     /* get the measurement blob */
631     ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_MEASURE,
632                     measurement, &error);
633     if (ret) {
634         error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
635                      __func__, ret, error, fw_error_to_str(errno));
636         goto free_data;
637     }
638 
639     sev_set_guest_state(sev, SEV_STATE_LAUNCH_SECRET);
640 
641     /* encode the measurement value and emit the event */
642     sev->measurement = g_base64_encode(data, measurement->len);
643     trace_kvm_sev_launch_measurement(sev->measurement);
644 
645 free_data:
646     g_free(data);
647 free_measurement:
648     g_free(measurement);
649 }
650 
651 char *
652 sev_get_launch_measurement(void)
653 {
654     if (sev_guest &&
655         sev_guest->state >= SEV_STATE_LAUNCH_SECRET) {
656         return g_strdup(sev_guest->measurement);
657     }
658 
659     return NULL;
660 }
661 
662 static Notifier sev_machine_done_notify = {
663     .notify = sev_launch_get_measure,
664 };
665 
666 static void
667 sev_launch_finish(SevGuestState *sev)
668 {
669     int ret, error;
670     Error *local_err = NULL;
671 
672     trace_kvm_sev_launch_finish();
673     ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_FINISH, 0, &error);
674     if (ret) {
675         error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
676                      __func__, ret, error, fw_error_to_str(error));
677         exit(1);
678     }
679 
680     sev_set_guest_state(sev, SEV_STATE_RUNNING);
681 
682     /* add migration blocker */
683     error_setg(&sev_mig_blocker,
684                "SEV: Migration is not implemented");
685     ret = migrate_add_blocker(sev_mig_blocker, &local_err);
686     if (local_err) {
687         error_report_err(local_err);
688         error_free(sev_mig_blocker);
689         exit(1);
690     }
691 }
692 
693 static void
694 sev_vm_state_change(void *opaque, bool running, RunState state)
695 {
696     SevGuestState *sev = opaque;
697 
698     if (running) {
699         if (!sev_check_state(sev, SEV_STATE_RUNNING)) {
700             sev_launch_finish(sev);
701         }
702     }
703 }
704 
705 int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
706 {
707     SevGuestState *sev
708         = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
709     char *devname;
710     int ret, fw_error, cmd;
711     uint32_t ebx;
712     uint32_t host_cbitpos;
713     struct sev_user_data_status status = {};
714 
715     if (!sev) {
716         return 0;
717     }
718 
719     ret = ram_block_discard_disable(true);
720     if (ret) {
721         error_report("%s: cannot disable RAM discard", __func__);
722         return -1;
723     }
724 
725     sev_guest = sev;
726     sev->state = SEV_STATE_UNINIT;
727 
728     host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
729     host_cbitpos = ebx & 0x3f;
730 
731     if (host_cbitpos != sev->cbitpos) {
732         error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
733                    __func__, host_cbitpos, sev->cbitpos);
734         goto err;
735     }
736 
737     if (sev->reduced_phys_bits < 1) {
738         error_setg(errp, "%s: reduced_phys_bits check failed, it should be >=1,"
739                    " requested '%d'", __func__, sev->reduced_phys_bits);
740         goto err;
741     }
742 
743     sev->me_mask = ~(1UL << sev->cbitpos);
744 
745     devname = object_property_get_str(OBJECT(sev), "sev-device", NULL);
746     sev->sev_fd = open(devname, O_RDWR);
747     if (sev->sev_fd < 0) {
748         error_setg(errp, "%s: Failed to open %s '%s'", __func__,
749                    devname, strerror(errno));
750         g_free(devname);
751         goto err;
752     }
753     g_free(devname);
754 
755     ret = sev_platform_ioctl(sev->sev_fd, SEV_PLATFORM_STATUS, &status,
756                              &fw_error);
757     if (ret) {
758         error_setg(errp, "%s: failed to get platform status ret=%d "
759                    "fw_error='%d: %s'", __func__, ret, fw_error,
760                    fw_error_to_str(fw_error));
761         goto err;
762     }
763     sev->build_id = status.build;
764     sev->api_major = status.api_major;
765     sev->api_minor = status.api_minor;
766 
767     if (sev_es_enabled()) {
768         if (!kvm_kernel_irqchip_allowed()) {
769             error_report("%s: SEV-ES guests require in-kernel irqchip support",
770                          __func__);
771             goto err;
772         }
773 
774         if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
775             error_report("%s: guest policy requires SEV-ES, but "
776                          "host SEV-ES support unavailable",
777                          __func__);
778             goto err;
779         }
780         cmd = KVM_SEV_ES_INIT;
781     } else {
782         cmd = KVM_SEV_INIT;
783     }
784 
785     trace_kvm_sev_init();
786     ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error);
787     if (ret) {
788         error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
789                    __func__, ret, fw_error, fw_error_to_str(fw_error));
790         goto err;
791     }
792 
793     ret = sev_launch_start(sev);
794     if (ret) {
795         error_setg(errp, "%s: failed to create encryption context", __func__);
796         goto err;
797     }
798 
799     ram_block_notifier_add(&sev_ram_notifier);
800     qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
801     qemu_add_vm_change_state_handler(sev_vm_state_change, sev);
802 
803     cgs->ready = true;
804 
805     return 0;
806 err:
807     sev_guest = NULL;
808     ram_block_discard_disable(false);
809     return -1;
810 }
811 
812 int
813 sev_encrypt_flash(uint8_t *ptr, uint64_t len, Error **errp)
814 {
815     if (!sev_guest) {
816         return 0;
817     }
818 
819     /* if SEV is in update state then encrypt the data else do nothing */
820     if (sev_check_state(sev_guest, SEV_STATE_LAUNCH_UPDATE)) {
821         int ret = sev_launch_update_data(sev_guest, ptr, len);
822         if (ret < 0) {
823             error_setg(errp, "failed to encrypt pflash rom");
824             return ret;
825         }
826     }
827 
828     return 0;
829 }
830 
831 int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
832                              uint64_t gpa, Error **errp)
833 {
834     struct kvm_sev_launch_secret input;
835     g_autofree guchar *data = NULL, *hdr = NULL;
836     int error, ret = 1;
837     void *hva;
838     gsize hdr_sz = 0, data_sz = 0;
839     MemoryRegion *mr = NULL;
840 
841     if (!sev_guest) {
842         error_setg(errp, "SEV: SEV not enabled.");
843         return 1;
844     }
845 
846     /* secret can be injected only in this state */
847     if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) {
848         error_setg(errp, "SEV: Not in correct state. (LSECRET) %x",
849                      sev_guest->state);
850         return 1;
851     }
852 
853     hdr = g_base64_decode(packet_hdr, &hdr_sz);
854     if (!hdr || !hdr_sz) {
855         error_setg(errp, "SEV: Failed to decode sequence header");
856         return 1;
857     }
858 
859     data = g_base64_decode(secret, &data_sz);
860     if (!data || !data_sz) {
861         error_setg(errp, "SEV: Failed to decode data");
862         return 1;
863     }
864 
865     hva = gpa2hva(&mr, gpa, data_sz, errp);
866     if (!hva) {
867         error_prepend(errp, "SEV: Failed to calculate guest address: ");
868         return 1;
869     }
870 
871     input.hdr_uaddr = (uint64_t)(unsigned long)hdr;
872     input.hdr_len = hdr_sz;
873 
874     input.trans_uaddr = (uint64_t)(unsigned long)data;
875     input.trans_len = data_sz;
876 
877     input.guest_uaddr = (uint64_t)(unsigned long)hva;
878     input.guest_len = data_sz;
879 
880     trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
881                                 input.trans_uaddr, input.trans_len);
882 
883     ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_LAUNCH_SECRET,
884                     &input, &error);
885     if (ret) {
886         error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
887                      ret, error, fw_error_to_str(error));
888         return ret;
889     }
890 
891     return 0;
892 }
893 
894 static int
895 sev_es_parse_reset_block(SevInfoBlock *info, uint32_t *addr)
896 {
897     if (!info->reset_addr) {
898         error_report("SEV-ES reset address is zero");
899         return 1;
900     }
901 
902     *addr = info->reset_addr;
903 
904     return 0;
905 }
906 
907 static int
908 sev_es_find_reset_vector(void *flash_ptr, uint64_t flash_size,
909                          uint32_t *addr)
910 {
911     QemuUUID info_guid, *guid;
912     SevInfoBlock *info;
913     uint8_t *data;
914     uint16_t *len;
915 
916     /*
917      * Initialize the address to zero. An address of zero with a successful
918      * return code indicates that SEV-ES is not active.
919      */
920     *addr = 0;
921 
922     /*
923      * Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
924      * The SEV GUID is located on its own (original implementation) or within
925      * the Firmware GUID Table (new implementation), either of which are
926      * located 32 bytes from the end of the flash.
927      *
928      * Check the Firmware GUID Table first.
929      */
930     if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID, &data, NULL)) {
931         return sev_es_parse_reset_block((SevInfoBlock *)data, addr);
932     }
933 
934     /*
935      * SEV info block not found in the Firmware GUID Table (or there isn't
936      * a Firmware GUID Table), fall back to the original implementation.
937      */
938     data = flash_ptr + flash_size - 0x20;
939 
940     qemu_uuid_parse(SEV_INFO_BLOCK_GUID, &info_guid);
941     info_guid = qemu_uuid_bswap(info_guid); /* GUIDs are LE */
942 
943     guid = (QemuUUID *)(data - sizeof(info_guid));
944     if (!qemu_uuid_is_equal(guid, &info_guid)) {
945         error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
946         return 1;
947     }
948 
949     len = (uint16_t *)((uint8_t *)guid - sizeof(*len));
950     info = (SevInfoBlock *)(data - le16_to_cpu(*len));
951 
952     return sev_es_parse_reset_block(info, addr);
953 }
954 
955 void sev_es_set_reset_vector(CPUState *cpu)
956 {
957     X86CPU *x86;
958     CPUX86State *env;
959 
960     /* Only update if we have valid reset information */
961     if (!sev_guest || !sev_guest->reset_data_valid) {
962         return;
963     }
964 
965     /* Do not update the BSP reset state */
966     if (cpu->cpu_index == 0) {
967         return;
968     }
969 
970     x86 = X86_CPU(cpu);
971     env = &x86->env;
972 
973     cpu_x86_load_seg_cache(env, R_CS, 0xf000, sev_guest->reset_cs, 0xffff,
974                            DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
975                            DESC_R_MASK | DESC_A_MASK);
976 
977     env->eip = sev_guest->reset_ip;
978 }
979 
980 int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
981 {
982     CPUState *cpu;
983     uint32_t addr;
984     int ret;
985 
986     if (!sev_es_enabled()) {
987         return 0;
988     }
989 
990     addr = 0;
991     ret = sev_es_find_reset_vector(flash_ptr, flash_size,
992                                    &addr);
993     if (ret) {
994         return ret;
995     }
996 
997     if (addr) {
998         sev_guest->reset_cs = addr & 0xffff0000;
999         sev_guest->reset_ip = addr & 0x0000ffff;
1000         sev_guest->reset_data_valid = true;
1001 
1002         CPU_FOREACH(cpu) {
1003             sev_es_set_reset_vector(cpu);
1004         }
1005     }
1006 
1007     return 0;
1008 }
1009 
1010 static void
1011 sev_register_types(void)
1012 {
1013     type_register_static(&sev_guest_info);
1014 }
1015 
1016 type_init(sev_register_types);
1017