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