xref: /linux/Documentation/virt/coco/sev-guest.rst (revision f5db8841ebe59dbdf07fda797c88ccb51e0c893d)
1.. SPDX-License-Identifier: GPL-2.0
2
3===================================================================
4The Definitive SEV Guest API Documentation
5===================================================================
6
71. General description
8======================
9
10The SEV API is a set of ioctls that are used by the guest or hypervisor
11to get or set a certain aspect of the SEV virtual machine. The ioctls belong
12to the following classes:
13
14 - Hypervisor ioctls: These query and set global attributes which affect the
15   whole SEV firmware.  These ioctl are used by platform provisioning tools.
16
17 - Guest ioctls: These query and set attributes of the SEV virtual machine.
18
192. API description
20==================
21
22This section describes ioctls that is used for querying the SEV guest report
23from the SEV firmware. For each ioctl, the following information is provided
24along with a description:
25
26  Technology:
27      which SEV technology provides this ioctl. SEV, SEV-ES, SEV-SNP or all.
28
29  Type:
30      hypervisor or guest. The ioctl can be used inside the guest or the
31      hypervisor.
32
33  Parameters:
34      what parameters are accepted by the ioctl.
35
36  Returns:
37      the return value.  General error numbers (-ENOMEM, -EINVAL)
38      are not detailed, but errors with specific meanings are.
39
40The guest ioctl should be issued on a file descriptor of the /dev/sev-guest
41device.  The ioctl accepts struct snp_user_guest_request. The input and
42output structure is specified through the req_data and resp_data field
43respectively. If the ioctl fails to execute due to a firmware error, then
44the fw_error code will be set, otherwise fw_error will be set to -1.
45
46The firmware checks that the message sequence counter is one greater than
47the guests message sequence counter. If guest driver fails to increment message
48counter (e.g. counter overflow), then -EIO will be returned.
49
50::
51
52        struct snp_guest_request_ioctl {
53                /* Message version number */
54                __u32 msg_version;
55
56                /* Request and response structure address */
57                __u64 req_data;
58                __u64 resp_data;
59
60                /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */
61                union {
62                        __u64 exitinfo2;
63                        struct {
64                                __u32 fw_error;
65                                __u32 vmm_error;
66                        };
67                };
68        };
69
70The host ioctls are issued to a file descriptor of the /dev/sev device.
71The ioctl accepts the command ID/input structure documented below.
72
73::
74        struct sev_issue_cmd {
75                /* Command ID */
76                __u32 cmd;
77
78                /* Command request structure */
79                __u64 data;
80
81                /* Firmware error code on failure (see psp-sev.h) */
82                __u32 error;
83        };
84
85
862.1 SNP_GET_REPORT
87------------------
88
89:Technology: sev-snp
90:Type: guest ioctl
91:Parameters (in): struct snp_report_req
92:Returns (out): struct snp_report_resp on success, -negative on error
93
94The SNP_GET_REPORT ioctl can be used to query the attestation report from the
95SEV-SNP firmware. The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command
96provided by the SEV-SNP firmware to query the attestation report.
97
98On success, the snp_report_resp.data will contains the report. The report
99contain the format described in the SEV-SNP specification. See the SEV-SNP
100specification for further details.
101
1022.2 SNP_GET_DERIVED_KEY
103-----------------------
104:Technology: sev-snp
105:Type: guest ioctl
106:Parameters (in): struct snp_derived_key_req
107:Returns (out): struct snp_derived_key_resp on success, -negative on error
108
109The SNP_GET_DERIVED_KEY ioctl can be used to get a key derive from a root key.
110The derived key can be used by the guest for any purpose, such as sealing keys
111or communicating with external entities.
112
113The ioctl uses the SNP_GUEST_REQUEST (MSG_KEY_REQ) command provided by the
114SEV-SNP firmware to derive the key. See SEV-SNP specification for further details
115on the various fields passed in the key derivation request.
116
117On success, the snp_derived_key_resp.data contains the derived key value. See
118the SEV-SNP specification for further details.
119
120
1212.3 SNP_GET_EXT_REPORT
122----------------------
123:Technology: sev-snp
124:Type: guest ioctl
125:Parameters (in/out): struct snp_ext_report_req
126:Returns (out): struct snp_report_resp on success, -negative on error
127
128The SNP_GET_EXT_REPORT ioctl is similar to the SNP_GET_REPORT. The difference is
129related to the additional certificate data that is returned with the report.
130The certificate data returned is being provided by the hypervisor through the
131SNP_SET_EXT_CONFIG.
132
133The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command provided by the SEV-SNP
134firmware to get the attestation report.
135
136On success, the snp_ext_report_resp.data will contain the attestation report
137and snp_ext_report_req.certs_address will contain the certificate blob. If the
138length of the blob is smaller than expected then snp_ext_report_req.certs_len will
139be updated with the expected value.
140
141See GHCB specification for further detail on how to parse the certificate blob.
142
1432.4 SNP_PLATFORM_STATUS
144-----------------------
145:Technology: sev-snp
146:Type: hypervisor ioctl cmd
147:Parameters (out): struct sev_user_data_snp_status
148:Returns (out): 0 on success, -negative on error
149
150The SNP_PLATFORM_STATUS command is used to query the SNP platform status. The
151status includes API major, minor version and more. See the SEV-SNP
152specification for further details.
153
1543. SEV-SNP CPUID Enforcement
155============================
156
157SEV-SNP guests can access a special page that contains a table of CPUID values
158that have been validated by the PSP as part of the SNP_LAUNCH_UPDATE firmware
159command. It provides the following assurances regarding the validity of CPUID
160values:
161
162 - Its address is obtained via bootloader/firmware (via CC blob), and those
163   binaries will be measured as part of the SEV-SNP attestation report.
164 - Its initial state will be encrypted/pvalidated, so attempts to modify
165   it during run-time will result in garbage being written, or #VC exceptions
166   being generated due to changes in validation state if the hypervisor tries
167   to swap the backing page.
168 - Attempts to bypass PSP checks by the hypervisor by using a normal page, or
169   a non-CPUID encrypted page will change the measurement provided by the
170   SEV-SNP attestation report.
171 - The CPUID page contents are *not* measured, but attempts to modify the
172   expected contents of a CPUID page as part of guest initialization will be
173   gated by the PSP CPUID enforcement policy checks performed on the page
174   during SNP_LAUNCH_UPDATE, and noticeable later if the guest owner
175   implements their own checks of the CPUID values.
176
177It is important to note that this last assurance is only useful if the kernel
178has taken care to make use of the SEV-SNP CPUID throughout all stages of boot.
179Otherwise, guest owner attestation provides no assurance that the kernel wasn't
180fed incorrect values at some point during boot.
181
182
183Reference
184---------
185
186SEV-SNP and GHCB specification: developer.amd.com/sev
187
188The driver is based on SEV-SNP firmware spec 0.9 and GHCB spec version 2.0.
189