From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=H6ljXic1; spf=none, err=SPF record not found (domain: amd.com, ip: 40.107.76.49, mailfrom: thomas.lendacky@amd.com) Received: from NAM02-CY1-obe.outbound.protection.outlook.com (NAM02-CY1-obe.outbound.protection.outlook.com [40.107.76.49]) by groups.io with SMTP; Thu, 19 Sep 2019 12:52:31 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cOd7URviCohT58IKF9Frf0lWg0xBlVDWxVQylIIwVxXlu3SpOkZnUsMZPvJ1clTAGy7PK+UowMeSJPx5lkJcXJbKTWcz+DJYD6oOnG7f8XyhvfhnxDECXvkTinWktW8VUGnb4dBdW62jNGrnQG4x9AV2Nl31nDVCBIS2s8j7M5FxIwfdIr9aBIFEhqSFKDGWNhR+g1sZdehhMCeEv2QUf8X237aBA8jsWgSFoTus3r/kaIUDazyqLDo2zlbLHuf8p4j1AELcPn2MqUOsCeo0T638fyzETPlfUAC15w+2CL35wQvz6+DsTS5P17te5WOZQ940pfKdC4agWxtiI8emhQ== 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=gFdVS/USbQaBe92WWt94pBCExMOWKw1xJAG3FHSbTEc=; b=L0g2265wsu3U4Sa3femZ2RUDSH5AxrNEnm6FsVilG59/MQsA5g5rclKnmI7tfQ/aGMTHNKxbWYmiLqXlHeqBDsVFf1ldeZ04JfcJfJp6Ookx5p4dmFQ4F/5eSCWhM0XOzhqhwJ/UJFXiuOWpC9DWiUJMcYIn2F6OfZlvVFg3HHdmt71mDAf6xKTEgrUVWX21UkmPZaj65FquzjI/Fuf3qz77pefpK8Q3NYN48CIVaK5fZ0M4JzLeKI+vFeLNrxiv/jMdb+DXCCXxtzLim178r0XyP/jai1BGJPufez1Yc5LkFsOPDc6BpctfOhVZx4N4iLES4MueHzeHFu9xF++MpQ== 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=gFdVS/USbQaBe92WWt94pBCExMOWKw1xJAG3FHSbTEc=; b=H6ljXic1UjLc5dH64/1WtmL65EsqPIAmP0o8pi610MCNwiUIFBmoHsVSLqmEZpCT1HTDX2b0omCdajxHUrhr9RgT/0x47bBMvBVv4hYUSBJAxCHQI8AcuEho2fnSyRC+T0+LsPemEcLe3NvEVK1IJPzDA7ICyCiAuqSLJl7+nyw= Received: from DM6PR12MB3163.namprd12.prod.outlook.com (20.179.104.150) by DM6PR12MB3228.namprd12.prod.outlook.com (20.179.105.96) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2263.13; Thu, 19 Sep 2019 19:52:29 +0000 Received: from DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::400e:f0c3:7ca:2fcc]) by DM6PR12MB3163.namprd12.prod.outlook.com ([fe80::400e:f0c3:7ca:2fcc%6]) with mapi id 15.20.2284.009; Thu, 19 Sep 2019 19:52:29 +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 , "Singh, Brijesh" Subject: [RFC PATCH v2 04/44] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Thread-Topic: [RFC PATCH v2 04/44] OvmfPkg/ResetVector: Add support for a 32-bit SEV check Thread-Index: AQHVbyPEW2twUlghfEifX1FioTvTGA== Date: Thu, 19 Sep 2019 19:52:29 +0000 Message-ID: <54ebf48fe05c20a1181a3dc90496e4835912ebf2.1568922728.git.thomas.lendacky@amd.com> References: In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 2.17.1 x-clientproxiedby: SN4PR0501CA0146.namprd05.prod.outlook.com (2603:10b6:803:2c::24) To DM6PR12MB3163.namprd12.prod.outlook.com (2603:10b6:5:182::22) authentication-results: spf=none (sender IP is ) smtp.mailfrom=Thomas.Lendacky@amd.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [165.204.78.1] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 926ccd90-21a1-41c5-8b55-08d73d3ae6e3 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600167)(711020)(4605104)(1401327)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);SRVR:DM6PR12MB3228; x-ms-traffictypediagnostic: DM6PR12MB3228: x-ms-exchange-purlcount: 1 x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:8273; x-forefront-prvs: 016572D96D x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(4636009)(366004)(376002)(396003)(136003)(39860400002)(346002)(189003)(199004)(4326008)(26005)(446003)(25786009)(52116002)(14444005)(19627235002)(71200400001)(71190400001)(8936002)(81156014)(81166006)(256004)(8676002)(186003)(50226002)(2351001)(2616005)(102836004)(486006)(11346002)(476003)(66066001)(386003)(6506007)(66446008)(14454004)(76176011)(99286004)(6486002)(36756003)(5640700003)(66556008)(118296001)(3846002)(316002)(7736002)(2501003)(1730700003)(6116002)(5660300002)(478600001)(54906003)(6916009)(966005)(6436002)(2906002)(64756008)(305945005)(86362001)(6512007)(6306002)(66476007)(66946007);DIR:OUT;SFP:1101;SCL:1;SRVR:DM6PR12MB3228;H:DM6PR12MB3163.namprd12.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: amd.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: ZD5wSYfgQ/Xq8KYI+WaUCUwbchzp/QMmMsNVsVGiC7whVC/6yYBCt/juASHH/PSXIrZC90Nje31oe6ulcjZRmPG9e6J25M7Ln7Myt8KK+KZ9E9W0ObFUGwt8Ed+dcJo6xs8qbvM8H8/rLCZ/S1haHeMX4oKkH7wV+wPTjdd5FMCTxov5MtEhZWmw64dLvx8eI7EEb+Kt0FUEctN/TgxGrz+GNTnU8pinWcFLtVB0meBa/r1ep5GufnAwfj4MlXATTbUoiEmc2kxDgCzNoO44y/LyYNTtTQAtIWWTHh9a6gZM/6bH8D5Gmd11Ep8JORbeuonNV2rcenJj2N0TPOdJGn+FMAQjIYRzVJ0OL65XxRwbOO55ap8ulhjPquGqMFDLJM9Y1VZkkWqlEzLEgUggfGvLsKaD08fGX7KkmgnBcT4= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-Network-Message-Id: 926ccd90-21a1-41c5-8b55-08d73d3ae6e3 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Sep 2019 19:52:29.1051 (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: Ooa/b9QxJCIhPvIj+e3Tk3uxGS9T+m2+awHWdshLgA3SFj+vnUaWHMhywWodIfFaKgfKe8GUg5yHbIRZAbCL7A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3228 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-ID: Content-Transfer-Encoding: quoted-printable From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2198 During BSP startup, the reset vector code will issue a CPUID instruction while in 32-bit mode. When running as an SEV-ES guest, this will trigger a #VC exception. Add exception handling support to the early reset vector code to catch these exceptions. Also, since the guest is in 32-bit mode at this point, writes to the GHCB will be encrypted and thus not able to be read by the hypervisor, so use the GHCB CPUID request/response protocol to obtain the requested CPUID function values and provide these to the guest. The exception handling support is active during the SEV check and uses the OVMF temporary RAM space for a stack. After the SEV check is complete, the exception handling support is removed and the stack pointer cleared. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Signed-off-by: Tom Lendacky --- OvmfPkg/ResetVector/ResetVector.inf | 2 + OvmfPkg/ResetVector/Ia32/PageTables64.asm | 177 +++++++++++++++++++++- OvmfPkg/ResetVector/ResetVector.nasmb | 1 + 3 files changed, 179 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/ResetVector/ResetVector.inf b/OvmfPkg/ResetVector/Rese= tVector.inf index b0ddfa5832a2..960b47cd0797 100644 --- a/OvmfPkg/ResetVector/ResetVector.inf +++ b/OvmfPkg/ResetVector/ResetVector.inf @@ -35,3 +35,5 @@ [BuildOptions] [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVecto= r/Ia32/PageTables64.asm index abad009f20f5..40f7814c1134 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm @@ -33,10 +33,21 @@ BITS 32 =20 ; Check if Secure Encrypted Virtualization (SEV) feature is enabled ; -; If SEV is enabled then EAX will be at least 32 +; Modified: EAX, EBX, ECX, EDX, ESP +; +; If SEV is enabled then EAX will be at least 32. ; If SEV is disabled then EAX will be zero. ; CheckSevFeature: + ; + ; Set up exception handlers to check for SEV-ES + ; Load temporary RAM stack based on PCDs + ; Establish exception handlers + ; + mov esp, SEV_TOP_OF_STACK + mov eax, ADDR_OF(Idtr) + lidt [cs:eax] + ; Check if we have a valid (0x8000_001F) CPUID leaf mov eax, 0x80000000 cpuid @@ -73,6 +84,15 @@ NoSev: xor eax, eax =20 SevExit: + ; + ; Clear exception handlers and stack + ; + push eax + mov eax, ADDR_OF(IdtrClear) + lidt [cs:eax] + pop eax + mov esp, 0 + OneTimeCallRet CheckSevFeature =20 ; @@ -146,3 +166,158 @@ pageTableEntriesLoop: mov cr3, eax =20 OneTimeCallRet SetCr3ForPageTables64 + +SevEsIdtCommon: + hlt + jmp SevEsIdtCommon + iret + +SevEsIdtVmmComm: + ; + ; If we're here, then we are an SEV-ES guest and this + ; was triggered by a CPUID instruction + ; + pop ecx ; Error code + cmp ecx, 0x72 ; Be sure it was CPUID + jne SevEsIdtCommon + + ; + ; Set up local variable room on the stack + ; CPUID function : + 28 + ; CPUID register : + 24 + ; GHCB MSR (EAX) : + 20 + ; GHCB MSR (EDX) : + 16 + ; CPUID result (EDX) : + 12 + ; CPUID result (ECX) : + 8 + ; CPUID result (EBX) : + 4 + ; CPUID result (EAX) : + 0 + sub esp, 32 + + ; Save CPUID function and initial register request + mov [esp + 28], eax + xor eax, eax + mov [esp + 24], eax + + ; Save current GHCB MSR value + mov ecx, 0xc0010130 + rdmsr + mov [esp + 20], eax + mov [esp + 16], edx + +NextReg: + ; + ; Setup GHCB MSR + ; GHCB_MSR[63:32] =3D CPUID function + ; GHCB_MSR[31:30] =3D CPUID register + ; GHCB_MSR[11:0] =3D CPUID request protocol + ; + mov eax, [esp + 24] + cmp eax, 4 + jge VmmDone + + shl eax, 30 + or eax, 0x004 + mov edx, [esp + 28] + mov ecx, 0xc0010130 + wrmsr + + ; Issue VMGEXIT (rep; vmmcall) + db 0xf3 + db 0x0f + db 0x01 + db 0xd9 + + ; + ; Read GHCB MSR + ; GHCB_MSR[63:32] =3D CPUID register value + ; GHCB_MSR[31:30] =3D CPUID register + ; GHCB_MSR[11:0] =3D CPUID response protocol + ; + mov ecx, 0xc0010130 + rdmsr + mov ecx, eax + and ecx, 0xfff + cmp ecx, 0x005 + jne SevEsIdtCommon + + ; Save returned value + shr eax, 30 + and eax, 0x3 + shl eax, 2 + mov ecx, esp + add ecx, eax + mov [ecx], edx + + ; Next register + inc word [esp + 24] + + jmp NextReg + +VmmDone: + ; + ; At this point we have all CPUID register values. Restore the GHCB MS= R, + ; set the return register values and return. + ; + mov eax, [esp + 20] + mov edx, [esp + 16] + mov ecx, 0xc0010130 + wrmsr + + mov eax, [esp + 0] + mov ebx, [esp + 4] + mov ecx, [esp + 8] + mov edx, [esp + 12] + + add esp, 32 + add word [esp], 2 ; Skip over the CPUID instruction + iret + +ALIGN 2 + +Idtr: + dw IDT_END - IDT_BASE - 1 ; Limit + dd ADDR_OF(IDT_BASE) ; Base + +IdtrClear: + dw 0 ; Limit + dd 0 ; Base + +ALIGN 16 + +; +; The Interrupt Descriptor Table (IDT) +; This will be used to determine if SEV-ES is enabled. Upon execution +; of the CPUID instruction, a VMM Communication Exception will occur. +; This will tell us if SEV-ES is enabled. We can use the current value +; of the GHCB MSR to determine the SEV attributes. +; +IDT_BASE: +; +; Vectors 0 - 28 +; +%rep 29 + dw (ADDR_OF(SevEsIdtCommon) & 0xffff) ; Offset low bits 15..0 + dw 0x10 ; Selector + db 0 ; Reserved + db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) + dw (ADDR_OF(SevEsIdtCommon) >> 16) ; Offset high bits 31..16 +%endrep +; +; Vector 29 (VMM Communication Exception) +; + dw (ADDR_OF(SevEsIdtVmmComm) & 0xffff) ; Offset low bits 15..0 + dw 0x10 ; Selector + db 0 ; Reserved + db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) + dw (ADDR_OF(SevEsIdtVmmComm) >> 16) ; Offset high bits 31..16 +; +; Vectors 30 - 31 +; +%rep 2 + dw (ADDR_OF(SevEsIdtCommon) & 0xffff) ; Offset low bits 15..0 + dw 0x10 ; Selector + db 0 ; Reserved + db 0x8E ; Gate Type (IA32_IDT_GAT= E_TYPE_INTERRUPT_32) + dw (ADDR_OF(SevEsIdtCommon) >> 16) ; Offset high bits 31..16 +%endrep +IDT_END: diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/Re= setVector.nasmb index 75cfe16654b1..3b213cd05ab2 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -55,6 +55,7 @@ =20 %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Off= set)) %include "Ia32/Flat32ToFlat64.asm" + %define SEV_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase) + Fix= edPcdGet32 (PcdOvmfSecPeiTempRamSize)) %include "Ia32/PageTables64.asm" %endif =20 --=20 2.17.1