From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.120]) by mx.groups.io with SMTP id smtpd.web11.9725.1591792807949671371 for ; Wed, 10 Jun 2020 05:40:08 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=diwG9jpJ; spf=pass (domain: redhat.com, ip: 207.211.31.120, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591792806; 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=XQGayVphmubE3cw2RzTRrr4cw9lsXiCatsP04QX0JUo=; b=diwG9jpJyjNX7dd4IjcwCot812RJuzXVoQsN0dUxvicRD5x4iXX6Fgsb+vs0+0u+YIPpLW NoNHIQnC4H3UUhWxhYYKgu4gxZYt1noIQKNNn3EX8TbwWG7rtsp6M7Pep/C8qVZLRPZU1D Q3IYPp0nfR1Z804it5ii4YFgnOm5bOE= 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-203-MrmJJ848OjGVdemqlIa_VA-1; Wed, 10 Jun 2020 08:39:55 -0400 X-MC-Unique: MrmJJ848OjGVdemqlIa_VA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E20991902ED4; Wed, 10 Jun 2020 12:39:53 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-112-233.ams2.redhat.com [10.36.112.233]) by smtp.corp.redhat.com (Postfix) with ESMTP id 98FD510013C1; Wed, 10 Jun 2020 12:39:51 +0000 (UTC) Subject: Re: [PATCH v9 14/46] OvmfPkg/VmgExitLib: Support string IO for IOIO_PROT NAE events To: Tom Lendacky , devel@edk2.groups.io Cc: Brijesh Singh , Ard Biesheuvel , Eric Dong , Jordan Justen , Liming Gao , Michael D Kinney , Ray Ni References: <8ecf3abbd4a58dfb920b68163680ddfd5b552eac.1591363657.git.thomas.lendacky@amd.com> From: "Laszlo Ersek" Message-ID: <9741ea16-eb4c-b177-3b8f-a54ef69d29cc@redhat.com> Date: Wed, 10 Jun 2020 14:39:50 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <8ecf3abbd4a58dfb920b68163680ddfd5b552eac.1591363657.git.thomas.lendacky@amd.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 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 06/05/20 15:27, Tom Lendacky wrote: > 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 7c2bb12df10a..b74b13045cfd 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); (1) missing space before the opening paren, but we're at v9. So my ACK stands. Thanks 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; >