Commit 1edc1459 authored by Tom Lendacky's avatar Tom Lendacky Committed by Paolo Bonzini
Browse files

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: default avatarTom Lendacky <thomas.lendacky@amd.com>
Message-Id: <c23c163a505290a0d1b9efc4659b838c8c902cbc.1607620209.git.thomas.lendacky@amd.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 291bd20d
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -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,11 +1500,31 @@ 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)
{
	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)
{
	struct vmcb_control_area *control = &svm->vmcb->control;
+17 −0
Original line number Diff line number Diff line
@@ -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)