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