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