From: vsntk18@gmail.com
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com, seanjc@google.com, jroedel@suse.de,
papaluri@amd.com, andrew.jones@linux.dev,
Vasant Karasulli <vkarasulli@suse.de>,
Varad Gautam <varad.gautam@suse.com>,
Marc Orr <marcorr@google.com>
Subject: [kvm-unit-tests PATCH v7 11/11] x86: AMD SEV-ES: Handle string IO for IOIO #VC
Date: Fri, 19 Apr 2024 18:16:23 +0200 [thread overview]
Message-ID: <20240419161623.45842-12-vsntk18@gmail.com> (raw)
In-Reply-To: <20240419161623.45842-1-vsntk18@gmail.com>
From: Vasant Karasulli <vkarasulli@suse.de>
Using Linux's IOIO #VC processing logic.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
Signed-off-by: Vasant Karasulli <vkarasulli@suse.de>
Reviewed-by: Marc Orr <marcorr@google.com>
Tested-by: Marc Orr <marcorr@google.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 2a553db1..aca549b3 100644
--- a/lib/x86/amd_sev_vc.c
+++ b/lib/x86/amd_sev_vc.c
@@ -306,10 +306,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);
@@ -317,7 +353,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.34.1
prev parent reply other threads:[~2024-04-19 16:16 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-19 16:16 [kvm-unit-tests PATCH v7 00/11] Add #VC exception handling for AMD SEV-ES vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 01/11] x86: AMD SEV-ES: Setup #VC exception handler " vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 02/11] x86: Move svm.h to lib/x86/ vsntk18
2024-06-05 16:05 ` Sean Christopherson
2024-06-06 18:57 ` Vasant Karasulli
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 03/11] lib: Define unlikely()/likely() macros in compiler.h vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 04/11] lib: x86: Import insn decoder from Linux vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 05/11] x86: AMD SEV-ES: Pull related GHCB definitions and helpers " vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 06/11] x86: AMD SEV-ES: Prepare for #VC processing vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 07/11] lib/x86: Move xsave helpers to lib/ vsntk18
2024-06-05 16:04 ` Sean Christopherson
2024-06-06 18:58 ` Vasant Karasulli
2024-06-06 23:49 ` Sean Christopherson
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 08/11] x86: AMD SEV-ES: Handle CPUID #VC vsntk18
2024-06-05 16:07 ` Sean Christopherson
2024-06-06 18:59 ` Vasant Karasulli
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 09/11] x86: AMD SEV-ES: Handle MSR #VC vsntk18
2024-04-19 16:16 ` [kvm-unit-tests PATCH v7 10/11] x86: AMD SEV-ES: Handle IOIO #VC vsntk18
2024-06-05 16:08 ` Sean Christopherson
2024-06-06 19:01 ` Vasant Karasulli
2024-04-19 16:16 ` vsntk18 [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=20240419161623.45842-12-vsntk18@gmail.com \
--to=vsntk18@gmail.com \
--cc=andrew.jones@linux.dev \
--cc=jroedel@suse.de \
--cc=kvm@vger.kernel.org \
--cc=marcorr@google.com \
--cc=papaluri@amd.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=varad.gautam@suse.com \
--cc=vkarasulli@suse.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox