From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com []) by mx.groups.io with SMTP id smtpd.web10.921.1589925107171473827 for ; Tue, 19 May 2020 14:51:48 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=RTY3R2Av; spf=none, err=SPF record not found (domain: amd.com, ip: , mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=PqmBxhZhfstiwsbJCmyJ1fTOx3uIJYRfY9+m3inxp/Fe3wgdYRTqJ51S2icdWHuqNt9JaG0ZSDCl7msL5fKoGXssRX4QnMBKS++LDGukUks5GS7A3I2jm2EzvHCMUb8pupca6lB4KxsNakGA+sKAbPJ1KoGVMzC1vyOpzSGec5lvIp35G+BPBZlhkmTW1eF84jif4LB/eh/FIDlEFnwPfpewTLr2FsLQ+8F9NSdoil/qal3ZYxvXEWV9iPpE1BLiIwv+uAjTSEf4scOXXv/4oYkruRJfLb4q6vgfLAwpPGU7hoUJtgX13sBW8ZypvenXXEwADSY1XVQiW0FWB70Sxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hnqlc+EaXTFfhtNNFca28U3waLn14gxVLejE7G1nohA=; b=GyXddPDcYd224DS0ygU+hBhqpInTbVY66u0iUSa7E2I3OtUnrbBjzdCt72lRQBVce/sc9baca3Mie3wEoASi+geuq/QSUVmWrbaH56QJ2ld0TMDCU6ISfdNroOZWXt654Ug6NRVOMZbkOMXdbOutokzIAh7CRDD3RtgCwA4onLR5FbFJIzGldiFWe/2mP6vDLTIbatMLHjOqgUKlcgTqSlAF1J5bVhelXpQTQS+YhDPBedvkAsi/5DEisowrZlbv1rZRghEV976ZafCCBOo4IqkwpV41Au9DgRuLUFLco5d33FZU+GeNOWOJq8NoE1Gy8PKLnEJFYkYTdi3KfiOHww== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hnqlc+EaXTFfhtNNFca28U3waLn14gxVLejE7G1nohA=; b=RTY3R2Avk2dwpiq/huVKfjDYaXxlnkEIBww47Na07QKbRqvj0CRc1WWmAxBA/LwHaxBEQ0QgUopssetis+jTPsJtMvs3SAo4diC5EcJYqeCNrGN1yURgGTDB6KeLZJJLEHdtwbpLQZojJPl3P2T69kwr1i98fDslKIvCam5mTG8= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) by DM5PR12MB2504.namprd12.prod.outlook.com (2603:10b6:4:b5::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3000.20; Tue, 19 May 2020 21:51:46 +0000 Received: from DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::4ce1:9947:9681:c8b1]) by DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::4ce1:9947:9681:c8b1%10]) with mapi id 15.20.3000.034; Tue, 19 May 2020 21:51:46 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io Cc: Jordan Justen , Laszlo Ersek , Ard Biesheuvel , Michael D Kinney , Liming Gao , Eric Dong , Ray Ni , Brijesh Singh , Ard Biesheuvel Subject: [PATCH v8 17/46] OvmfPkg/VmgExitLib: Add support for NPF NAE events (MMIO) Date: Tue, 19 May 2020 16:50:45 -0500 Message-Id: <1a5f159a487e2f20b5ad7bff83659fb1442ecbcd.1589925074.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: X-ClientProxiedBy: DM6PR11CA0048.namprd11.prod.outlook.com (2603:10b6:5:14c::25) To DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) Return-Path: thomas.lendacky@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from tlendack-t1.amd.com (165.204.77.1) by DM6PR11CA0048.namprd11.prod.outlook.com (2603:10b6:5:14c::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3000.25 via Frontend Transport; Tue, 19 May 2020 21:51:45 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [165.204.77.1] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: f98625e6-dedc-4447-d76c-08d7fc3ed39a X-MS-TrafficTypeDiagnostic: DM5PR12MB2504: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:7691; X-Forefront-PRVS: 040866B734 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: OQY9cM9bw42RCD6AZQ3JYaL6q+9C+gNeowy2gCbxKaBlcVhv0IJXSxqds51OO+pQ696gD5pbL355+Z214bRh5gZD9A4qFpf3pnkTcEehOdFDJb964lKHrVYvSA8QD1BivFI76/ExJcYRuArG3w8i1M+zmkhnLPTxlCSJT6JbD6Aut/Y0PvtSP9LtLekfErQDwUcSo02Os+2+vxaeTa4eJ6IpK03lH99O4yTiKhCPmOob2tvte3hbNz8zHsvQPPJLzkfXyjjICRhnbJz5SWcIIaowGkmjVyjWzIpRbKyjjN6G/7qsM2G4CY7Flq0AG6J1rC3qQID4w4sIUE8udmUwpZ+hEVWh746WYjcDnMelNZnLt5RDkx8CAqM2wsGWcafqA9QPwgda6cDtoBrRhWoEKCD4Mr+xpEOg9R53i2KwrYpN78ZEGF5cmyAmeylbizDPbT5B/tHKIMglA2hL+ZXt9HEUfsww+cheYsiLhG0cZDWGGHprbc3Q/Fz+cib16x8+TdISVrHyQ1RUT0Ruefot3pj5iDeBPmK96yZ5XnIam8v+A0UkiTLyfOahOCY2QTtEDlZ4IhPIStTs1UYbaZZEqw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR12MB1355.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(376002)(39860400002)(136003)(346002)(396003)(366004)(316002)(86362001)(2906002)(54906003)(7696005)(52116002)(2616005)(956004)(66946007)(66476007)(19627235002)(66556008)(36756003)(26005)(16526019)(186003)(30864003)(4326008)(8676002)(5660300002)(966005)(6486002)(8936002)(6916009)(478600001)(136400200001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: NdYlZC/gfBaB0lFagZCWSJfeHNGkfj9x0dVJYUeB0WJKQhZXpciYVXeqZbczxrDKzJcMCZGgD1lSRa8nz9rZz3fdIi8Ho5C/hycAMiyHp/nnYzmFpfjWxKpGlgUgKW+Q9bKPeAe6QAantOvVsUDDymN+sVh/dfhLjYCqmZfl6sVDpucZQ6n5m6Ihu7gCJ2UpSm52DaTjPC/yu5XGgP3L5O0NEmisv8GWKt1WcQIU5xMVNcBQwwqa2n2OjFqDiyO8CxFVsfH4tqi2IvIhihhKF761hQ+cPfVoc2S3EPBi4xiS30IZkoiRddNSmBfWT68sSZezvwUSgOlFhwyf2PiCd1Jxi+/4FN2K8AG6jhuwvrouc6V2KHtq0wYaoPGlX3JTA/GhIYifdnTyQPtyaw7JOOYKIM29AIiXAREmvxYjxkme9iisCmodYq3sikVoEbK71gVeYIZHwWAYVGsbIV2tim665m4mcvFeMwzqZNyDIXY= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: f98625e6-dedc-4447-d76c-08d7fc3ed39a X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 May 2020 21:51:46.6645 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: epcfqL6U1ms488KZGanIQoNrVyqMD+fHMkc7z6aa/zRsNTqtHZpKqCpWQjwuNfOJLywYa04sneb5Az6nqYrHRg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB2504 Content-Type: text/plain BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198 Under SEV-ES, a NPF intercept for an NPT entry with a reserved bit set generates a #VC exception. This condition is assumed to be an MMIO access. VMGEXIT must be used to allow the hypervisor to handle this intercept. Add support to construct the required GHCB values to support a NPF NAE event for MMIO. Parse the instruction that generated the #VC exception, setting the required register values in the GHCB and creating the proper SW_EXIT_INFO1, SW_EXITINFO2 and SW_SCRATCH values in the GHCB. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Tom Lendacky --- .../Library/VmgExitLib/X64/VmgExitVcHandler.c | 436 ++++++++++++++++++ 1 file changed, 436 insertions(+) diff --git a/OvmfPkg/Library/VmgExitLib/X64/VmgExitVcHandler.c b/OvmfPkg/Library/VmgExitLib/X64/VmgExitVcHandler.c index 1c6b472a47c4..50199845ceef 100644 --- a/OvmfPkg/Library/VmgExitLib/X64/VmgExitVcHandler.c +++ b/OvmfPkg/Library/VmgExitLib/X64/VmgExitVcHandler.c @@ -224,6 +224,263 @@ GhcbSetRegValid ( Ghcb->SaveArea.ValidBitmap[RegIndex] |= (1 << RegBit); } +/** + Return a pointer to the contents of the specified register. + + Based upon the input register, return a pointer to the registers contents + in the x86 processor context. + + @param[in] Regs x64 processor context + @param[in] Register Register to obtain pointer for + + @retval Pointer to the contents of the requested register + +**/ +STATIC +INT64 * +GetRegisterPointer ( + IN EFI_SYSTEM_CONTEXT_X64 *Regs, + IN UINT8 Register + ) +{ + UINT64 *Reg; + + switch (Register) { + case 0: + Reg = &Regs->Rax; + break; + case 1: + Reg = &Regs->Rcx; + break; + case 2: + Reg = &Regs->Rdx; + break; + case 3: + Reg = &Regs->Rbx; + break; + case 4: + Reg = &Regs->Rsp; + break; + case 5: + Reg = &Regs->Rbp; + break; + case 6: + Reg = &Regs->Rsi; + break; + case 7: + Reg = &Regs->Rdi; + break; + case 8: + Reg = &Regs->R8; + break; + case 9: + Reg = &Regs->R9; + break; + case 10: + Reg = &Regs->R10; + break; + case 11: + Reg = &Regs->R11; + break; + case 12: + Reg = &Regs->R12; + break; + case 13: + Reg = &Regs->R13; + break; + case 14: + Reg = &Regs->R14; + break; + case 15: + Reg = &Regs->R15; + break; + default: + Reg = NULL; + } + ASSERT (Reg != NULL); + + return (INT64 *) Reg; +} + +/** + Update the instruction parsing context for displacement bytes. + + @param[in, out] InstructionData Instruction parsing context + @param[in] Size The instruction displacement size + +**/ +STATIC +VOID +UpdateForDisplacement ( + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData, + IN UINTN Size + ) +{ + InstructionData->DisplacementSize = Size; + InstructionData->Immediate += Size; + InstructionData->End += Size; +} + +/** + Determine if an instruction address if RIP relative. + + Examine the instruction parsing context to determine if the address offset + is relative to the instruction pointer. + + @param[in] InstructionData Instruction parsing context + + @retval TRUE Instruction addressing is RIP relative + @retval FALSE Instruction addressing is not RIP relative + +**/ +STATIC +BOOLEAN +IsRipRelative ( + IN SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; + + Ext = &InstructionData->Ext; + + return ((InstructionData->Mode == LongMode64Bit) && + (Ext->ModRm.Mod == 0) && + (Ext->ModRm.Rm == 5) && + (InstructionData->SibPresent == FALSE)); +} + +/** + Return the effective address of a memory operand. + + Examine the instruction parsing context to obtain the effective memory + address of a memory operand. + + @param[in] Regs x64 processor context + @param[in] InstructionData Instruction parsing context + + @retval The memory operand effective address + +**/ +STATIC +UINTN +GetEffectiveMemoryAddress ( + IN EFI_SYSTEM_CONTEXT_X64 *Regs, + IN SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; + INTN EffectiveAddress; + + Ext = &InstructionData->Ext; + EffectiveAddress = 0; + + if (IsRipRelative (InstructionData)) { + /* RIP-relative displacement is a 32-bit signed value */ + INT32 RipRelative; + + RipRelative = *(INT32 *) InstructionData->Displacement; + + UpdateForDisplacement (InstructionData, 4); + return (UINTN) ((INTN) Regs->Rip + RipRelative); + } + + switch (Ext->ModRm.Mod) { + case 1: + UpdateForDisplacement (InstructionData, 1); + EffectiveAddress += (INT8) (*(INT8 *) (InstructionData->Displacement)); + break; + case 2: + switch (InstructionData->AddrSize) { + case Size16Bits: + UpdateForDisplacement (InstructionData, 2); + EffectiveAddress += (INT16) (*(INT16 *) (InstructionData->Displacement)); + break; + default: + UpdateForDisplacement (InstructionData, 4); + EffectiveAddress += (INT32) (*(INT32 *) (InstructionData->Displacement)); + break; + } + break; + } + + if (InstructionData->SibPresent) { + if (Ext->Sib.Index != 4) { + EffectiveAddress += (*GetRegisterPointer (Regs, Ext->Sib.Index) << Ext->Sib.Scale); + } + + if ((Ext->Sib.Base != 5) || Ext->ModRm.Mod) { + EffectiveAddress += *GetRegisterPointer (Regs, Ext->Sib.Base); + } else { + UpdateForDisplacement (InstructionData, 4); + EffectiveAddress += (INT32) (*(INT32 *) (InstructionData->Displacement)); + } + } else { + EffectiveAddress += *GetRegisterPointer (Regs, Ext->ModRm.Rm); + } + + return (UINTN) EffectiveAddress; +} + +/** + Decode a ModRM byte. + + Examine the instruction parsing context to decode a ModRM byte and the SIB + byte, if present. + + @param[in] Regs x64 processor context + @param[in, out] InstructionData Instruction parsing context + +**/ +STATIC +VOID +DecodeModRm ( + IN EFI_SYSTEM_CONTEXT_X64 *Regs, + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + SEV_ES_INSTRUCTION_REX_PREFIX *RexPrefix; + SEV_ES_INSTRUCTION_OPCODE_EXT *Ext; + SEV_ES_INSTRUCTION_MODRM *ModRm; + SEV_ES_INSTRUCTION_SIB *Sib; + + RexPrefix = &InstructionData->RexPrefix; + Ext = &InstructionData->Ext; + ModRm = &InstructionData->ModRm; + Sib = &InstructionData->Sib; + + InstructionData->ModRmPresent = TRUE; + ModRm->Uint8 = *(InstructionData->End); + + InstructionData->Displacement++; + InstructionData->Immediate++; + InstructionData->End++; + + Ext->ModRm.Mod = ModRm->Bits.Mod; + Ext->ModRm.Reg = (RexPrefix->Bits.BitR << 3) | ModRm->Bits.Reg; + Ext->ModRm.Rm = (RexPrefix->Bits.BitB << 3) | ModRm->Bits.Rm; + + Ext->RegData = *GetRegisterPointer (Regs, Ext->ModRm.Reg); + + if (Ext->ModRm.Mod == 3) { + Ext->RmData = *GetRegisterPointer (Regs, Ext->ModRm.Rm); + } else { + if (ModRm->Bits.Rm == 4) { + InstructionData->SibPresent = TRUE; + Sib->Uint8 = *(InstructionData->End); + + InstructionData->Displacement++; + InstructionData->Immediate++; + InstructionData->End++; + + Ext->Sib.Scale = Sib->Bits.Scale; + Ext->Sib.Index = (RexPrefix->Bits.BitX << 3) | Sib->Bits.Index; + Ext->Sib.Base = (RexPrefix->Bits.BitB << 3) | Sib->Bits.Base; + } + + Ext->RmData = GetEffectiveMemoryAddress (Regs, InstructionData); + } +} + /** Decode instruction prefixes. @@ -411,6 +668,181 @@ UnsupportedExit ( return Status; } +/** + Handle an MMIO event. + + Use the VMGEXIT instruction to handle either an MMIO read or an MMIO write. + + @param[in, out] Ghcb Pointer to the Guest-Hypervisor Communication + Block + @param[in, out] Regs x64 processor context + @param[in, out] InstructionData Instruction parsing context + + @retval 0 Event handled successfully + @retval Others New exception value to propagate + +**/ +STATIC +UINT64 +MmioExit ( + IN OUT GHCB *Ghcb, + IN OUT EFI_SYSTEM_CONTEXT_X64 *Regs, + IN OUT SEV_ES_INSTRUCTION_DATA *InstructionData + ) +{ + UINT64 ExitInfo1, ExitInfo2, Status; + UINTN Bytes; + INTN *Register; + UINT8 OpCode, SignByte; + + Bytes = 0; + + OpCode = *(InstructionData->OpCodes); + if (OpCode == 0x0F) { + OpCode = *(InstructionData->OpCodes + 1); + } + + switch (OpCode) { + /* MMIO write */ + case 0x88: + Bytes = 1; + case 0x89: + DecodeModRm (Regs, InstructionData); + Bytes = (Bytes) ? Bytes + : (InstructionData->DataSize == Size16Bits) ? 2 + : (InstructionData->DataSize == Size32Bits) ? 4 + : (InstructionData->DataSize == Size64Bits) ? 8 + : 0; + + if (InstructionData->Ext.ModRm.Mod == 3) { + /* NPF on two register operands??? */ + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + + ExitInfo1 = InstructionData->Ext.RmData; + ExitInfo2 = Bytes; + CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes); + + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + break; + + case 0xC6: + Bytes = 1; + case 0xC7: + DecodeModRm (Regs, InstructionData); + Bytes = (Bytes) ? Bytes + : (InstructionData->DataSize == Size16Bits) ? 2 + : (InstructionData->DataSize == Size32Bits) ? 4 + : 0; + + InstructionData->ImmediateSize = Bytes; + InstructionData->End += Bytes; + + ExitInfo1 = InstructionData->Ext.RmData; + ExitInfo2 = Bytes; + CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes); + + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + break; + + /* MMIO read */ + case 0x8A: + Bytes = 1; + case 0x8B: + DecodeModRm (Regs, InstructionData); + Bytes = (Bytes) ? Bytes + : (InstructionData->DataSize == Size16Bits) ? 2 + : (InstructionData->DataSize == Size32Bits) ? 4 + : (InstructionData->DataSize == Size64Bits) ? 8 + : 0; + if (InstructionData->Ext.ModRm.Mod == 3) { + /* NPF on two register operands??? */ + return UnsupportedExit (Ghcb, Regs, InstructionData); + } + + ExitInfo1 = InstructionData->Ext.RmData; + ExitInfo2 = Bytes; + + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg); + if (Bytes == 4) { + /* Zero-extend for 32-bit operation */ + *Register = 0; + } + CopyMem (Register, Ghcb->SharedBuffer, Bytes); + break; + + /* MMIO Read w/ zero-extension */ + case 0xB6: + Bytes = 1; + case 0xB7: + Bytes = (Bytes) ? Bytes : 2; + + ExitInfo1 = InstructionData->Ext.RmData; + ExitInfo2 = Bytes; + + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg); + SetMem (Register, InstructionData->DataSize, 0); + CopyMem (Register, Ghcb->SharedBuffer, Bytes); + break; + + /* MMIO Read w/ sign-extension */ + case 0xBE: + Bytes = 1; + case 0xBF: + Bytes = (Bytes) ? Bytes : 2; + + ExitInfo1 = InstructionData->Ext.RmData; + ExitInfo2 = Bytes; + + Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer; + Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2); + if (Status) { + return Status; + } + + if (Bytes == 1) { + UINT8 *Data = (UINT8 *) Ghcb->SharedBuffer; + + SignByte = (*Data & 0x80) ? 0xFF : 0x00; + } else { + UINT16 *Data = (UINT16 *) Ghcb->SharedBuffer; + + SignByte = (*Data & 0x8000) ? 0xFF : 0x00; + } + + Register = GetRegisterPointer (Regs, InstructionData->Ext.ModRm.Reg); + SetMem (Register, InstructionData->DataSize, SignByte); + CopyMem (Register, Ghcb->SharedBuffer, Bytes); + break; + + default: + Status = GP_EXCEPTION; + ASSERT (FALSE); + } + + return Status; +} + /** Handle an MSR event. @@ -806,6 +1238,10 @@ VmgExitHandleVc ( NaeExit = MsrExit; break; + case SVM_EXIT_NPF: + NaeExit = MmioExit; + break; + default: NaeExit = UnsupportedExit; } -- 2.17.1