amd-memory-encryption.rst (18699B)
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 43818. KVM_SNP_INIT 439---------------- 440 441The KVM_SNP_INIT command can be used by the hypervisor to initialize SEV-SNP 442context. In a typical workflow, this command should be the first command issued. 443 444Parameters (in/out): struct kvm_snp_init 445 446Returns: 0 on success, -negative on error 447 448:: 449 450 struct kvm_snp_init { 451 __u64 flags; 452 }; 453 454The flags bitmap is defined as:: 455 456 /* enable the restricted injection */ 457 #define KVM_SEV_SNP_RESTRICTED_INJET (1<<0) 458 459 /* enable the restricted injection timer */ 460 #define KVM_SEV_SNP_RESTRICTED_TIMER_INJET (1<<1) 461 462If the specified flags is not supported then return -EOPNOTSUPP, and the supported 463flags are returned. 464 46519. KVM_SNP_LAUNCH_START 466------------------------ 467 468The KVM_SNP_LAUNCH_START command is used for creating the memory encryption 469context for the SEV-SNP guest. To create the encryption context, user must 470provide a guest policy, migration agent (if any) and guest OS visible 471workarounds value as defined SEV-SNP specification. 472 473Parameters (in): struct kvm_snp_launch_start 474 475Returns: 0 on success, -negative on error 476 477:: 478 479 struct kvm_sev_snp_launch_start { 480 __u64 policy; /* Guest policy to use. */ 481 __u64 ma_uaddr; /* userspace address of migration agent */ 482 __u8 ma_en; /* 1 if the migtation agent is enabled */ 483 __u8 imi_en; /* set IMI to 1. */ 484 __u8 gosvw[16]; /* guest OS visible workarounds */ 485 }; 486 487See the SEV-SNP specification for further detail on the launch input. 488 48920. KVM_SNP_LAUNCH_UPDATE 490------------------------- 491 492The KVM_SNP_LAUNCH_UPDATE is used for encrypting a memory region. It also 493calculates a measurement of the memory contents. The measurement is a signature 494of the memory contents that can be sent to the guest owner as an attestation 495that the memory was encrypted correctly by the firmware. 496 497Parameters (in): struct kvm_snp_launch_update 498 499Returns: 0 on success, -negative on error 500 501:: 502 503 struct kvm_sev_snp_launch_update { 504 __u64 start_gfn; /* Guest page number to start from. */ 505 __u64 uaddr; /* userspace address need to be encrypted */ 506 __u32 len; /* length of memory region */ 507 __u8 imi_page; /* 1 if memory is part of the IMI */ 508 __u8 page_type; /* page type */ 509 __u8 vmpl3_perms; /* VMPL3 permission mask */ 510 __u8 vmpl2_perms; /* VMPL2 permission mask */ 511 __u8 vmpl1_perms; /* VMPL1 permission mask */ 512 }; 513 514See the SEV-SNP spec for further details on how to build the VMPL permission 515mask and page type. 516 51721. KVM_SNP_LAUNCH_FINISH 518------------------------- 519 520After completion of the SNP guest launch flow, the KVM_SNP_LAUNCH_FINISH command can be 521issued to make the guest ready for the execution. 522 523Parameters (in): struct kvm_sev_snp_launch_finish 524 525Returns: 0 on success, -negative on error 526 527:: 528 529 struct kvm_sev_snp_launch_finish { 530 __u64 id_block_uaddr; 531 __u64 id_auth_uaddr; 532 __u8 id_block_en; 533 __u8 auth_key_en; 534 __u8 host_data[32]; 535 }; 536 537 538See SEV-SNP specification for further details on launch finish input parameters. 539 540References 541========== 542 543 544See [white-paper]_, [api-spec]_, [amd-apm]_ and [kvm-forum]_ for more info. 545 546.. [white-paper] http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf 547.. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf 548.. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34) 549.. [kvm-forum] https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf