All of lore.kernel.org
 help / color / mirror / Atom feed
From: Varad Gautam <varad.gautam@suse.com>
To: kvm@vger.kernel.org, pbonzini@redhat.com, drjones@redhat.com
Cc: marcorr@google.com, zxwang42@gmail.com, erdemaktas@google.com,
	rientjes@google.com, seanjc@google.com, brijesh.singh@amd.com,
	Thomas.Lendacky@amd.com, jroedel@suse.de, bp@suse.de,
	varad.gautam@suse.com
Subject: [kvm-unit-tests 13/13] x86: AMD SEV-ES: Handle string IO for IOIO #VC
Date: Thu, 20 Jan 2022 13:51:22 +0100	[thread overview]
Message-ID: <20220120125122.4633-14-varad.gautam@suse.com> (raw)
In-Reply-To: <20220120125122.4633-1-varad.gautam@suse.com>

Using Linux's IOIO #VC processing logic.

Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
 lib/x86/amd_sev_vc.c | 108 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 2 deletions(-)

diff --git a/lib/x86/amd_sev_vc.c b/lib/x86/amd_sev_vc.c
index bb912e4..24db992 100644
--- a/lib/x86/amd_sev_vc.c
+++ b/lib/x86/amd_sev_vc.c
@@ -307,10 +307,46 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo)
 	return ES_OK;
 }
 
+static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt,
+					  void *src, unsigned char *buf,
+					  unsigned int data_size,
+					  unsigned int count,
+					  bool backwards)
+{
+	int i, b = backwards ? -1 : 1;
+
+	for (i = 0; i < count; i++) {
+		void *s = src + (i * data_size * b);
+		unsigned char *d = buf + (i * data_size);
+
+		memcpy(d, s, data_size);
+	}
+
+	return ES_OK;
+}
+
+static enum es_result vc_insn_string_write(struct es_em_ctxt *ctxt,
+					   void *dst, unsigned char *buf,
+					   unsigned int data_size,
+					   unsigned int count,
+					   bool backwards)
+{
+	int i, s = backwards ? -1 : 1;
+
+	for (i = 0; i < count; i++) {
+		void *d = dst + (i * data_size * s);
+		unsigned char *b = buf + (i * data_size);
+
+		memcpy(d, b, data_size);
+	}
+
+	return ES_OK;
+}
+
 static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
 {
 	struct ex_regs *regs = ctxt->regs;
-	u64 exit_info_1;
+	u64 exit_info_1, exit_info_2;
 	enum es_result ret;
 
 	ret = vc_ioio_exitinfo(ctxt, &exit_info_1);
@@ -318,7 +354,75 @@ static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
 		return ret;
 
 	if (exit_info_1 & IOIO_TYPE_STR) {
-		ret = ES_VMM_ERROR;
+		/* (REP) INS/OUTS */
+
+		bool df = ((regs->rflags & X86_EFLAGS_DF) == X86_EFLAGS_DF);
+		unsigned int io_bytes, exit_bytes;
+		unsigned int ghcb_count, op_count;
+		unsigned long es_base;
+		u64 sw_scratch;
+
+		/*
+		 * For the string variants with rep prefix the amount of in/out
+		 * operations per #VC exception is limited so that the kernel
+		 * has a chance to take interrupts and re-schedule while the
+		 * instruction is emulated.
+		 */
+		io_bytes   = (exit_info_1 >> 4) & 0x7;
+		ghcb_count = sizeof(ghcb->shared_buffer) / io_bytes;
+
+		op_count    = (exit_info_1 & IOIO_REP) ? regs->rcx : 1;
+		exit_info_2 = op_count < ghcb_count ? op_count : ghcb_count;
+		exit_bytes  = exit_info_2 * io_bytes;
+
+		es_base = 0;
+
+		/* Read bytes of OUTS into the shared buffer */
+		if (!(exit_info_1 & IOIO_TYPE_IN)) {
+			ret = vc_insn_string_read(ctxt,
+					       (void *)(es_base + regs->rsi),
+					       ghcb->shared_buffer, io_bytes,
+					       exit_info_2, df);
+			if (ret)
+				return ret;
+		}
+
+		/*
+		 * Issue an VMGEXIT to the HV to consume the bytes from the
+		 * shared buffer or to have it write them into the shared buffer
+		 * depending on the instruction: OUTS or INS.
+		 */
+		sw_scratch = __pa(ghcb) + offsetof(struct ghcb, shared_buffer);
+		ghcb_set_sw_scratch(ghcb, sw_scratch);
+		ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_IOIO,
+					  exit_info_1, exit_info_2);
+		if (ret != ES_OK)
+			return ret;
+
+		/* Read bytes from shared buffer into the guest's destination. */
+		if (exit_info_1 & IOIO_TYPE_IN) {
+			ret = vc_insn_string_write(ctxt,
+						   (void *)(es_base + regs->rdi),
+						   ghcb->shared_buffer, io_bytes,
+						   exit_info_2, df);
+			if (ret)
+				return ret;
+
+			if (df)
+				regs->rdi -= exit_bytes;
+			else
+				regs->rdi += exit_bytes;
+		} else {
+			if (df)
+				regs->rsi -= exit_bytes;
+			else
+				regs->rsi += exit_bytes;
+		}
+
+		if (exit_info_1 & IOIO_REP)
+			regs->rcx -= exit_info_2;
+
+		ret = regs->rcx ? ES_RETRY : ES_OK;
 	} else {
 		/* IN/OUT into/from rAX */
 
-- 
2.32.0


      parent reply	other threads:[~2022-01-20 12:52 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-20 12:51 [kvm-unit-tests 00/13] Add #VC exception handling for AMD SEV-ES Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 01/13] x86/efi: Allow specifying AMD SEV/SEV-ES guest launch policy Varad Gautam
2022-01-20 16:18   ` Tom Lendacky
2022-01-30 20:04   ` Marc Orr
2022-01-20 12:51 ` [kvm-unit-tests 02/13] x86: AMD SEV-ES: Setup #VC exception handler for AMD SEV-ES Varad Gautam
2022-01-30 20:36   ` Marc Orr
2022-02-04 10:55     ` Joerg Roedel
2022-02-04 15:57       ` Marc Orr
2022-02-04 16:30         ` Sean Christopherson
2022-02-04 20:09           ` Marc Orr
2022-02-07 21:11             ` Sean Christopherson
2022-02-08  1:58               ` Marc Orr
2022-02-04 17:15         ` Joerg Roedel
2022-02-04 20:12           ` Marc Orr
2022-01-20 12:51 ` [kvm-unit-tests 03/13] x86: Move svm.h to lib/x86/ Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 04/13] lib: x86: Import insn decoder from Linux Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 05/13] x86: AMD SEV-ES: Pull related GHCB definitions and helpers " Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 06/13] x86: AMD SEV-ES: Prepare for #VC processing Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 07/13] x86: AMD SEV-ES: Handle WBINVD #VC Varad Gautam
2022-02-07 21:13   ` Sean Christopherson
2022-01-20 12:51 ` [kvm-unit-tests 08/13] lib/x86: Move xsave helpers to lib/ Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 09/13] x86: AMD SEV-ES: Handle CPUID #VC Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 10/13] x86: AMD SEV-ES: Handle RDTSC/RDTSCP #VC Varad Gautam
2022-02-07 21:17   ` Sean Christopherson
2022-01-20 12:51 ` [kvm-unit-tests 11/13] x86: AMD SEV-ES: Handle MSR #VC Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 12/13] x86: AMD SEV-ES: Handle IOIO #VC Varad Gautam
2022-01-20 12:51 ` Varad Gautam [this message]

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=20220120125122.4633-14-varad.gautam@suse.com \
    --to=varad.gautam@suse.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=bp@suse.de \
    --cc=brijesh.singh@amd.com \
    --cc=drjones@redhat.com \
    --cc=erdemaktas@google.com \
    --cc=jroedel@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=marcorr@google.com \
    --cc=pbonzini@redhat.com \
    --cc=rientjes@google.com \
    --cc=seanjc@google.com \
    --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.