[edk2-devel] [PATCH v5 12/42] UefiCpuPkg/CpuExceptionHandler: Support string IO for IOIO_PROT NAE events

Lendacky, Thomas thomas.lendacky at amd.com
Mon Mar 2 23:06:43 UTC 2020


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: Eric Dong <eric.dong at intel.com>
Cc: Ray Ni <ray.ni at intel.com>
Cc: Laszlo Ersek <lersek at redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky at amd.com>
---
 .../X64/ArchAMDSevVcHandler.c                 | 78 ++++++++++++++++---
 1 file changed, 68 insertions(+), 10 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index eb7b776859c1..28adf0d5e9c4 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -321,6 +321,22 @@ IoioExitInfo (
   UINT64  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
   case 0xE4:
   case 0xE5:
@@ -358,6 +374,8 @@ IoioExitInfo (
   }
 
   switch (*(InstructionData->OpCodes)) {
+  case 0x6C:
+  case 0x6E:
   case 0xE4:
   case 0xE6:
   case 0xEC:
@@ -404,7 +422,8 @@ IoioExit (
   SEV_ES_INSTRUCTION_DATA  *InstructionData
   )
 {
-  UINT64  ExitInfo1, Status;
+  UINT64   ExitInfo1, ExitInfo2, Status;
+  BOOLEAN  String;
 
   ExitInfo1 = IoioExitInfo (Regs, InstructionData);
   if (!ExitInfo1) {
@@ -421,16 +440,55 @@ IoioExit (
   Ghcb->SaveArea.Rax = Regs->Rax;
   GhcbSetRegValid (Ghcb, GhcbRax);
 
-  Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
-  if (Status) {
-    return Status;
-  }
-
-  if (ExitInfo1 & IOIO_TYPE_IN) {
-    if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
-      return UnsupportedExit (Ghcb, Regs, InstructionData);
+  String = (ExitInfo1 & IOIO_TYPE_STR) ? TRUE : FALSE;
+  if (String) {
+    UINTN  IoBytes, VmgExitBytes;
+    UINTN  GhcbCount, OpCount;
+
+    Status = 0;
+
+    IoBytes = (ExitInfo1 >> 4) & 0x7;
+    GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;
+
+    OpCount = (ExitInfo1 & IOIO_REP) ? Regs->Rcx : 1;
+    while (OpCount) {
+      ExitInfo2 = MIN (OpCount, GhcbCount);
+      VmgExitBytes = ExitInfo2 * IoBytes;
+
+      if (!(ExitInfo1 & IOIO_TYPE_IN)) {
+        CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes);
+        Regs->Rsi += VmgExitBytes;
+      }
+
+      Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;
+      Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, ExitInfo2);
+      if (Status) {
+        return Status;
+      }
+
+      if (ExitInfo1 & IOIO_TYPE_IN) {
+        CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);
+        Regs->Rdi += VmgExitBytes;
+      }
+
+      if (ExitInfo1 & IOIO_REP) {
+        Regs->Rcx -= ExitInfo2;
+      }
+
+      OpCount -= ExitInfo2;
+    }
+  } else {
+    Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
+    if (Status) {
+      return Status;
+    }
+
+    if (ExitInfo1 & IOIO_TYPE_IN) {
+      if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
+        return UnsupportedExit (Ghcb, Regs, InstructionData);
+      }
+      Regs->Rax = Ghcb->SaveArea.Rax;
     }
-    Regs->Rax = Ghcb->SaveArea.Rax;
   }
 
   return 0;
-- 
2.17.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#55252): https://edk2.groups.io/g/devel/message/55252
Mute This Topic: https://groups.io/mt/71687803/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list