Create a Documentation entry to describe the AMD Secure Encrypted Virtualization (SEV) feature. Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> Cc: "Radim Krčmář" <rkrcmar@xxxxxxxxxx> Cc: Jonathan Corbet <corbet@xxxxxxx> Cc: Borislav Petkov <bp@xxxxxxx> Cc: Tom Lendacky <thomas.lendacky@xxxxxxx> Cc: kvm@xxxxxxxxxxxxxxx Cc: x86@xxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> --- Documentation/virtual/kvm/00-INDEX | 3 + .../virtual/kvm/amd-memory-encryption.txt | 210 +++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 Documentation/virtual/kvm/amd-memory-encryption.txt diff --git a/Documentation/virtual/kvm/00-INDEX b/Documentation/virtual/kvm/00-INDEX index 69fe1a8b7ad1..3da73aabff5a 100644 --- a/Documentation/virtual/kvm/00-INDEX +++ b/Documentation/virtual/kvm/00-INDEX @@ -26,3 +26,6 @@ s390-diag.txt - Diagnose hypercall description (for IBM S/390) timekeeping.txt - timekeeping virtualization for x86-based architectures. +amd-memory-encryption.txt + - notes on AMD Secure Encrypted Virtualization feature and SEV firmware + command description diff --git a/Documentation/virtual/kvm/amd-memory-encryption.txt b/Documentation/virtual/kvm/amd-memory-encryption.txt new file mode 100644 index 000000000000..5586d51a8983 --- /dev/null +++ b/Documentation/virtual/kvm/amd-memory-encryption.txt @@ -0,0 +1,210 @@ +Secure Encrypted Virtualization (SEV) is a feature found on AMD processors. + +SEV is an extension to the AMD-V architecture which supports running virtual +machines (VMs) under the control of a hypervisor. When enabled, the memory +contents of VM will be transparently encrypted with a key unique to the VM. + +Hypervisor can determine the SEV support through the CPUID instruction. The CPUID +function 0x8000001f reports information related to SEV: + + 0x8000001f[eax]: + Bit[1] indicates support for SEV + + [ecx]: + Bits[31:0] Number of encrypted guest supported simultaneously + +If support for SEV is present, MSR 0xc001_0010 (MSR_K8_SYSCFG) and MSR +0xc001_0015 (MSR_K7_HWCR_SMMLOCK) can be used to determine if it can be enabled: + + 0xc001_0010: + Bit[23] 0 = memory encryption can be enabled + 0 = memory encryption can not be enabled + + 0xc001_0015: + Bit[0] 0 = memory encryption can not be enabled + 1 = memory encryption can be enabled + +When SEV support is available, it can be enabled in specific VM during the VMRUN +instruction by setting SEV bit in VMCB offset 090h: + + VMCB[0x90]: + Bit[1] 1 = Enable SEV + +SEV hardware uses ASIDs to associate a memory encryption key with a VM. Hence +the ASID for the SEV enabled guests must be from 1 to a maximum value defined +in the CPUID function 0x8000001f[ecx] field. + +SEV Key Management +------------------ +The Key management for the SEV guest is handled by a separate processor known as +the AMD Secure Processor (AMD-SP). Firmware running inside the AMD-SP provides a +secure key management interface to perform common hypervisor activities such as +encrypting bootstrap code, snapshot, migrating and debugging the guest. For +more information, see SEV Key Management spec at + +http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf + +KVM implements the following commands to support SEV guests launch, migrate +and save/restore. + +1. KVM_SEV_LAUNCH_START + +Parameters: struct kvm_sev_launch_start (in/out) +Returns: 0 on success, -negative on error + +The KVM_SEV_LAUNCH_START command is used for creation the encryption context. +To create the encryption context, user must provide a guest policy, the owner's +public Diffie-Hellman (PDH) key and session information. + +struct kvm_sev_launch_start { + /* if zero then FW creates a new handle */ + __u32 handle; + + /* guest policy */ + __u32 policy; + + /* userspace address pointing to the guest owner's PDH key */ + __u64 dh_uaddr; + __u32 dh_len; + + /* userspace address which points to the guest session information */ + __u64 session_addr; + __u32 session_len; +}; + +On success, the 'handle' field contain a new handle and on error, a negative value. + +For more details, see SEV spec Section 6.2. + +2. KVM_SEV_LAUNCH_UPDATE_DATA + +Parameters (in): struct kvm_sev_launch_update +Returns: 0 on success, -negative on error + +The KVM_SEV_LAUNCH_UPDATE_DATA is used for encrypting the guest memory regions +with the encryption context created using KVM_SEV_LAUNCH_START. + +struct kvm_sev_launch_update { + /* userspace address need to be encrypted (must be 16-byte aligned) */ + __u64 uaddr; + + /* length of the data to be encrypted (must be 16-byte aligned) */ + __u32 len; +}; + +For more details, see SEV spec Section 6.3. + +3. KVM_SEV_LAUNCH_MEASURE + +Parameters (in): struct kvm_sev_launch_measure +Returns: 0 on success, -negative on error + +The KVM_SEV_LAUNCH_MEASURE command is used to retrieve the measurement of the +memory regions encrypted using KVM_SEV_LAUNCH_UPDATE_DATA. + +struct kvm_sev_launch_measure { + /* where to copy the measurement */ + __u64 uaddr; + + /* length of measurement blob */ + __u32 len; +}; + +For more details on how the measurement can be used for attesation, see SEV +spec Section 6.4. + +4. KVM_SEV_LAUNCH_FINISH + +Returns: 0 on success, -negative on error + +KVM_SEV_LAUNCH_FINISH command finalize the SEV guest launch process. + +5. KVM_SEV_GUEST_STATUS + +Parameters (out): struct kvm_sev_guest_status +Returns: 0 on success, -negative on error + +The KVM_SEV_GUEST_STATUS command is used to retrieve status information about an +SEV-enabled guest.. + +struct kvm_sev_guest_status { + /* guest handle */ + __u32 handle; + + /* guest policy */ + __u32 policy; + + /* guest state (see below) */ + __u8 state; +}; + +SEV guest state: + +enum { + SEV_STATE_INVALID = 0; + SEV_STATE_LAUNCHING, /* guest is currently being launched */ + SEV_STATE_SECRET, /* guest is being launched and ready to accept the ciphertext data */ + SEV_STATE_RUNNING, /* guest is fully launched and running */ + SEV_STATE_RECEIVING, /* guest is being migrated in from another SEV machine */ + SEV_STATE_SENDING /* guest is getting migrated out another SEV machine */ +}; + +6. KVM_SEV_DBG_DECRYPT + +Parameters (in): struct kvm_sev_dbg +Returns: 0 on success, -negative on error + +The KVM_SEV_DEBUG_DECRYPT command is used for decrypting a memory region for the +debug purposes. + +struct kvm_sev_dbg { + /* userspace address of data to decrypt */ + __u64 src_uaddr; + /* userspace address of destination */ + __u64 dst_uaddr; + + /* length of memory region to decrypt */ + __u32 len; +}; + +The command returns an error if guest policy does not allow debugging. + +7. KVM_SEV_DBG_ENCRYPT + +Parameters (in): struct kvm_sev_dbg +Returns: 0 on success, -negative on error + +The KVM_SEV_DEBUG_ENCRYPT command is used for encrypting a plaintext using the +VM encryption key. + +struct kvm_sev_dbg { + /* userspace address of data to encrypt */ + __u64 src_uaddr; + /* userspace address of destination */ + __u64 dst_uaddr; + + /* length of memory region to encrypt */ + __u32 len; +}; + +8. KVM_SEV_LAUNCH_SECRET + +Parameters (in): struct kvm_sev_launch_secret +Returns: 0 on success, -negative on error + +Te KVM_SEV_LAUNCH_SECRET command can be used by hypevisor to inject a secret +into the guest. + +struct kvm_sev_launch_secret { + /* userspace address containing the packet header */ + __u64 hdr_uaddr; + __u32 hdr_len; + + /* the guest memory region where the secret should be injected */ + __u64 guest_uaddr; + __u32 guest_len; + + /* the hypervisor memory region which contains the secret */ + __u64 trans_uaddr; + __u32 trans_len; +}; -- 2.9.5