All of lore.kernel.org
 help / color / mirror / Atom feed
From: vsntk18@gmail.com
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com, seanjc@google.com, jroedel@suse.de,
	papaluri@amd.com, zxwang42@gmail.com,
	Vasant Karasulli <vkarasulli@suse.de>,
	Varad Gautam <varad.gautam@suse.com>
Subject: [kvm-unit-tests PATCH v6 08/11] x86: AMD SEV-ES: Handle CPUID #VC
Date: Thu, 11 Apr 2024 19:29:41 +0200	[thread overview]
Message-ID: <20240411172944.23089-9-vsntk18@gmail.com> (raw)
In-Reply-To: <20240411172944.23089-1-vsntk18@gmail.com>

From: Vasant Karasulli <vkarasulli@suse.de>

Using Linux's CPUID #VC processing logic.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
Signed-off-by: Vasant Karasulli <vkarasulli@suse.de>
---
 lib/x86/amd_sev.h    |  5 ++-
 lib/x86/amd_sev_vc.c | 97 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/lib/x86/amd_sev.h b/lib/x86/amd_sev.h
index b6b7a13f..efd439fb 100644
--- a/lib/x86/amd_sev.h
+++ b/lib/x86/amd_sev.h
@@ -71,7 +71,7 @@ struct ghcb {
 	u8 shared_buffer[GHCB_SHARED_BUF_SIZE];

 	u8 reserved_0xff0[10];
-	u16 protocol_version;	/* negotiated SEV-ES/GHCB protocol version */
+	u16 version;	/* version of the GHCB data structure */
 	u32 ghcb_usage;
 } __packed;

@@ -79,6 +79,9 @@ struct ghcb {
 #define GHCB_PROTOCOL_MAX	1ULL
 #define GHCB_DEFAULT_USAGE	0ULL

+/* Version of the GHCB data structure */
+#define GHCB_VERSION		1
+
 #define	VMGEXIT()			{ asm volatile("rep; vmmcall\n\r"); }

 enum es_result {
diff --git a/lib/x86/amd_sev_vc.c b/lib/x86/amd_sev_vc.c
index 30b892f9..3a5e593c 100644
--- a/lib/x86/amd_sev_vc.c
+++ b/lib/x86/amd_sev_vc.c
@@ -8,6 +8,7 @@

 #include "amd_sev.h"
 #include "svm.h"
+#include "x86/xsave.h"

 extern phys_addr_t ghcb_addr;

@@ -58,6 +59,99 @@ static void vc_finish_insn(struct es_em_ctxt *ctxt)
 	ctxt->regs->rip += ctxt->insn.length;
 }

+static inline void sev_es_wr_ghcb_msr(u64 val)
+{
+	wrmsr(MSR_AMD64_SEV_ES_GHCB, val);
+}
+
+static inline u64 sev_es_rd_ghcb_msr(void)
+{
+	return rdmsr(MSR_AMD64_SEV_ES_GHCB);
+}
+
+
+static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
+					  struct es_em_ctxt *ctxt,
+					  u64 exit_code, u64 exit_info_1,
+					  u64 exit_info_2)
+{
+	enum es_result ret;
+
+	/* Fill in protocol and format specifiers */
+	ghcb->version = GHCB_VERSION;
+	ghcb->ghcb_usage       = GHCB_DEFAULT_USAGE;
+
+	ghcb_set_sw_exit_code(ghcb, exit_code);
+	ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
+	ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
+
+	sev_es_wr_ghcb_msr(__pa(ghcb));
+	VMGEXIT();
+
+	if ((ghcb->save.sw_exit_info_1 & 0xffffffff) == 1) {
+		u64 info = ghcb->save.sw_exit_info_2;
+		unsigned long v;
+
+		v = info & SVM_EVTINJ_VEC_MASK;
+
+		/* Check if exception information from hypervisor is sane. */
+		if ((info & SVM_EVTINJ_VALID) &&
+		    ((v == GP_VECTOR) || (v == UD_VECTOR)) &&
+		    ((info & SVM_EVTINJ_TYPE_MASK) == SVM_EVTINJ_TYPE_EXEPT)) {
+			ctxt->fi.vector = v;
+			if (info & SVM_EVTINJ_VALID_ERR)
+				ctxt->fi.error_code = info >> 32;
+			ret = ES_EXCEPTION;
+		} else {
+			ret = ES_VMM_ERROR;
+		}
+	} else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
+		ret = ES_VMM_ERROR;
+	} else {
+		ret = ES_OK;
+	}
+
+	return ret;
+}
+
+static enum es_result vc_handle_cpuid(struct ghcb *ghcb,
+				      struct es_em_ctxt *ctxt)
+{
+	struct ex_regs *regs = ctxt->regs;
+	u32 cr4 = read_cr4();
+	enum es_result ret;
+
+	ghcb_set_rax(ghcb, regs->rax);
+	ghcb_set_rcx(ghcb, regs->rcx);
+
+	if (cr4 & X86_CR4_OSXSAVE) {
+		/* Safe to read xcr0 */
+		u64 xcr0;
+		xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0);
+		ghcb_set_xcr0(ghcb, xcr0);
+	} else {
+		/* xgetbv will cause #GP - use reset value for xcr0 */
+		ghcb_set_xcr0(ghcb, 1);
+	}
+
+	ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0);
+	if (ret != ES_OK)
+		return ret;
+
+	if (!(ghcb_rax_is_valid(ghcb) &&
+	      ghcb_rbx_is_valid(ghcb) &&
+	      ghcb_rcx_is_valid(ghcb) &&
+	      ghcb_rdx_is_valid(ghcb)))
+		return ES_VMM_ERROR;
+
+	regs->rax = ghcb->save.rax;
+	regs->rbx = ghcb->save.rbx;
+	regs->rcx = ghcb->save.rcx;
+	regs->rdx = ghcb->save.rdx;
+
+	return ES_OK;
+}
+
 static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt,
 					 struct ghcb *ghcb,
 					 unsigned long exit_code)
