mirror of https://github.com/acidanthera/audk.git
OvfmPkg/VmgExitLib: Properly decode MMIO MOVZX and MOVSX opcodes
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3345
The MOVZX and MOVSX instructions use the ModRM byte in the instruction,
but the instruction decoding support was not decoding it. This resulted
in invalid decoding and failing of the MMIO operation. Also, when
performing the zero-extend or sign-extend operation, the memory operation
should be using the size, and not the size enumeration value.
Add the ModRM byte decoding for the MOVZX and MOVSX opcodes and use the
true data size to perform the extend operations. Additionally, add a
DEBUG statement identifying the MMIO address being flagged as encrypted
during the MMIO address validation.
Fixes: c45f678a1e
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Min Xu <min.m.xu@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Message-Id: <5949d54cb2c9ab69256f67ed5654b32654c0501c.1619716333.git.thomas.lendacky@amd.com>
This commit is contained in:
parent
ab957f036f
commit
75d1a7903d
|
@ -643,6 +643,9 @@ ValidateMmioMemory (
|
||||||
//
|
//
|
||||||
// Any state other than unencrypted is an error, issue a #GP.
|
// Any state other than unencrypted is an error, issue a #GP.
|
||||||
//
|
//
|
||||||
|
DEBUG ((DEBUG_ERROR,
|
||||||
|
"MMIO using encrypted memory: %lx\n",
|
||||||
|
(UINT64) MemoryAddress));
|
||||||
GpEvent.Uint64 = 0;
|
GpEvent.Uint64 = 0;
|
||||||
GpEvent.Elements.Vector = GP_EXCEPTION;
|
GpEvent.Elements.Vector = GP_EXCEPTION;
|
||||||
GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
|
GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
|
||||||
|
@ -817,6 +820,7 @@ MmioExit (
|
||||||
// fall through
|
// fall through
|
||||||
//
|
//
|
||||||
case 0xB7:
|
case 0xB7:
|
||||||
|
DecodeModRm (Regs, InstructionData);
|
||||||
Bytes = (Bytes != 0) ? Bytes : 2;
|
Bytes = (Bytes != 0) ? Bytes : 2;
|
||||||
|
|
||||||
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
@ -835,7 +839,7 @@ MmioExit (
|
||||||
}
|
}
|
||||||
|
|
||||||
Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
|
Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
|
||||||
SetMem (Register, InstructionData->DataSize, 0);
|
SetMem (Register, (UINTN) (1 << InstructionData->DataSize), 0);
|
||||||
CopyMem (Register, Ghcb->SharedBuffer, Bytes);
|
CopyMem (Register, Ghcb->SharedBuffer, Bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -848,6 +852,7 @@ MmioExit (
|
||||||
// fall through
|
// fall through
|
||||||
//
|
//
|
||||||
case 0xBF:
|
case 0xBF:
|
||||||
|
DecodeModRm (Regs, InstructionData);
|
||||||
Bytes = (Bytes != 0) ? Bytes : 2;
|
Bytes = (Bytes != 0) ? Bytes : 2;
|
||||||
|
|
||||||
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
@ -878,7 +883,7 @@ MmioExit (
|
||||||
}
|
}
|
||||||
|
|
||||||
Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
|
Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg);
|
||||||
SetMem (Register, InstructionData->DataSize, SignByte);
|
SetMem (Register, (UINTN) (1 << InstructionData->DataSize), SignByte);
|
||||||
CopyMem (Register, Ghcb->SharedBuffer, Bytes);
|
CopyMem (Register, Ghcb->SharedBuffer, Bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue