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