@@ -65,6 +159,9 @@ static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt,
 	enum es_result result;

 	switch (exit_code) {
+	case SVM_EXIT_CPUID:
+		result = vc_handle_cpuid(ghcb, ctxt);
+		break;
 	default:
 		/*
 		 * Unexpected #VC exception
--
2.34.1


  parent reply	other threads:[~2024-04-11 17:30 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-11 17:29 [PATCH v6 00/11] Add #VC exception handling for AMD SEV-ES vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 01/11] x86: AMD SEV-ES: Setup #VC exception handler " vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 02/11] x86: Move svm.h to lib/x86/ vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 03/11] lib: Define unlikely()/likely() macros in libcflat.h vsntk18
2024-04-12  6:31   ` Andrew Jones
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 04/11] lib: x86: Import insn decoder from Linux vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 05/11] x86: AMD SEV-ES: Pull related GHCB definitions and helpers " vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 06/11] x86: AMD SEV-ES: Prepare for #VC processing vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 07/11] lib/x86: Move xsave helpers to lib/ vsntk18
2024-04-11 17:29 ` vsntk18 [this message]
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 09/11] x86: AMD SEV-ES: Handle MSR #VC vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 10/11] x86: AMD SEV-ES: Handle IOIO #VC vsntk18
2024-04-11 17:29 ` [kvm-unit-tests PATCH v6 11/11] x86: AMD SEV-ES: Handle string IO for " vsntk18

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240411172944.23089-9-vsntk18@gmail.com \
    --to=vsntk18@gmail.com \
    --cc=jroedel@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=papaluri@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=varad.gautam@suse.com \
    --cc=vkarasulli@suse.de \
    --cc=zxwang42@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.