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``. If the file specified by ``init_ex_path`` does not exist or 93is invalid, the OS will create or override the file with output from PSP. 94 95Returns: 0 on success, -negative on error 96 972. KVM_SEV_LAUNCH_START 98----------------------- 99 100The KVM_SEV_LAUNCH_START command is used for creating the memory encryption 101context. To create the encryption context, user must provide a guest policy, 102the owner's public Diffie-Hellman (PDH) key and session information. 103 104Parameters: struct kvm_sev_launch_start (in/out) 105 106Returns: 0 on success, -negative on error 107 108:: 109 110 struct kvm_sev_launch_start { 111 __u32 handle; /* if zero then firmware creates a new handle */ 112 __u32 policy; /* guest's policy */ 113 114 __u64 dh_uaddr; /* userspace address pointing to the guest owner's PDH key */ 115 __u32 dh_len; 116 117 __u64 session_addr; /* userspace address which points to the guest session information */ 118 __u32 session_len; 119 }; 120 121On success, the 'handle' field contains a new handle and on error, a negative value. 122 123KVM_SEV_LAUNCH_START requires the ``sev_fd`` field to be valid. 124 125For more details, see SEV spec Section 6.2. 126 1273. KVM_SEV_LAUNCH_UPDATE_DATA 128----------------------------- 129 130The KVM_SEV_LAUNCH_UPDATE_DATA is used for encrypting a memory region. It also 131calculates a measurement of the memory contents. The measurement is a signature 132of the memory contents that can be sent to the guest owner as an attestation 133that the memory was encrypted correctly by the firmware. 134 135Parameters (in): struct kvm_sev_launch_update_data 136 137Returns: 0 on success, -negative on error 138 139:: 140 141 struct kvm_sev_launch_update { 142 __u64 uaddr; /* userspace address to be encrypted (must be 16-byte aligned) */ 143 __u32 len; /* length of the data to be encrypted (must be 16-byte aligned) */ 144 }; 145 146For more details, see SEV spec Section 6.3. 147 1484. KVM_SEV_LAUNCH_MEASURE 149------------------------- 150 151The KVM_SEV_LAUNCH_MEASURE command is used to retrieve the measurement of the 152data encrypted by the KVM_SEV_LAUNCH_UPDATE_DATA command. The guest owner may 153wait to provide the guest with confidential information until it can verify the 154measurement. Since the guest owner knows the initial contents of the guest at 155boot, the measurement can be verified by comparing it to what the guest owner 156expects. 157 158If len is zero on entry, the measurement blob length is written to len and 159uaddr is unused. 160 161Parameters (in): struct kvm_sev_launch_measure 162 163Returns: 0 on success, -negative on error 164 165:: 166 167 struct kvm_sev_launch_measure { 168 __u64 uaddr; /* where to copy the measurement */ 169 __u32 len; /* length of measurement blob */ 170 }; 171 172For more details on the measurement verification flow, see SEV spec Section 6.4. 173 1745. KVM_SEV_LAUNCH_FINISH 175------------------------ 176 177After completion of the launch flow, the KVM_SEV_LAUNCH_FINISH command can be 178issued to make the guest ready for the execution. 179 180Returns: 0 on success, -negative on error 181 1826. KVM_SEV_GUEST_STATUS 183----------------------- 184 185The KVM_SEV_GUEST_STATUS command is used to retrieve status information about a 186SEV-enabled guest. 187 188Parameters (out): struct kvm_sev_guest_status 189 190Returns: 0 on success, -negative on error 191 192:: 193 194 struct kvm_sev_guest_status { 195 __u32 handle; /* guest handle */ 196 __u32 policy; /* guest policy */ 197 __u8 state; /* guest state (see enum below) */ 198 }; 199 200SEV guest state: 201 202:: 203 204 enum { 205 SEV_STATE_INVALID = 0; 206 SEV_STATE_LAUNCHING, /* guest is currently being launched */ 207 SEV_STATE_SECRET, /* guest is being launched and ready to accept the ciphertext data */ 208 SEV_STATE_RUNNING, /* guest is fully launched and running */ 209 SEV_STATE_RECEIVING, /* guest is being migrated in from another SEV machine */ 210 SEV_STATE_SENDING /* guest is getting migrated out to another SEV machine */ 211 }; 212 2137. KVM_SEV_DBG_DECRYPT 214---------------------- 215 216The KVM_SEV_DEBUG_DECRYPT command can be used by the hypervisor to request the 217firmware to decrypt the data at the given memory region. 218 219Parameters (in): struct kvm_sev_dbg 220 221Returns: 0 on success, -negative on error 222 223:: 224 225 struct kvm_sev_dbg { 226 __u64 src_uaddr; /* userspace address of data to decrypt */ 227 __u64 dst_uaddr; /* userspace address of destination */ 228 __u32 len; /* length of memory region to decrypt */ 229 }; 230 231The command returns an error if the guest policy does not allow debugging. 232 2338. KVM_SEV_DBG_ENCRYPT 234---------------------- 235 236The KVM_SEV_DEBUG_ENCRYPT command can be used by the hypervisor to request the 237firmware to encrypt the data at the given memory region. 238 239Parameters (in): struct kvm_sev_dbg 240 241Returns: 0 on success, -negative on error 242 243:: 244 245 struct kvm_sev_dbg { 246 __u64 src_uaddr; /* userspace address of data to encrypt */ 247 __u64 dst_uaddr; /* userspace address of destination */ 248 __u32 len; /* length of memory region to encrypt */ 249 }; 250 251The command returns an error if the guest policy does not allow debugging. 252 2539. KVM_SEV_LAUNCH_SECRET 254------------------------ 255 256The KVM_SEV_LAUNCH_SECRET command can be used by the hypervisor to inject secret 257data after the measurement has been validated by the guest owner. 258 259Parameters (in): struct kvm_sev_launch_secret 260 261Returns: 0 on success, -negative on error 262 263:: 264 265 struct kvm_sev_launch_secret { 266 __u64 hdr_uaddr; /* userspace address containing the packet header */ 267 __u32 hdr_len; 268 269 __u64 guest_uaddr; /* the guest memory region where the secret should be injected */ 270 __u32 guest_len; 271 272 __u64 trans_uaddr; /* the hypervisor memory region which contains the secret */ 273 __u32 trans_len; 274 }; 275 27610. KVM_SEV_GET_ATTESTATION_REPORT 277---------------------------------- 278 279The KVM_SEV_GET_ATTESTATION_REPORT command can be used by the hypervisor to query the attestation 280report containing the SHA-256 digest of the guest memory and VMSA passed through the KVM_SEV_LAUNCH 281commands and signed with the PEK. The digest returned by the command should match the digest 282used by the guest owner with the KVM_SEV_LAUNCH_MEASURE. 283 284If len is zero on entry, the measurement blob length is written to len and 285uaddr is unused. 286 287Parameters (in): struct kvm_sev_attestation 288 289Returns: 0 on success, -negative on error 290 291:: 292 293 struct kvm_sev_attestation_report { 294 __u8 mnonce[16]; /* A random mnonce that will be placed in the report */ 295 296 __u64 uaddr; /* userspace address where the report should be copied */ 297 __u32 len; 298 }; 299 30011. KVM_SEV_SEND_START 301---------------------- 302 303The KVM_SEV_SEND_START command can be used by the hypervisor to create an 304outgoing guest encryption context. 305 306If session_len is zero on entry, the length of the guest session information is 307written to session_len and all other fields are not used. 308 309Parameters (in): struct kvm_sev_send_start 310 311Returns: 0 on success, -negative on error 312 313:: 314 315 struct kvm_sev_send_start { 316 __u32 policy; /* guest policy */ 317 318 __u64 pdh_cert_uaddr; /* platform Diffie-Hellman certificate */ 319 __u32 pdh_cert_len; 320 321 __u64 plat_certs_uaddr; /* platform certificate chain */ 322 __u32 plat_certs_len; 323 324 __u64 amd_certs_uaddr; /* AMD certificate */ 325 __u32 amd_certs_len; 326 327 __u64 session_uaddr; /* Guest session information */ 328 __u32 session_len; 329 }; 330 33112. KVM_SEV_SEND_UPDATE_DATA 332---------------------------- 333 334The KVM_SEV_SEND_UPDATE_DATA command can be used by the hypervisor to encrypt the 335outgoing guest memory region with the encryption context creating using 336KVM_SEV_SEND_START. 337 338If hdr_len or trans_len are zero on entry, the length of the packet header and 339transport region are written to hdr_len and trans_len respectively, and all 340other fields are not used. 341 342Parameters (in): struct kvm_sev_send_update_data 343 344Returns: 0 on success, -negative on error 345 346:: 347 348 struct kvm_sev_launch_send_update_data { 349 __u64 hdr_uaddr; /* userspace address containing the packet header */ 350 __u32 hdr_len; 351 352 __u64 guest_uaddr; /* the source memory region to be encrypted */ 353 __u32 guest_len; 354 355 __u64 trans_uaddr; /* the destination memory region */ 356 __u32 trans_len; 357 }; 358 35913. KVM_SEV_SEND_FINISH 360------------------------ 361 362After completion of the migration flow, the KVM_SEV_SEND_FINISH command can be 363issued by the hypervisor to delete the encryption context. 364 365Returns: 0 on success, -negative on error 366 36714. KVM_SEV_SEND_CANCEL 368------------------------ 369 370After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the 371SEND_CANCEL command to stop a migration. This is necessary so that a cancelled 372migration can restart with a new target later. 373 374Returns: 0 on success, -negative on error 375 37615. KVM_SEV_RECEIVE_START 377------------------------- 378 379The KVM_SEV_RECEIVE_START command is used for creating the memory encryption 380context for an incoming SEV guest. To create the encryption context, the user must 381provide a guest policy, the platform public Diffie-Hellman (PDH) key and session 382information. 383 384Parameters: struct kvm_sev_receive_start (in/out) 385 386Returns: 0 on success, -negative on error 387 388:: 389 390 struct kvm_sev_receive_start { 391 __u32 handle; /* if zero then firmware creates a new handle */ 392 __u32 policy; /* guest's policy */ 393 394 __u64 pdh_uaddr; /* userspace address pointing to the PDH key */ 395 __u32 pdh_len; 396 397 __u64 session_uaddr; /* userspace address which points to the guest session information */ 398 __u32 session_len; 399 }; 400 401On success, the 'handle' field contains a new handle and on error, a negative value. 402 403For more details, see SEV spec Section 6.12. 404 40516. KVM_SEV_RECEIVE_UPDATE_DATA 406------------------------------- 407 408The KVM_SEV_RECEIVE_UPDATE_DATA command can be used by the hypervisor to copy 409the incoming buffers into the guest memory region with encryption context 410created during the KVM_SEV_RECEIVE_START. 411 412Parameters (in): struct kvm_sev_receive_update_data 413 414Returns: 0 on success, -negative on error 415 416:: 417 418 struct kvm_sev_launch_receive_update_data { 419 __u64 hdr_uaddr; /* userspace address containing the packet header */ 420 __u32 hdr_len; 421 422 __u64 guest_uaddr; /* the destination guest memory region */ 423 __u32 guest_len; 424 425 __u64 trans_uaddr; /* the incoming buffer memory region */ 426 __u32 trans_len; 427 }; 428 42917. KVM_SEV_RECEIVE_FINISH 430-------------------------- 431 432After completion of the migration flow, the KVM_SEV_RECEIVE_FINISH command can be 433issued by the hypervisor to make the guest ready for execution. 434 435Returns: 0 on success, -negative on error 436 437References 438========== 439 440 441See [white-paper]_, [api-spec]_, [amd-apm]_ and [kvm-forum]_ for more info. 442 443.. [white-paper] http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf 444.. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf 445.. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34) 446.. [kvm-forum] https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf 447