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