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@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
---
.../X64/ArchAMDSevVcHandler.c | 86 ++++++++++++++++---
1 file changed, 72 insertions(+), 14 deletions(-)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
index 588f2af572e1..5fade675ad84 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchAMDSevVcHandler.c
@@ -446,6 +446,22 @@ 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
case 0xE4:
case 0xE5:
@@ -483,6 +499,8 @@ IoioExitInfo (
}
switch (*(InstructionData->OpCodes)) {
+ case 0x6C:
+ case 0x6E:
case 0xE4:
case 0xE6:
case 0xEC:
@@ -543,30 +561,70 @@ IoioExit (
IN SEV_ES_INSTRUCTION_DATA *InstructionData
)
{
- UINT64 ExitInfo1, Status;
+ UINT64 ExitInfo1, ExitInfo2, Status;
+ BOOLEAN String;
ExitInfo1 = IoioExitInfo (Regs, InstructionData);
if (!ExitInfo1) {
return UnsupportedExit (Ghcb, Regs, InstructionData);
}
- if (ExitInfo1 & IOIO_TYPE_IN) {
- Ghcb->SaveArea.Rax = 0;
+ 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 {
- CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
- }
- GhcbSetRegValid (Ghcb, GhcbRax);
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ Ghcb->SaveArea.Rax = 0;
+ } else {
+ CopyMem (&Ghcb->SaveArea.Rax, &Regs->Rax, IOIO_DATA_BYTES (ExitInfo1));
+ }
+ GhcbSetRegValid (Ghcb, GhcbRax);
- Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
- if (Status) {
- return Status;
- }
+ Status = VmgExit (Ghcb, SvmExitIoioProt, ExitInfo1, 0);
+ if (Status) {
+ return Status;
+ }
- if (ExitInfo1 & IOIO_TYPE_IN) {
- if (!GhcbIsRegValid (Ghcb, GhcbRax)) {
- return UnsupportedExit (Ghcb, Regs, InstructionData);
+ if (ExitInfo1 & IOIO_TYPE_IN) {
+ 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;
--
2.17.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#57844): https://edk2.groups.io/g/devel/message/57844
Mute This Topic: https://groups.io/mt/73201902/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-