xref: /openbmc/qemu/include/system/confidential-guest-support.h (revision 65cb7129f4160c7e07a0da107f888ec73ae96776)
1*433442a7SPhilippe Mathieu-Daudé /*
2*433442a7SPhilippe Mathieu-Daudé  * QEMU Confidential Guest support
3*433442a7SPhilippe Mathieu-Daudé  *   This interface describes the common pieces between various
4*433442a7SPhilippe Mathieu-Daudé  *   schemes for protecting guest memory or other state against a
5*433442a7SPhilippe Mathieu-Daudé  *   compromised hypervisor.  This includes memory encryption (AMD's
6*433442a7SPhilippe Mathieu-Daudé  *   SEV and Intel's MKTME) or special protection modes (PEF on POWER,
7*433442a7SPhilippe Mathieu-Daudé  *   or PV on s390x).
8*433442a7SPhilippe Mathieu-Daudé  *
9*433442a7SPhilippe Mathieu-Daudé  * Copyright Red Hat.
10*433442a7SPhilippe Mathieu-Daudé  *
11*433442a7SPhilippe Mathieu-Daudé  * Authors:
12*433442a7SPhilippe Mathieu-Daudé  *  David Gibson <david@gibson.dropbear.id.au>
13*433442a7SPhilippe Mathieu-Daudé  *
14*433442a7SPhilippe Mathieu-Daudé  * This work is licensed under the terms of the GNU GPL, version 2 or
15*433442a7SPhilippe Mathieu-Daudé  * later.  See the COPYING file in the top-level directory.
16*433442a7SPhilippe Mathieu-Daudé  *
17*433442a7SPhilippe Mathieu-Daudé  */
18*433442a7SPhilippe Mathieu-Daudé #ifndef QEMU_CONFIDENTIAL_GUEST_SUPPORT_H
19*433442a7SPhilippe Mathieu-Daudé #define QEMU_CONFIDENTIAL_GUEST_SUPPORT_H
20*433442a7SPhilippe Mathieu-Daudé 
21*433442a7SPhilippe Mathieu-Daudé #ifdef CONFIG_USER_ONLY
22*433442a7SPhilippe Mathieu-Daudé #error Cannot include system/confidential-guest-support.h from user emulation
23*433442a7SPhilippe Mathieu-Daudé #endif
24*433442a7SPhilippe Mathieu-Daudé 
25*433442a7SPhilippe Mathieu-Daudé #include "qom/object.h"
26*433442a7SPhilippe Mathieu-Daudé 
27*433442a7SPhilippe Mathieu-Daudé #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
28*433442a7SPhilippe Mathieu-Daudé OBJECT_DECLARE_TYPE(ConfidentialGuestSupport,
29*433442a7SPhilippe Mathieu-Daudé                     ConfidentialGuestSupportClass,
30*433442a7SPhilippe Mathieu-Daudé                     CONFIDENTIAL_GUEST_SUPPORT)
31*433442a7SPhilippe Mathieu-Daudé 
32*433442a7SPhilippe Mathieu-Daudé 
33*433442a7SPhilippe Mathieu-Daudé struct ConfidentialGuestSupport {
34*433442a7SPhilippe Mathieu-Daudé     Object parent;
35*433442a7SPhilippe Mathieu-Daudé 
36*433442a7SPhilippe Mathieu-Daudé     /*
37*433442a7SPhilippe Mathieu-Daudé      * True if the machine should use guest_memfd for RAM.
38*433442a7SPhilippe Mathieu-Daudé      */
39*433442a7SPhilippe Mathieu-Daudé     bool require_guest_memfd;
40*433442a7SPhilippe Mathieu-Daudé 
41*433442a7SPhilippe Mathieu-Daudé     /*
42*433442a7SPhilippe Mathieu-Daudé      * ready: flag set by CGS initialization code once it's ready to
43*433442a7SPhilippe Mathieu-Daudé      *        start executing instructions in a potentially-secure
44*433442a7SPhilippe Mathieu-Daudé      *        guest
45*433442a7SPhilippe Mathieu-Daudé      *
46*433442a7SPhilippe Mathieu-Daudé      * The definition here is a bit fuzzy, because this is essentially
47*433442a7SPhilippe Mathieu-Daudé      * part of a self-sanity-check, rather than a strict mechanism.
48*433442a7SPhilippe Mathieu-Daudé      *
49*433442a7SPhilippe Mathieu-Daudé      * It's not feasible to have a single point in the common machine
50*433442a7SPhilippe Mathieu-Daudé      * init path to configure confidential guest support, because
51*433442a7SPhilippe Mathieu-Daudé      * different mechanisms have different interdependencies requiring
52*433442a7SPhilippe Mathieu-Daudé      * initialization in different places, often in arch or machine
53*433442a7SPhilippe Mathieu-Daudé      * type specific code.  It's also usually not possible to check
54*433442a7SPhilippe Mathieu-Daudé      * for invalid configurations until that initialization code.
55*433442a7SPhilippe Mathieu-Daudé      * That means it would be very easy to have a bug allowing CGS
56*433442a7SPhilippe Mathieu-Daudé      * init to be bypassed entirely in certain configurations.
57*433442a7SPhilippe Mathieu-Daudé      *
58*433442a7SPhilippe Mathieu-Daudé      * Silently ignoring a requested security feature would be bad, so
59*433442a7SPhilippe Mathieu-Daudé      * to avoid that we check late in init that this 'ready' flag is
60*433442a7SPhilippe Mathieu-Daudé      * set if CGS was requested.  If the CGS init hasn't happened, and
61*433442a7SPhilippe Mathieu-Daudé      * so 'ready' is not set, we'll abort.
62*433442a7SPhilippe Mathieu-Daudé      */
63*433442a7SPhilippe Mathieu-Daudé     bool ready;
64*433442a7SPhilippe Mathieu-Daudé };
65*433442a7SPhilippe Mathieu-Daudé 
66*433442a7SPhilippe Mathieu-Daudé typedef struct ConfidentialGuestSupportClass {
67*433442a7SPhilippe Mathieu-Daudé     ObjectClass parent;
68*433442a7SPhilippe Mathieu-Daudé 
69*433442a7SPhilippe Mathieu-Daudé     int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
70*433442a7SPhilippe Mathieu-Daudé     int (*kvm_reset)(ConfidentialGuestSupport *cgs, Error **errp);
71*433442a7SPhilippe Mathieu-Daudé } ConfidentialGuestSupportClass;
72*433442a7SPhilippe Mathieu-Daudé 
confidential_guest_kvm_init(ConfidentialGuestSupport * cgs,Error ** errp)73*433442a7SPhilippe Mathieu-Daudé static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs,
74*433442a7SPhilippe Mathieu-Daudé                                               Error **errp)
75*433442a7SPhilippe Mathieu-Daudé {
76*433442a7SPhilippe Mathieu-Daudé     ConfidentialGuestSupportClass *klass;
77*433442a7SPhilippe Mathieu-Daudé 
78*433442a7SPhilippe Mathieu-Daudé     klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
79*433442a7SPhilippe Mathieu-Daudé     if (klass->kvm_init) {
80*433442a7SPhilippe Mathieu-Daudé         return klass->kvm_init(cgs, errp);
81*433442a7SPhilippe Mathieu-Daudé     }
82*433442a7SPhilippe Mathieu-Daudé 
83*433442a7SPhilippe Mathieu-Daudé     return 0;
84*433442a7SPhilippe Mathieu-Daudé }
85*433442a7SPhilippe Mathieu-Daudé 
confidential_guest_kvm_reset(ConfidentialGuestSupport * cgs,Error ** errp)86*433442a7SPhilippe Mathieu-Daudé static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs,
87*433442a7SPhilippe Mathieu-Daudé                                                Error **errp)
88*433442a7SPhilippe Mathieu-Daudé {
89*433442a7SPhilippe Mathieu-Daudé     ConfidentialGuestSupportClass *klass;
90*433442a7SPhilippe Mathieu-Daudé 
91*433442a7SPhilippe Mathieu-Daudé     klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs);
92*433442a7SPhilippe Mathieu-Daudé     if (klass->kvm_reset) {
93*433442a7SPhilippe Mathieu-Daudé         return klass->kvm_reset(cgs, errp);
94*433442a7SPhilippe Mathieu-Daudé     }
95*433442a7SPhilippe Mathieu-Daudé 
96*433442a7SPhilippe Mathieu-Daudé     return 0;
97*433442a7SPhilippe Mathieu-Daudé }
98*433442a7SPhilippe Mathieu-Daudé 
99*433442a7SPhilippe Mathieu-Daudé #endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */
100