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