From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.61]) by mx.groups.io with SMTP id smtpd.web10.53.1594829435607505030 for ; Wed, 15 Jul 2020 09:10:35 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=dUNOZ9iz; spf=pass (domain: redhat.com, ip: 205.139.110.61, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1594829434; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ra737qrMVJ1hbVrUyy2xAhvfkz8Odax6JSiaQpTQ/ys=; b=dUNOZ9izNdo1b5cb6133uNkj5HU3mEpT6skhc1Pibn6y0mGuNguIWpSIv8E7psfkbHdcE9 fsTibrWBkOqz6Bd58K0hX4BacN/TjbhsG7mT6w51YRnEpPNGIW8QNszHPM1Vpm1czL9BTD Cosswgi4XCwQngMJweTJLWXKJfFgjAg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-172-_RjdapIIOC6kimEigFUiUg-1; Wed, 15 Jul 2020 12:09:51 -0400 X-MC-Unique: _RjdapIIOC6kimEigFUiUg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CC2051080; Wed, 15 Jul 2020 16:09:49 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-114-3.ams2.redhat.com [10.36.114.3]) by smtp.corp.redhat.com (Postfix) with ESMTP id C56162B6DC; Wed, 15 Jul 2020 16:09:47 +0000 (UTC) Subject: Re: [edk2-devel] [PATCH v10 14/46] OvmfPkg/VmgExitLib: Support string IO for IOIO_PROT NAE events To: devel@edk2.groups.io, thomas.lendacky@amd.com Cc: Brijesh Singh , Ard Biesheuvel , Eric Dong , Jordan Justen , Liming Gao , Michael D Kinney , Ray Ni References: <60a44c3029fcbe2f7f8ee329147130ab8be2357c.1594736896.git.thomas.lendacky@amd.com> From: "Laszlo Ersek" Message-ID: <1afe78c1-9d7a-4cc5-c3cf-362b50c064e0@redhat.com> Date: Wed, 15 Jul 2020 18:09:46 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <60a44c3029fcbe2f7f8ee329147130ab8be2357c.1594736896.git.thomas.lendacky@amd.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 07/14/20 16:27, Lendacky, Thomas wrote: > From: Tom Lendacky > > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198 > > Add support to the #VC exception handler to handle string IO. This > requires expanding the IO instruction parsing to recognize string based > IO instructions as well as preparing an un-encrypted buffer to be used > to transfer (either to or from the guest) the string contents for the IO > operation. The SW_EXITINFO2 and SW_SCRATCH fields of the GHCB are set > appropriately for the operation. Multiple VMGEXIT invocations may be > needed to complete the string IO operation. > > Cc: Jordan Justen > Cc: Laszlo Ersek > Cc: Ard Biesheuvel > Acked-by: Laszlo Ersek > Signed-off-by: Tom Lendacky > --- > OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 90 ++++++++++++++++--- > 1 file changed, 76 insertions(+), 14 deletions(-) > > diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c > index 04e8b8aebf7d..b6ac3552894f 100644 > --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c > +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c > @@ -397,6 +397,26 @@ IoioExitInfo ( > ExitInfo = 0; > > switch (*(InstructionData->OpCodes)) { > + // > + // INS opcodes > + // > + case 0x6C: > + case 0x6D: > + ExitInfo |= IOIO_TYPE_INS; > + ExitInfo |= IOIO_SEG_ES; > + ExitInfo |= ((Regs->Rdx & 0xffff) << 16); > + break; > + > + // > + // OUTS opcodes > + // > + case 0x6E: > + case 0x6F: > + ExitInfo |= IOIO_TYPE_OUTS; > + ExitInfo |= IOIO_SEG_DS; > + ExitInfo |= ((Regs->Rdx & 0xffff) << 16); > + break; > + > // > // IN immediate opcodes > // > @@ -445,6 +465,8 @@ IoioExitInfo ( > // > // Single-byte opcodes > // > + case 0x6C: > + case 0x6E: > case 0xE4: > case 0xE6: > case 0xEC: > @@ -506,30 +528,70 @@ IoioExit ( > IN SEV_ES_INSTRUCTION_DATA *InstructionData > ) > { > - UINT64 ExitInfo1, Status; > + UINT64 ExitInfo1, ExitInfo2, Status; > + BOOLEAN IsString; > > ExitInfo1 = IoioExitInfo (Regs, InstructionData); > if (ExitInfo1 == 0) { > return UnsupportedExit (Ghcb, Regs, InstructionData); > } > > - if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { > - Ghcb->SaveArea.Rax = 0; > + IsString = ((ExitInfo1 & IOIO_TYPE_STR) != 0) ? TRUE : FALSE; > + if (IsString) { > + UINTN IoBytes, VmgExitBytes; > + UINTN GhcbCount, OpCount; > + > + Status = 0; > + > + IoBytes = IOIO_DATA_BYTES (ExitInfo1); Thanks for fixing the whitespace! Laszlo > + GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes; > + > + OpCount = ((ExitInfo1 & IOIO_REP) != 0) ? Regs->Rcx : 1; > + while (OpCount) { > + ExitInfo2 = MIN (OpCount, GhcbCount); > + VmgExitBytes = ExitInfo2 * IoBytes; > + > + if ((ExitInfo1 & IOIO_TYPE_IN) == 0) { > + CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes); > + Regs->Rsi += VmgExitBytes; > + } > + > + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; > + Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, ExitInfo2); > + if (Status != 0) { > + return Status; > + } > + > + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { > + CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes); > + Regs->Rdi += VmgExitBytes; > + } > + > + if ((ExitInfo1 & IOIO_REP) != 0) { > + Regs->Rcx -= ExitInfo2; > + } > + > + OpCount -= ExitInfo2; > + } > } else { > - CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1)); > - } > - GhcbSetRegValid (Ghcb, GhcbRax); > + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { > + Ghcb->SaveArea.Rax = 0; > + } else { > + CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1)); > + } > + GhcbSetRegValid (Ghcb, GhcbRax); > > - Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0); > - if (Status != 0) { > - return Status; > - } > + Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, 0); > + if (Status != 0) { > + return Status; > + } > > - if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { > - if (!GhcbIsRegValid (Ghcb, GhcbRax)) { > - return UnsupportedExit (Ghcb, Regs, InstructionData); > + if ((ExitInfo1 & IOIO_TYPE_IN) != 0) { > + if (!GhcbIsRegValid (Ghcb, GhcbRax)) { > + return UnsupportedExit (Ghcb, Regs, InstructionData); > + } > + CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1)); > } > - CopyMem (&Regs->Rax, &Ghcb->SaveArea.Rax, IOIO_DATA_BYTES (ExitInfo1)); > } > > return 0; >