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