diff options
| author | Tom Lendacky <thomas.lendacky@amd.com> | 2020-12-10 11:09:49 -0600 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-12-15 05:20:47 -0500 |
| commit | 1edc14599e06fdf23dcf7516f73f09091853eb9a (patch) | |
| tree | 83a0e79c62b9c869942d9bd13cf09afd6b7d866c /arch/x86/kvm/svm/sev.c | |
| parent | 291bd20d5d88814a73d43b55b9428feab2f28094 (diff) | |
KVM: SVM: Add support for SEV-ES GHCB MSR protocol function 0x002
The GHCB specification defines a GHCB MSR protocol using the lower
12-bits of the GHCB MSR (in the hypervisor this corresponds to the
GHCB GPA field in the VMCB).
Function 0x002 is a request to set the GHCB MSR value to the SEV INFO as
per the specification via the VMCB GHCB GPA field.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <c23c163a505290a0d1b9efc4659b838c8c902cbc.1607620209.git.thomas.lendacky@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm/sev.c')
| -rw-r--r-- | arch/x86/kvm/svm/sev.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 0244f4f244b4..2246e4f3e4f3 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -20,6 +20,7 @@ #include "svm.h" #include "cpuid.h" +static u8 sev_enc_bit; static int sev_flush_asids(void); static DECLARE_RWSEM(sev_deactivate_lock); static DEFINE_MUTEX(sev_bitmap_lock); @@ -1140,6 +1141,9 @@ void __init sev_hardware_setup(void) /* Retrieve SEV CPUID information */ cpuid(0x8000001f, &eax, &ebx, &ecx, &edx); + /* Set encryption bit location for SEV-ES guests */ + sev_enc_bit = ebx & 0x3f; + /* Maximum number of encrypted guests supported simultaneously */ max_sev_asid = ecx; @@ -1496,9 +1500,29 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) vmcb_mark_dirty(svm->vmcb, VMCB_ASID); } +static void set_ghcb_msr(struct vcpu_svm *svm, u64 value) +{ + svm->vmcb->control.ghcb_gpa = value; +} + static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) { - return -EINVAL; + struct vmcb_control_area *control = &svm->vmcb->control; + u64 ghcb_info; + + ghcb_info = control->ghcb_gpa & GHCB_MSR_INFO_MASK; + + switch (ghcb_info) { + case GHCB_MSR_SEV_INFO_REQ: + set_ghcb_msr(svm, GHCB_MSR_SEV_INFO(GHCB_VERSION_MAX, + GHCB_VERSION_MIN, + sev_enc_bit)); + break; + default: + return -EINVAL; + } + + return 1; } int sev_handle_vmgexit(struct vcpu_svm *svm) |
