1.. SPDX-License-Identifier: GPL-2.0
2
3======================================
4Secure Encrypted Virtualization (SEV)
5======================================
6
7Overview
8========
9
10Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
11
12SEV is an extension to the AMD-V architecture which supports running
13virtual machines (VMs) under the control of a hypervisor. When enabled,
14the memory contents of a VM will be transparently encrypted with a key
15unique to that VM.
16
17The hypervisor can determine the SEV support through the CPUID
18instruction. The CPUID function 0x8000001f reports information related
19to SEV::
20
21	0x8000001f[eax]:
22			Bit[1] 	indicates support for SEV
23	    ...
24		  [ecx]:
25			Bits[31:0]  Number of encrypted guests supported simultaneously
26
27If support for SEV is present, MSR 0xc001_0010 (MSR_AMD64_SYSCFG) and MSR 0xc001_0015
28(MSR_K7_HWCR) can be used to determine if it can be enabled::
29
30	0xc001_0010:
31		Bit[23]	   1 = memory encryption can be enabled
32			   0 = memory encryption can not be enabled
33
34	0xc001_0015:
35		Bit[0]	   1 = memory encryption can be enabled
36			   0 = memory encryption can not be enabled
37
38When SEV support is available, it can be enabled in a specific VM by
39setting the SEV bit before executing VMRUN.::
40
41	VMCB[0x90]:
42		Bit[1]	    1 = SEV is enabled
43			    0 = SEV is disabled
44
45SEV hardware uses ASIDs to associate a memory encryption key with a VM.
46Hence, the ASID for the SEV-enabled guests must be from 1 to a maximum value
47defined in the CPUID 0x8000001f[ecx] field.
48
49The KVM_MEMORY_ENCRYPT_OP ioctl
50===============================
51
52The main ioctl to access SEV is KVM_MEMORY_ENCRYPT_OP, which operates on
53the VM file descriptor.  If the argument to KVM_MEMORY_ENCRYPT_OP is NULL,
54the ioctl returns 0 if SEV is enabled and ``ENOTTY`` if it is disabled
55(on some older versions of Linux, the ioctl tries to run normally even
56with a NULL argument, and therefore will likely return ``EFAULT`` instead
57of zero if SEV is enabled).  If non-NULL, the argument to
58KVM_MEMORY_ENCRYPT_OP must be a struct kvm_sev_cmd::
59
60       struct kvm_sev_cmd {
61               __u32 id;
62               __u64 data;
63               __u32 error;
64               __u32 sev_fd;
65       };
66
67
68The ``id`` field contains the subcommand, and the ``data`` field points to
69another struct containing arguments specific to command.  The ``sev_fd``
70should point to a file descriptor that is opened on the ``/dev/sev``
71device, if needed (see individual commands).
72
73On output, ``error`` is zero on success, or an error code.  Error codes
74are defined in ``<linux/psp-dev.h>``.
75
76KVM implements the following commands to support common lifecycle events of SEV
77guests, such as launching, running, snapshotting, migrating and decommissioning.
78
791. KVM_SEV_INIT
80---------------
81
82The KVM_SEV_INIT command is used by the hypervisor to initialize the SEV platform
83context. In a typical workflow, this command should be the first command issued.
84
85
86Returns: 0 on success, -negative on error
87
882. KVM_SEV_LAUNCH_START
89-----------------------
90
91The KVM_SEV_LAUNCH_START command is used for creating the memory encryption
92context. To create the encryption context, user must provide a guest policy,
93the owner's public Diffie-Hellman (PDH) key and session information.
94
95Parameters: struct  kvm_sev_launch_start (in/out)
96
97Returns: 0 on success, -negative on error
98
99::
100
101        struct kvm_sev_launch_start {
102                __u32 handle;           /* if zero then firmware creates a new handle */
103                __u32 policy;           /* guest's policy */
104
105                __u64 dh_uaddr;         /* userspace address pointing to the guest owner's PDH key */
106                __u32 dh_len;
107
108                __u64 session_addr;     /* userspace address which points to the guest session information */
109                __u32 session_len;
110        };
111
112On success, the 'handle' field contains a new handle and on error, a negative value.
113
114KVM_SEV_LAUNCH_START requires the ``sev_fd`` field to be valid.
115
116For more details, see SEV spec Section 6.2.
117
1183. KVM_SEV_LAUNCH_UPDATE_DATA
119-----------------------------
120
121The KVM_SEV_LAUNCH_UPDATE_DATA is used for encrypting a memory region. It also
122calculates a measurement of the memory contents. The measurement is a signature
123of the memory contents that can be sent to the guest owner as an attestation
124that the memory was encrypted correctly by the firmware.
125
126Parameters (in): struct  kvm_sev_launch_update_data
127
128Returns: 0 on success, -negative on error
129
130::
131
132        struct kvm_sev_launch_update {
133                __u64 uaddr;    /* userspace address to be encrypted (must be 16-byte aligned) */
134                __u32 len;      /* length of the data to be encrypted (must be 16-byte aligned) */
135        };
136
137For more details, see SEV spec Section 6.3.
138
1394. KVM_SEV_LAUNCH_MEASURE
140-------------------------
141
142The KVM_SEV_LAUNCH_MEASURE command is used to retrieve the measurement of the
143data encrypted by the KVM_SEV_LAUNCH_UPDATE_DATA command. The guest owner may
144wait to provide the guest with confidential information until it can verify the
145measurement. Since the guest owner knows the initial contents of the guest at
146boot, the measurement can be verified by comparing it to what the guest owner
147expects.
148
149If len is zero on entry, the measurement blob length is written to len and
150uaddr is unused.
151
152Parameters (in): struct  kvm_sev_launch_measure
153
154Returns: 0 on success, -negative on error
155
156::
157
158        struct kvm_sev_launch_measure {
159                __u64 uaddr;    /* where to copy the measurement */
160                __u32 len;      /* length of measurement blob */
161        };
162
163For more details on the measurement verification flow, see SEV spec Section 6.4.
164
1655. KVM_SEV_LAUNCH_FINISH
166------------------------
167
168After completion of the launch flow, the KVM_SEV_LAUNCH_FINISH command can be
169issued to make the guest ready for the execution.
170
171Returns: 0 on success, -negative on error
172
1736. KVM_SEV_GUEST_STATUS
174-----------------------
175
176The KVM_SEV_GUEST_STATUS command is used to retrieve status information about a
177SEV-enabled guest.
178
179Parameters (out): struct kvm_sev_guest_status
180
181Returns: 0 on success, -negative on error
182
183::
184
185        struct kvm_sev_guest_status {
186                __u32 handle;   /* guest handle */
187                __u32 policy;   /* guest policy */
188                __u8 state;     /* guest state (see enum below) */
189        };
190
191SEV guest state:
192
193::
194
195        enum {
196        SEV_STATE_INVALID = 0;
197        SEV_STATE_LAUNCHING,    /* guest is currently being launched */
198        SEV_STATE_SECRET,       /* guest is being launched and ready to accept the ciphertext data */
199        SEV_STATE_RUNNING,      /* guest is fully launched and running */
200        SEV_STATE_RECEIVING,    /* guest is being migrated in from another SEV machine */
201        SEV_STATE_SENDING       /* guest is getting migrated out to another SEV machine */
202        };
203
2047. KVM_SEV_DBG_DECRYPT
205----------------------
206
207The KVM_SEV_DEBUG_DECRYPT command can be used by the hypervisor to request the
208firmware to decrypt the data at the given memory region.
209
210Parameters (in): struct kvm_sev_dbg
211
212Returns: 0 on success, -negative on error
213
214::
215
216        struct kvm_sev_dbg {
217                __u64 src_uaddr;        /* userspace address of data to decrypt */
218                __u64 dst_uaddr;        /* userspace address of destination */
219                __u32 len;              /* length of memory region to decrypt */
220        };
221
222The command returns an error if the guest policy does not allow debugging.
223
2248. KVM_SEV_DBG_ENCRYPT
225----------------------
226
227The KVM_SEV_DEBUG_ENCRYPT command can be used by the hypervisor to request the
228firmware to encrypt the data at the given memory region.
229
230Parameters (in): struct kvm_sev_dbg
231
232Returns: 0 on success, -negative on error
233
234::
235
236        struct kvm_sev_dbg {
237                __u64 src_uaddr;        /* userspace address of data to encrypt */
238                __u64 dst_uaddr;        /* userspace address of destination */
239                __u32 len;              /* length of memory region to encrypt */
240        };
241
242The command returns an error if the guest policy does not allow debugging.
243
2449. KVM_SEV_LAUNCH_SECRET
245------------------------
246
247The KVM_SEV_LAUNCH_SECRET command can be used by the hypervisor to inject secret
248data after the measurement has been validated by the guest owner.
249
250Parameters (in): struct kvm_sev_launch_secret
251
252Returns: 0 on success, -negative on error
253
254::
255
256        struct kvm_sev_launch_secret {
257                __u64 hdr_uaddr;        /* userspace address containing the packet header */
258                __u32 hdr_len;
259
260                __u64 guest_uaddr;      /* the guest memory region where the secret should be injected */
261                __u32 guest_len;
262
263                __u64 trans_uaddr;      /* the hypervisor memory region which contains the secret */
264                __u32 trans_len;
265        };
266
26710. KVM_SEV_GET_ATTESTATION_REPORT
268----------------------------------
269
270The KVM_SEV_GET_ATTESTATION_REPORT command can be used by the hypervisor to query the attestation
271report containing the SHA-256 digest of the guest memory and VMSA passed through the KVM_SEV_LAUNCH
272commands and signed with the PEK. The digest returned by the command should match the digest
273used by the guest owner with the KVM_SEV_LAUNCH_MEASURE.
274
275If len is zero on entry, the measurement blob length is written to len and
276uaddr is unused.
277
278Parameters (in): struct kvm_sev_attestation
279
280Returns: 0 on success, -negative on error
281
282::
283
284        struct kvm_sev_attestation_report {
285                __u8 mnonce[16];        /* A random mnonce that will be placed in the report */
286
287                __u64 uaddr;            /* userspace address where the report should be copied */
288                __u32 len;
289        };
290
29111. KVM_SEV_SEND_START
292----------------------
293
294The KVM_SEV_SEND_START command can be used by the hypervisor to create an
295outgoing guest encryption context.
296
297If session_len is zero on entry, the length of the guest session information is
298written to session_len and all other fields are not used.
299
300Parameters (in): struct kvm_sev_send_start
301
302Returns: 0 on success, -negative on error
303
304::
305
306        struct kvm_sev_send_start {
307                __u32 policy;                 /* guest policy */
308
309                __u64 pdh_cert_uaddr;         /* platform Diffie-Hellman certificate */
310                __u32 pdh_cert_len;
311
312                __u64 plat_certs_uaddr;        /* platform certificate chain */
313                __u32 plat_certs_len;
314
315                __u64 amd_certs_uaddr;        /* AMD certificate */
316                __u32 amd_certs_len;
317
318                __u64 session_uaddr;          /* Guest session information */
319                __u32 session_len;
320        };
321
32212. KVM_SEV_SEND_UPDATE_DATA
323----------------------------
324
325The KVM_SEV_SEND_UPDATE_DATA command can be used by the hypervisor to encrypt the
326outgoing guest memory region with the encryption context creating using
327KVM_SEV_SEND_START.
328
329If hdr_len or trans_len are zero on entry, the length of the packet header and
330transport region are written to hdr_len and trans_len respectively, and all
331other fields are not used.
332
333Parameters (in): struct kvm_sev_send_update_data
334
335Returns: 0 on success, -negative on error
336
337::
338
339        struct kvm_sev_launch_send_update_data {
340                __u64 hdr_uaddr;        /* userspace address containing the packet header */
341                __u32 hdr_len;
342
343                __u64 guest_uaddr;      /* the source memory region to be encrypted */
344                __u32 guest_len;
345
346                __u64 trans_uaddr;      /* the destination memory region  */
347                __u32 trans_len;
348        };
349
35013. KVM_SEV_SEND_FINISH
351------------------------
352
353After completion of the migration flow, the KVM_SEV_SEND_FINISH command can be
354issued by the hypervisor to delete the encryption context.
355
356Returns: 0 on success, -negative on error
357
35814. KVM_SEV_SEND_CANCEL
359------------------------
360
361After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the
362SEND_CANCEL command to stop a migration. This is necessary so that a cancelled
363migration can restart with a new target later.
364
365Returns: 0 on success, -negative on error
366
36715. KVM_SEV_RECEIVE_START
368-------------------------
369
370The KVM_SEV_RECEIVE_START command is used for creating the memory encryption
371context for an incoming SEV guest. To create the encryption context, the user must
372provide a guest policy, the platform public Diffie-Hellman (PDH) key and session
373information.
374
375Parameters: struct  kvm_sev_receive_start (in/out)
376
377Returns: 0 on success, -negative on error
378
379::
380
381        struct kvm_sev_receive_start {
382                __u32 handle;           /* if zero then firmware creates a new handle */
383                __u32 policy;           /* guest's policy */
384
385                __u64 pdh_uaddr;        /* userspace address pointing to the PDH key */
386                __u32 pdh_len;
387
388                __u64 session_uaddr;    /* userspace address which points to the guest session information */
389                __u32 session_len;
390        };
391
392On success, the 'handle' field contains a new handle and on error, a negative value.
393
394For more details, see SEV spec Section 6.12.
395
39616. KVM_SEV_RECEIVE_UPDATE_DATA
397-------------------------------
398
399The KVM_SEV_RECEIVE_UPDATE_DATA command can be used by the hypervisor to copy
400the incoming buffers into the guest memory region with encryption context
401created during the KVM_SEV_RECEIVE_START.
402
403Parameters (in): struct kvm_sev_receive_update_data
404
405Returns: 0 on success, -negative on error
406
407::
408
409        struct kvm_sev_launch_receive_update_data {
410                __u64 hdr_uaddr;        /* userspace address containing the packet header */
411                __u32 hdr_len;
412
413                __u64 guest_uaddr;      /* the destination guest memory region */
414                __u32 guest_len;
415
416                __u64 trans_uaddr;      /* the incoming buffer memory region  */
417                __u32 trans_len;
418        };
419
42017. KVM_SEV_RECEIVE_FINISH
421--------------------------
422
423After completion of the migration flow, the KVM_SEV_RECEIVE_FINISH command can be
424issued by the hypervisor to make the guest ready for execution.
425
426Returns: 0 on success, -negative on error
427
428Firmware Management
429===================
430
431The SEV guest key management is handled by a separate processor called the AMD
432Secure Processor (AMD-SP). Firmware running inside the AMD-SP provides a secure
433key management interface to perform common hypervisor activities such as
434encrypting bootstrap code, snapshot, migrating and debugging the guest. For more
435information, see the SEV Key Management spec [api-spec]_
436
437The AMD-SP firmware can be initialized either by using its own non-volatile
438storage or the OS can manage the NV storage for the firmware using
439parameter ``init_ex_path`` of the ``ccp`` module. If the file specified
440by ``init_ex_path`` does not exist or is invalid, the OS will create or
441override the file with PSP non-volatile storage.
442
443References
444==========
445
446
447See [white-paper]_, [api-spec]_, [amd-apm]_ and [kvm-forum]_ for more info.
448
449.. [white-paper] https://developer.amd.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
450.. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf
451.. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34)
452.. [kvm-forum]  https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf
453