Skip to content

Commit

Permalink
KVM: SVM: Add support for SEV-ES GHCB MSR protocol function 0x002
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tom Lendacky authored and Paolo Bonzini committed Dec 15, 2020
1 parent 291bd20 commit 1edc145
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
26 changes: 25 additions & 1 deletion arch/x86/kvm/svm/sev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions arch/x86/kvm/svm/svm.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,9 +514,26 @@ void svm_vcpu_unblocking(struct kvm_vcpu *vcpu);

/* sev.c */

#define GHCB_VERSION_MAX 1ULL
#define GHCB_VERSION_MIN 1ULL

#define GHCB_MSR_INFO_POS 0
#define GHCB_MSR_INFO_MASK (BIT_ULL(12) - 1)

#define GHCB_MSR_SEV_INFO_RESP 0x001
#define GHCB_MSR_SEV_INFO_REQ 0x002
#define GHCB_MSR_VER_MAX_POS 48
#define GHCB_MSR_VER_MAX_MASK 0xffff
#define GHCB_MSR_VER_MIN_POS 32
#define GHCB_MSR_VER_MIN_MASK 0xffff
#define GHCB_MSR_CBIT_POS 24
#define GHCB_MSR_CBIT_MASK 0xff
#define GHCB_MSR_SEV_INFO(_max, _min, _cbit) \
((((_max) & GHCB_MSR_VER_MAX_MASK) << GHCB_MSR_VER_MAX_POS) | \
(((_min) & GHCB_MSR_VER_MIN_MASK) << GHCB_MSR_VER_MIN_POS) | \
(((_cbit) & GHCB_MSR_CBIT_MASK) << GHCB_MSR_CBIT_POS) | \
GHCB_MSR_SEV_INFO_RESP)

extern unsigned int max_sev_asid;

static inline bool svm_sev_enabled(void)
Expand Down

0 comments on commit 1edc145

Please sign in to comment.