Back to home page

OSCL-LXR

 
 

    


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