+ IsString = ((ExitInfo1 & IOIO_TYPE_STR) != 0) ? TRUE : FALSE;\r
+ if (IsString) {\r
+ UINTN IoBytes, VmgExitBytes;\r
+ UINTN GhcbCount, OpCount;\r
+\r
+ Status = 0;\r
+\r
+ IoBytes = IOIO_DATA_BYTES (ExitInfo1);\r
+ GhcbCount = sizeof (Ghcb->SharedBuffer) / IoBytes;\r
+\r
+ OpCount = ((ExitInfo1 & IOIO_REP) != 0) ? Regs->Rcx : 1;\r
+ while (OpCount != 0) {\r
+ ExitInfo2 = MIN (OpCount, GhcbCount);\r
+ VmgExitBytes = ExitInfo2 * IoBytes;\r
+\r
+ if ((ExitInfo1 & IOIO_TYPE_IN) == 0) {\r
+ CopyMem (Ghcb->SharedBuffer, (VOID *) Regs->Rsi, VmgExitBytes);\r
+ Regs->Rsi += VmgExitBytes;\r
+ }\r
+\r
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;\r
+ Status = VmgExit (Ghcb, SVM_EXIT_IOIO_PROT, ExitInfo1, ExitInfo2);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+\r
+ if ((ExitInfo1 & IOIO_TYPE_IN) != 0) {\r
+ CopyMem ((VOID *) Regs->Rdi, Ghcb->SharedBuffer, VmgExitBytes);\r
+ Regs->Rdi += VmgExitBytes;\r
+ }\r
+\r
+ if ((ExitInfo1 & IOIO_REP) != 0) {\r
+ Regs->Rcx -= ExitInfo2;\r
+ }\r
+\r
+ OpCount -= ExitInfo2;\r
+ }\r