0001 .. SPDX-License-Identifier: GPL-2.0
0002
0003 ======================================
0004 Secure Encrypted Virtualization (SEV)
0005 ======================================
0006
0007 Overview
0008 ========
0009
0010 Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
0011
0012 SEV is an extension to the AMD-V architecture which supports running
0013 virtual machines (VMs) under the control of a hypervisor. When enabled,
0014 the memory contents of a VM will be transparently encrypted with a key
0015 unique to that VM.
0016
0017 The hypervisor can determine the SEV support through the CPUID
0018 instruction. The CPUID function 0x8000001f reports information related
0019 to SEV::
0020
0021 0x8000001f[eax]:
0022 Bit[1] indicates support for SEV
0023 ...
0024 [ecx]:
0025 Bits[31:0] Number of encrypted guests supported simultaneously
0026
0027 If support for SEV is present, MSR 0xc001_0010 (MSR_AMD64_SYSCFG) and MSR 0xc001_0015
0028 (MSR_K7_HWCR) can be used to determine if it can be enabled::
0029
0030 0xc001_0010:
0031 Bit[23] 1 = memory encryption can be enabled
0032 0 = memory encryption can not be enabled
0033
0034 0xc001_0015:
0035 Bit[0] 1 = memory encryption can be enabled
0036 0 = memory encryption can not be enabled
0037
0038 When SEV support is available, it can be enabled in a specific VM by
0039 setting the SEV bit before executing VMRUN.::
0040
0041 VMCB[0x90]:
0042 Bit[1] 1 = SEV is enabled
0043 0 = SEV is disabled
0044
0045 SEV hardware uses ASIDs to associate a memory encryption key with a VM.
0046 Hence, the ASID for the SEV-enabled guests must be from 1 to a maximum value
0047 defined in the CPUID 0x8000001f[ecx] field.
0048
0049 SEV Key Management
0050 ==================
0051
0052 The SEV guest key management is handled by a separate processor called the AMD
0053 Secure Processor (AMD-SP). Firmware running inside the AMD-SP provides a secure
0054 key management interface to perform common hypervisor activities such as
0055 encrypting bootstrap code, snapshot, migrating and debugging the guest. For more
0056 information, see the SEV Key Management spec [api-spec]_
0057
0058 The main ioctl to access SEV is KVM_MEMORY_ENCRYPT_OP. If the argument
0059 to KVM_MEMORY_ENCRYPT_OP is NULL, the ioctl returns 0 if SEV is enabled
0060 and ``ENOTTY` if it is disabled (on some older versions of Linux,
0061 the ioctl runs normally even with a NULL argument, and therefore will
0062 likely return ``EFAULT``). If non-NULL, the argument to KVM_MEMORY_ENCRYPT_OP
0063 must be a struct kvm_sev_cmd::
0064
0065 struct kvm_sev_cmd {
0066 __u32 id;
0067 __u64 data;
0068 __u32 error;
0069 __u32 sev_fd;
0070 };
0071
0072
0073 The ``id`` field contains the subcommand, and the ``data`` field points to
0074 another struct containing arguments specific to command. The ``sev_fd``
0075 should point to a file descriptor that is opened on the ``/dev/sev``
0076 device, if needed (see individual commands).
0077
0078 On output, ``error`` is zero on success, or an error code. Error codes
0079 are defined in ``<linux/psp-dev.h>``.
0080
0081 KVM implements the following commands to support common lifecycle events of SEV
0082 guests, such as launching, running, snapshotting, migrating and decommissioning.
0083
0084 1. KVM_SEV_INIT
0085 ---------------
0086
0087 The KVM_SEV_INIT command is used by the hypervisor to initialize the SEV platform
0088 context. In a typical workflow, this command should be the first command issued.
0089
0090 The firmware can be initialized either by using its own non-volatile storage or
0091 the OS can manage the NV storage for the firmware using the module parameter
0092 ``init_ex_path``. The file specified by ``init_ex_path`` must exist. To create
0093 a new NV storage file allocate the file with 32KB bytes of 0xFF as required by
0094 the SEV spec.
0095
0096 Returns: 0 on success, -negative on error
0097
0098 2. KVM_SEV_LAUNCH_START
0099 -----------------------
0100
0101 The KVM_SEV_LAUNCH_START command is used for creating the memory encryption
0102 context. To create the encryption context, user must provide a guest policy,
0103 the owner's public Diffie-Hellman (PDH) key and session information.
0104
0105 Parameters: struct kvm_sev_launch_start (in/out)
0106
0107 Returns: 0 on success, -negative on error
0108
0109 ::
0110
0111 struct kvm_sev_launch_start {
0112 __u32 handle; /* if zero then firmware creates a new handle */
0113 __u32 policy; /* guest's policy */
0114
0115 __u64 dh_uaddr; /* userspace address pointing to the guest owner's PDH key */
0116 __u32 dh_len;
0117
0118 __u64 session_addr; /* userspace address which points to the guest session information */
0119 __u32 session_len;
0120 };
0121
0122 On success, the 'handle' field contains a new handle and on error, a negative value.
0123
0124 KVM_SEV_LAUNCH_START requires the ``sev_fd`` field to be valid.
0125
0126 For more details, see SEV spec Section 6.2.
0127
0128 3. KVM_SEV_LAUNCH_UPDATE_DATA
0129 -----------------------------
0130
0131 The KVM_SEV_LAUNCH_UPDATE_DATA is used for encrypting a memory region. It also
0132 calculates a measurement of the memory contents. The measurement is a signature
0133 of the memory contents that can be sent to the guest owner as an attestation
0134 that the memory was encrypted correctly by the firmware.
0135
0136 Parameters (in): struct kvm_sev_launch_update_data
0137
0138 Returns: 0 on success, -negative on error
0139
0140 ::
0141
0142 struct kvm_sev_launch_update {
0143 __u64 uaddr; /* userspace address to be encrypted (must be 16-byte aligned) */
0144 __u32 len; /* length of the data to be encrypted (must be 16-byte aligned) */
0145 };
0146
0147 For more details, see SEV spec Section 6.3.
0148
0149 4. KVM_SEV_LAUNCH_MEASURE
0150 -------------------------
0151
0152 The KVM_SEV_LAUNCH_MEASURE command is used to retrieve the measurement of the
0153 data encrypted by the KVM_SEV_LAUNCH_UPDATE_DATA command. The guest owner may
0154 wait to provide the guest with confidential information until it can verify the
0155 measurement. Since the guest owner knows the initial contents of the guest at
0156 boot, the measurement can be verified by comparing it to what the guest owner
0157 expects.
0158
0159 If len is zero on entry, the measurement blob length is written to len and
0160 uaddr is unused.
0161
0162 Parameters (in): struct kvm_sev_launch_measure
0163
0164 Returns: 0 on success, -negative on error
0165
0166 ::
0167
0168 struct kvm_sev_launch_measure {
0169 __u64 uaddr; /* where to copy the measurement */
0170 __u32 len; /* length of measurement blob */
0171 };
0172
0173 For more details on the measurement verification flow, see SEV spec Section 6.4.
0174
0175 5. KVM_SEV_LAUNCH_FINISH
0176 ------------------------
0177
0178 After completion of the launch flow, the KVM_SEV_LAUNCH_FINISH command can be
0179 issued to make the guest ready for the execution.
0180
0181 Returns: 0 on success, -negative on error
0182
0183 6. KVM_SEV_GUEST_STATUS
0184 -----------------------
0185
0186 The KVM_SEV_GUEST_STATUS command is used to retrieve status information about a
0187 SEV-enabled guest.
0188
0189 Parameters (out): struct kvm_sev_guest_status
0190
0191 Returns: 0 on success, -negative on error
0192
0193 ::
0194
0195 struct kvm_sev_guest_status {
0196 __u32 handle; /* guest handle */
0197 __u32 policy; /* guest policy */
0198 __u8 state; /* guest state (see enum below) */
0199 };
0200
0201 SEV guest state:
0202
0203 ::
0204
0205 enum {
0206 SEV_STATE_INVALID = 0;
0207 SEV_STATE_LAUNCHING, /* guest is currently being launched */
0208 SEV_STATE_SECRET, /* guest is being launched and ready to accept the ciphertext data */
0209 SEV_STATE_RUNNING, /* guest is fully launched and running */
0210 SEV_STATE_RECEIVING, /* guest is being migrated in from another SEV machine */
0211 SEV_STATE_SENDING /* guest is getting migrated out to another SEV machine */
0212 };
0213
0214 7. KVM_SEV_DBG_DECRYPT
0215 ----------------------
0216
0217 The KVM_SEV_DEBUG_DECRYPT command can be used by the hypervisor to request the
0218 firmware to decrypt the data at the given memory region.
0219
0220 Parameters (in): struct kvm_sev_dbg
0221
0222 Returns: 0 on success, -negative on error
0223
0224 ::
0225
0226 struct kvm_sev_dbg {
0227 __u64 src_uaddr; /* userspace address of data to decrypt */
0228 __u64 dst_uaddr; /* userspace address of destination */
0229 __u32 len; /* length of memory region to decrypt */
0230 };
0231
0232 The command returns an error if the guest policy does not allow debugging.
0233
0234 8. KVM_SEV_DBG_ENCRYPT
0235 ----------------------
0236
0237 The KVM_SEV_DEBUG_ENCRYPT command can be used by the hypervisor to request the
0238 firmware to encrypt the data at the given memory region.
0239
0240 Parameters (in): struct kvm_sev_dbg
0241
0242 Returns: 0 on success, -negative on error
0243
0244 ::
0245
0246 struct kvm_sev_dbg {
0247 __u64 src_uaddr; /* userspace address of data to encrypt */
0248 __u64 dst_uaddr; /* userspace address of destination */
0249 __u32 len; /* length of memory region to encrypt */
0250 };
0251
0252 The command returns an error if the guest policy does not allow debugging.
0253
0254 9. KVM_SEV_LAUNCH_SECRET
0255 ------------------------
0256
0257 The KVM_SEV_LAUNCH_SECRET command can be used by the hypervisor to inject secret
0258 data after the measurement has been validated by the guest owner.
0259
0260 Parameters (in): struct kvm_sev_launch_secret
0261
0262 Returns: 0 on success, -negative on error
0263
0264 ::
0265
0266 struct kvm_sev_launch_secret {
0267 __u64 hdr_uaddr; /* userspace address containing the packet header */
0268 __u32 hdr_len;
0269
0270 __u64 guest_uaddr; /* the guest memory region where the secret should be injected */
0271 __u32 guest_len;
0272
0273 __u64 trans_uaddr; /* the hypervisor memory region which contains the secret */
0274 __u32 trans_len;
0275 };
0276
0277 10. KVM_SEV_GET_ATTESTATION_REPORT
0278 ----------------------------------
0279
0280 The KVM_SEV_GET_ATTESTATION_REPORT command can be used by the hypervisor to query the attestation
0281 report containing the SHA-256 digest of the guest memory and VMSA passed through the KVM_SEV_LAUNCH
0282 commands and signed with the PEK. The digest returned by the command should match the digest
0283 used by the guest owner with the KVM_SEV_LAUNCH_MEASURE.
0284
0285 If len is zero on entry, the measurement blob length is written to len and
0286 uaddr is unused.
0287
0288 Parameters (in): struct kvm_sev_attestation
0289
0290 Returns: 0 on success, -negative on error
0291
0292 ::
0293
0294 struct kvm_sev_attestation_report {
0295 __u8 mnonce[16]; /* A random mnonce that will be placed in the report */
0296
0297 __u64 uaddr; /* userspace address where the report should be copied */
0298 __u32 len;
0299 };
0300
0301 11. KVM_SEV_SEND_START
0302 ----------------------
0303
0304 The KVM_SEV_SEND_START command can be used by the hypervisor to create an
0305 outgoing guest encryption context.
0306
0307 If session_len is zero on entry, the length of the guest session information is
0308 written to session_len and all other fields are not used.
0309
0310 Parameters (in): struct kvm_sev_send_start
0311
0312 Returns: 0 on success, -negative on error
0313
0314 ::
0315
0316 struct kvm_sev_send_start {
0317 __u32 policy; /* guest policy */
0318
0319 __u64 pdh_cert_uaddr; /* platform Diffie-Hellman certificate */
0320 __u32 pdh_cert_len;
0321
0322 __u64 plat_certs_uaddr; /* platform certificate chain */
0323 __u32 plat_certs_len;
0324
0325 __u64 amd_certs_uaddr; /* AMD certificate */
0326 __u32 amd_certs_len;
0327
0328 __u64 session_uaddr; /* Guest session information */
0329 __u32 session_len;
0330 };
0331
0332 12. KVM_SEV_SEND_UPDATE_DATA
0333 ----------------------------
0334
0335 The KVM_SEV_SEND_UPDATE_DATA command can be used by the hypervisor to encrypt the
0336 outgoing guest memory region with the encryption context creating using
0337 KVM_SEV_SEND_START.
0338
0339 If hdr_len or trans_len are zero on entry, the length of the packet header and
0340 transport region are written to hdr_len and trans_len respectively, and all
0341 other fields are not used.
0342
0343 Parameters (in): struct kvm_sev_send_update_data
0344
0345 Returns: 0 on success, -negative on error
0346
0347 ::
0348
0349 struct kvm_sev_launch_send_update_data {
0350 __u64 hdr_uaddr; /* userspace address containing the packet header */
0351 __u32 hdr_len;
0352
0353 __u64 guest_uaddr; /* the source memory region to be encrypted */
0354 __u32 guest_len;
0355
0356 __u64 trans_uaddr; /* the destination memory region */
0357 __u32 trans_len;
0358 };
0359
0360 13. KVM_SEV_SEND_FINISH
0361 ------------------------
0362
0363 After completion of the migration flow, the KVM_SEV_SEND_FINISH command can be
0364 issued by the hypervisor to delete the encryption context.
0365
0366 Returns: 0 on success, -negative on error
0367
0368 14. KVM_SEV_SEND_CANCEL
0369 ------------------------
0370
0371 After completion of SEND_START, but before SEND_FINISH, the source VMM can issue the
0372 SEND_CANCEL command to stop a migration. This is necessary so that a cancelled
0373 migration can restart with a new target later.
0374
0375 Returns: 0 on success, -negative on error
0376
0377 15. KVM_SEV_RECEIVE_START
0378 -------------------------
0379
0380 The KVM_SEV_RECEIVE_START command is used for creating the memory encryption
0381 context for an incoming SEV guest. To create the encryption context, the user must
0382 provide a guest policy, the platform public Diffie-Hellman (PDH) key and session
0383 information.
0384
0385 Parameters: struct kvm_sev_receive_start (in/out)
0386
0387 Returns: 0 on success, -negative on error
0388
0389 ::
0390
0391 struct kvm_sev_receive_start {
0392 __u32 handle; /* if zero then firmware creates a new handle */
0393 __u32 policy; /* guest's policy */
0394
0395 __u64 pdh_uaddr; /* userspace address pointing to the PDH key */
0396 __u32 pdh_len;
0397
0398 __u64 session_uaddr; /* userspace address which points to the guest session information */
0399 __u32 session_len;
0400 };
0401
0402 On success, the 'handle' field contains a new handle and on error, a negative value.
0403
0404 For more details, see SEV spec Section 6.12.
0405
0406 16. KVM_SEV_RECEIVE_UPDATE_DATA
0407 -------------------------------
0408
0409 The KVM_SEV_RECEIVE_UPDATE_DATA command can be used by the hypervisor to copy
0410 the incoming buffers into the guest memory region with encryption context
0411 created during the KVM_SEV_RECEIVE_START.
0412
0413 Parameters (in): struct kvm_sev_receive_update_data
0414
0415 Returns: 0 on success, -negative on error
0416
0417 ::
0418
0419 struct kvm_sev_launch_receive_update_data {
0420 __u64 hdr_uaddr; /* userspace address containing the packet header */
0421 __u32 hdr_len;
0422
0423 __u64 guest_uaddr; /* the destination guest memory region */
0424 __u32 guest_len;
0425
0426 __u64 trans_uaddr; /* the incoming buffer memory region */
0427 __u32 trans_len;
0428 };
0429
0430 17. KVM_SEV_RECEIVE_FINISH
0431 --------------------------
0432
0433 After completion of the migration flow, the KVM_SEV_RECEIVE_FINISH command can be
0434 issued by the hypervisor to make the guest ready for execution.
0435
0436 Returns: 0 on success, -negative on error
0437
0438 References
0439 ==========
0440
0441
0442 See [white-paper]_, [api-spec]_, [amd-apm]_ and [kvm-forum]_ for more info.
0443
0444 .. [white-paper] http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/12/AMD_Memory_Encryption_Whitepaper_v7-Public.pdf
0445 .. [api-spec] https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf
0446 .. [amd-apm] https://support.amd.com/TechDocs/24593.pdf (section 15.34)
0447 .. [kvm-forum] https://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf