From nobody Sun Apr 28 19:47:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+97416+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97416+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1671080605; cv=none; d=zohomail.com; s=zohoarc; b=Du8+6v8dUeKmbzCnh96GthoZrsdsTD4jHPvgz4zv4tW4D+OWuWRaLAlj7z1e/ABl0aIsMdhoHMuyqIEiysgcR8of1ucvAK1YBsNbTIKjANkol4sCRiSxm/0esfMMR1SBBdcS4wt3a9eRp36o5hIDMbUWzFJGsftXJHllNVmC0xM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671080605; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=TMze1kYLiFyeBl7TBpF5UGiK6GSIpX80qH2Wsz/ZlgM=; b=Wn5lnsflq8OcPaMmZROMGflOCPj1vHsE1dUgl71qPAOo6thKTcZCzox8r2ltrs4+IXfQiG1ro/Isszyd2mTuAQU6ELwcNrrltFM+PnsS86pacwO32z1C9knMEVIgevBBbkWaMwmXkhLDh1Rz8WZEoP312c04hfuIC7OeBVH8G7M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97416+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1671080604994375.28925623528335; Wed, 14 Dec 2022 21:03:24 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8TZPYY1788612x46TBFFesAn; Wed, 14 Dec 2022 21:03:24 -0800 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.126756.1671080601833256277 for ; Wed, 14 Dec 2022 21:03:23 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="319727755" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="319727755" X-Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 21:03:23 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="791493400" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="791493400" X-Received: from shwdeopenlab705.ccr.corp.intel.com ([10.239.182.166]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 21:03:22 -0800 From: "Yuanhao Xie" To: devel@edk2.groups.io Subject: [edk2-devel] [Patch V2 1/2] UefiCpuPkg: Duplicated AsmRelocateApLoop as AsmRelocateApLoopAmd Date: Thu, 15 Dec 2022 13:03:07 +0800 Message-Id: <20221215050308.2191-2-yuanhao.xie@intel.com> In-Reply-To: <20221215050308.2191-1-yuanhao.xie@intel.com> References: <20221215050308.2191-1-yuanhao.xie@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yuanhao.xie@intel.com X-Gm-Message-State: Ebe2jqCG70jZb2LP1LNufzd5x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1671080604; bh=PhJCxuwt+/kG6E1Fv/SAk8aUudgljm2Pex6sJClsdjg=; h=Date:From:Reply-To:Subject:To; b=Ml1a8Edwsmq22j8vvUjAqJwhN3PxJhrdS/q0FrWWim8eMltdF74NwQlwhcgt1UAJVL7 3ruEMdXc+PRC1fEP5Vblv0hcdj8Ez/0S9xiJf0ytH/OscFvJL2H8+BF1UnCy7Se8x6q/U KTXuAnajT8IWS3+rViwpvCqVr07kOdeshPo= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1671080605892100006 Content-Type: text/plain; charset="utf-8" AsmRelocateApLoop is replicated for future Intel Logic Extraction, further brings AP into 64-bit, and enables paging. Signed-off-by: Yuanhao Xie --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 52 ++++++++++++++++++++++= ++++++++++-------------------- UefiCpuPkg/Library/MpInitLib/MpEqu.inc | 2 ++ UefiCpuPkg/Library/MpInitLib/MpLib.h | 27 ++++++++++++++++++++++= +++++ UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm | 169 ++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 6 ++++++ 5 files changed, 236 insertions(+), 20 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/M= pInitLib/DxeMpLib.c index a84e9e33ba..445e0853d2 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -1,7 +1,7 @@ /** @file MP initialize support functions for DXE phase. =20 - Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -378,32 +378,44 @@ RelocateApLoop ( IN OUT VOID *Buffer ) { - CPU_MP_DATA *CpuMpData; - BOOLEAN MwaitSupport; - ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; - UINTN ProcessorNumber; - UINTN StackStart; + CPU_MP_DATA *CpuMpData; + BOOLEAN MwaitSupport; + ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; + ASM_RELOCATE_AP_LOOP_AMD AsmRelocateApLoopFuncAmd; + UINTN ProcessorNumber; + UINTN StackStart; =20 MpInitLibWhoAmI (&ProcessorNumber); CpuMpData =3D GetCpuMpData (); MwaitSupport =3D IsMwaitSupport (); - if (CpuMpData->UseSevEsAPMethod) { - StackStart =3D CpuMpData->SevEsAPResetStackStart; + if (StandardSignatureIsAuthenticAMD ()) { + StackStart =3D CpuMpData->UseSevEsAPMethod ? CpuMpData->= SevEsAPResetStackStart : mReservedTopOfApStack; + AsmRelocateApLoopFuncAmd =3D (ASM_RELOCATE_AP_LOOP_AMD)(UINTN)mReserve= dApLoopFunc; + AsmRelocateApLoopFuncAmd ( + MwaitSupport, + CpuMpData->ApTargetCState, + CpuMpData->PmCodeSegment, + StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, + (UINTN)&mNumberToFinish, + CpuMpData->Pm16CodeSegment, + CpuMpData->SevEsAPBuffer, + CpuMpData->WakeupBuffer + ); } else { - StackStart =3D mReservedTopOfApStack; + StackStart =3D mReservedTopOfApStack; + AsmRelocateApLoopFunc =3D (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoop= Func; + AsmRelocateApLoopFunc ( + MwaitSupport, + CpuMpData->ApTargetCState, + CpuMpData->PmCodeSegment, + StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, + (UINTN)&mNumberToFinish, + CpuMpData->Pm16CodeSegment, + CpuMpData->SevEsAPBuffer, + CpuMpData->WakeupBuffer + ); } =20 - AsmRelocateApLoopFunc =3D (ASM_RELOCATE_AP_LOOP)(UINTN)mReservedApLoopFu= nc; - AsmRelocateApLoopFunc ( - MwaitSupport, - CpuMpData->ApTargetCState, - CpuMpData->PmCodeSegment, - StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, - (UINTN)&mNumberToFinish, - CpuMpData->Pm16CodeSegment, - CpuMpData->SevEsAPBuffer, - CpuMpData->WakeupBuffer - ); // // It should never reach here // diff --git a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc b/UefiCpuPkg/Library/Mp= InitLib/MpEqu.inc index ebadcc6fb3..ea202d4aef 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpEqu.inc +++ b/UefiCpuPkg/Library/MpInitLib/MpEqu.inc @@ -26,6 +26,8 @@ struc MP_ASSEMBLY_ADDRESS_MAP .RendezvousFunnelSize CTYPE_UINTN 1 .RelocateApLoopFuncAddress CTYPE_UINTN 1 .RelocateApLoopFuncSize CTYPE_UINTN 1 + .RelocateApLoopFuncAddressAmd CTYPE_UINTN 1 + .RelocateApLoopFuncSizeAmd CTYPE_UINTN 1 .ModeTransitionOffset CTYPE_UINTN 1 .SwitchToRealNoNxOffset CTYPE_UINTN 1 .SwitchToRealPM16ModeOffset CTYPE_UINTN 1 diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index f5086e497e..1102003a93 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -179,6 +179,8 @@ typedef struct { UINTN RendezvousFunnelSize; UINT8 *RelocateApLoopFuncAddress; UINTN RelocateApLoopFuncSize; + UINT8 *RelocateApLoopFuncAddressAmd; + UINTN RelocateApLoopFuncSizeAmd; UINTN ModeTransitionOffset; UINTN SwitchToRealNoNxOffset; UINTN SwitchToRealPM16ModeOffset; @@ -346,6 +348,31 @@ typedef =20 extern EFI_GUID mCpuInitMpLibHobGuid; =20 +/** + Assembly code to place AP into safe loop mode for Amd. + Place AP into targeted C-State if MONITOR is supported, otherwise + place AP into hlt state. + Place AP in protected mode if the current is long mode. Due to AP maybe + wakeup by some hardware event. It could avoid accessing page table that + may not available during booting to OS. + @param[in] MwaitSupport TRUE indicates MONITOR is supported. + FALSE indicates MONITOR is not supported. + @param[in] ApTargetCState Target C-State value. + @param[in] PmCodeSegment Protected mode code segment value. +**/ +typedef + VOID +(EFIAPI *ASM_RELOCATE_AP_LOOP_AMD)( + IN BOOLEAN MwaitSupport, + IN UINTN ApTargetCState, + IN UINTN PmCodeSegment, + IN UINTN TopOfApStack, + IN UINTN NumberToFinish, + IN UINTN Pm16CodeSegment, + IN UINTN SevEsAPJumpTable, + IN UINTN WakeupBuffer + ); + /** Assembly code to place AP into safe loop mode. =20 diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Libr= ary/MpInitLib/X64/AmdSev.nasm index 7c2469f9c5..47fc8e9325 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm @@ -346,3 +346,172 @@ PM16Mode: iret =20 SwitchToRealProcEnd: +;-------------------------------------------------------------------------= ------------ +; AsmRelocateApLoopAmd (MwaitSupport, ApTargetCState, PmCodeSegment, TopO= fApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer); +;-------------------------------------------------------------------------= ------------ + +AsmRelocateApLoopStartAmd: +BITS 64 + cmp qword [rsp + 56], 0 ; SevEsAPJumpTable + je NoSevEsAmd + + ; + ; Perform some SEV-ES related setup before leaving 64-bit mode + ; + push rcx + push rdx + + ; + ; Get the RDX reset value using CPUID + ; + mov rax, 1 + cpuid + mov rsi, rax ; Save off the reset value for RDX + + ; + ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call + ; - Must be done while in 64-bit long mode so that writes to + ; the GHCB memory will be unencrypted. + ; - No NAE events can be generated once this is set otherwise + ; the AP_RESET_HOLD SW_EXITCODE will be overwritten. + ; + mov rcx, 0xc0010130 + rdmsr ; Retrieve current GHCB address + shl rdx, 32 + or rdx, rax + + mov rdi, rdx + xor rax, rax + mov rcx, 0x800 + shr rcx, 3 + rep stosq ; Clear the GHCB + + mov rax, 0x80000004 ; VMGEXIT AP_RESET_HOLD + mov [rdx + 0x390], rax + mov rax, 114 ; Set SwExitCode valid bit + bts [rdx + 0x3f0], rax + inc rax ; Set SwExitInfo1 valid bit + bts [rdx + 0x3f0], rax + inc rax ; Set SwExitInfo2 valid bit + bts [rdx + 0x3f0], rax + + pop rdx + pop rcx + +NoSevEsAmd: + cli ; Disable interrupt before switching to 3= 2-bit mode + mov rax, [rsp + 40] ; CountTofinish + lock dec dword [rax] ; (*CountTofinish)-- + + mov r10, [rsp + 48] ; Pm16CodeSegment + mov rax, [rsp + 56] ; SevEsAPJumpTable + mov rbx, [rsp + 64] ; WakeupBuffer + mov rsp, r9 ; TopOfApStack + + push rax ; Save SevEsAPJumpTable + push rbx ; Save WakeupBuffer + push r10 ; Save Pm16CodeSegment + push rcx ; Save MwaitSupport + push rdx ; Save ApTargetCState + + lea rax, [PmEntryAmd] ; rax <- The start address of transiti= on code + + push r8 + push rax + + ; + ; Clear R8 - R15, for reset, before going into 32-bit mode + ; + xor r8, r8 + xor r9, r9 + xor r10, r10 + xor r11, r11 + xor r12, r12 + xor r13, r13 + xor r14, r14 + xor r15, r15 + + ; + ; Far return into 32-bit mode + ; +o64 retf + +BITS 32 +PmEntryAmd: + mov eax, cr0 + btr eax, 31 ; Clear CR0.PG + mov cr0, eax ; Disable paging and caches + + mov ecx, 0xc0000080 + rdmsr + and ah, ~ 1 ; Clear LME + wrmsr + mov eax, cr4 + and al, ~ (1 << 5) ; Clear PAE + mov cr4, eax + + pop edx + add esp, 4 + pop ecx, + add esp, 4 + +MwaitCheckAmd: + cmp cl, 1 ; Check mwait-monitor support + jnz HltLoopAmd + mov ebx, edx ; Save C-State to ebx +MwaitLoopAmd: + cli + mov eax, esp ; Set Monitor Address + xor ecx, ecx ; ecx =3D 0 + xor edx, edx ; edx =3D 0 + monitor + mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4] + shl eax, 4 + mwait + jmp MwaitLoopAmd + +HltLoopAmd: + pop edx ; PM16CodeSegment + add esp, 4 + pop ebx ; WakeupBuffer + add esp, 4 + pop eax ; SevEsAPJumpTable + add esp, 4 + cmp eax, 0 ; Check for SEV-ES + je DoHltAmd + + cli + ; + ; SEV-ES is enabled, use VMGEXIT (GHCB information already + ; set by caller) + ; +BITS 64 + rep vmmcall +BITS 32 + + ; + ; Back from VMGEXIT AP_HLT_LOOP + ; Push the FLAGS/CS/IP values to use + ; + push word 0x0002 ; EFLAGS + xor ecx, ecx + mov cx, [eax + 2] ; CS + push cx + mov cx, [eax] ; IP + push cx + push word 0x0000 ; For alignment, will be discarded + + push edx + push ebx + + mov edx, esi ; Restore RDX reset value + + retf + +DoHltAmd: + cli + hlt + jmp DoHltAmd + +BITS 64 +AsmRelocateApLoopEndAmd: \ No newline at end of file diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Lib= rary/MpInitLib/X64/MpFuncs.nasm index 5d71995bf8..87b23b482e 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm @@ -460,6 +460,12 @@ ASM_PFX(AsmGetAddressMap): mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr= ess], rax mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize= ], AsmRelocateApLoopEnd - AsmRelocateApLoopStart mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],= Flat32Start - RendezvousFunnelProcStart + + lea rax, [AsmRelocateApLoopStartAmd] + mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddr= essAmd], rax + mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize= Amd], AsmRelocateApLoopEndAmd - AsmRelocateApLoopStartAmd + mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset],= Flat32Start - RendezvousFunnelProcStart + mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset= ], SwitchToRealProcStart - Flat32Start mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOf= fset], PM16Mode - RendezvousFunnelProcStart mov qword [rcx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSi= ze], SwitchToRealProcEnd - PM16Mode --=20 2.36.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#97416): https://edk2.groups.io/g/devel/message/97416 Mute This Topic: https://groups.io/mt/95683382/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sun Apr 28 19:47:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+97417+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97417+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1671080607; cv=none; d=zohomail.com; s=zohoarc; b=SJPvf7QbEI4rIPm6+oKYi4IPJHqFJkrEpt2WnGlXEPP+MrtEZZw7ZAzrIn2tOuRGZBCUiXkXwoGHX7mZ5LH6s8x+9XLIwBkknMKdleixW0IgVSMdNa1RC/wUrvwXeeDg0I1Dj5WE7MCWJycXP8Z6NFALmzTowtWycoonWTWmsSs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671080607; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=rEUircgzhzAf+ZxZHxWFGrX0qEF2WKtBcanL35Sw+C4=; b=RDAodkqCL5UAMP44mGFbwvt6JfWZ8XUdJo4eOm13VKotzEk0UFt0otoAxEYX0Ot3Zm8Hnd/AxFCAgKJ4goyLAChL6D9a6o4hSOKxUEVdKbCjelgEhxH90iTcPWEwB4HbPx/kqI3OtsoctOxaL0sR3h9KDqSPCOEBKhwL3biHesQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97417+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1671080607059991.1375347532161; Wed, 14 Dec 2022 21:03:27 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 9kgrYY1788612x1Lx3oqezem; Wed, 14 Dec 2022 21:03:26 -0800 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.126756.1671080601833256277 for ; Wed, 14 Dec 2022 21:03:25 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="319727785" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="319727785" X-Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 21:03:25 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10561"; a="791493404" X-IronPort-AV: E=Sophos;i="5.96,246,1665471600"; d="scan'208";a="791493404" X-Received: from shwdeopenlab705.ccr.corp.intel.com ([10.239.182.166]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2022 21:03:24 -0800 From: "Yuanhao Xie" To: devel@edk2.groups.io Cc: Ray Ni Subject: [edk2-devel] [Patch V2 2/2] UefiCpuPkg: Has APs in 64 bit long-mode before booting to OS. Date: Thu, 15 Dec 2022 13:03:08 +0800 Message-Id: <20221215050308.2191-3-yuanhao.xie@intel.com> In-Reply-To: <20221215050308.2191-1-yuanhao.xie@intel.com> References: <20221215050308.2191-1-yuanhao.xie@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,yuanhao.xie@intel.com X-Gm-Message-State: V0Y6UehPFWKhKgh4UTalPNiKx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1671080606; bh=gfSr363EJetL1ToUzYf53+9UH1tuVk0HXbAZ3X0/8xQ=; h=Cc:Date:From:Reply-To:Subject:To; b=fwwf1H8nzzE3zrVH9ZwUMHTtZZ3lzotRHh2cgfi44cQkx6HZFFdCghxfI3H9HOoatCB MfBr/t/hHzjuRUXgLybTEKCJ8LMp4CBocUiT1+5EvHFQEL3gy9yhsqI/AhKvPvLsn5HS1 2BDiXzd+nEx5JHy/dHsCsLIfH+03s0M9ndc= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1671080607880100010 Content-Type: text/plain; charset="utf-8" During the finalization of Mp initialization before booting into the OS, depending on whether Mwait is supported or not, AsmRelocateApLoop places Aps in MWAIT-loop or HLT-loop. Since paging is necessary for long mode, the original implementation of moving APs to 32-bit was to disable paging to ensure that the booting does not crash. The current modification creates a page table in reserved memory, avoiding switching modes and reclaiming memory by OS. More specifically, we keep the AMD logic as the original code flow, extract and update the Intel-related code, where the APs would stay in 64-bit, and run in a Mwait or Hlt loop until the OS wake them up. Signed-off-by: Ray Ni Signed-off-by: Yuanhao Xie --- UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 + UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 126 ++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------= ----------------------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 5 +---- UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm | 2 +- UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 171 ++++++++++++++++++++++= +++++----------------------------------------------------------------------= -------------------------------------------------------------------------- 5 files changed, 105 insertions(+), 200 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Lib= rary/MpInitLib/DxeMpInitLib.inf index cd07de3a3c..f19c6c9958 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -56,6 +56,7 @@ PcdLib CcExitLib MicrocodeLib + CpuPageTableLib =20 [Protocols] gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/M= pInitLib/DxeMpLib.c index 445e0853d2..5726d16a51 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -13,9 +13,11 @@ #include #include #include +#include #include #include =20 +#include #include =20 #define AP_SAFE_STACK_SIZE 128 @@ -28,6 +30,7 @@ volatile BOOLEAN mStopCheckAllApsStatus =3D TRUE; VOID *mReservedApLoopFunc =3D NULL; UINTN mReservedTopOfApStack; volatile UINT32 mNumberToFinish =3D 0; +UINTN mApPageTable; =20 // // Begin wakeup buffer allocation below 0x88000 @@ -407,12 +410,9 @@ RelocateApLoop ( AsmRelocateApLoopFunc ( MwaitSupport, CpuMpData->ApTargetCState, - CpuMpData->PmCodeSegment, StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE, (UINTN)&mNumberToFinish, - CpuMpData->Pm16CodeSegment, - CpuMpData->SevEsAPBuffer, - CpuMpData->WakeupBuffer + mApPageTable ); } =20 @@ -477,12 +477,16 @@ InitMpGlobalData ( ) { EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; UINTN ApSafeBufferSize; UINTN Index; EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; UINTN StackBase; CPU_INFO_IN_HOB *CpuInfoInHob; + IA32_MAP_ATTRIBUTE MapAttribute; + IA32_MAP_ATTRIBUTE MapMask; + UINTN PageTable; + VOID *PageTableBuffer; + UINTN PageTableBufferSize; =20 SaveCpuMpData (CpuMpData); =20 @@ -545,60 +549,80 @@ InitMpGlobalData ( // Allocating it in advance since memory services are not available in // Exit Boot Services callback function. // - ApSafeBufferSize =3D EFI_PAGES_TO_SIZE ( - EFI_SIZE_TO_PAGES ( - CpuMpData->AddressMap.RelocateApLoopFuncSize - ) - ); - Address =3D BASE_4GB - 1; - Status =3D gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - EFI_SIZE_TO_PAGES (ApSafeBufferSize), - &Address - ); - ASSERT_EFI_ERROR (Status); - - mReservedApLoopFunc =3D (VOID *)(UINTN)Address; - ASSERT (mReservedApLoopFunc !=3D NULL); - - // - // Make sure that the buffer memory is executable if NX protection is en= abled - // for EfiReservedMemoryType. + // +------------+ + // | Ap Loop | + // +------------+ + // | Stack * N | + // +------------+ (low address) // - // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE G= CD - // service. - // - Status =3D gDS->GetMemorySpaceDescriptor (Address, &MemDesc); - if (!EFI_ERROR (Status)) { - gDS->SetMemorySpaceAttributes ( - Address, - ApSafeBufferSize, - MemDesc.Attributes & (~EFI_MEMORY_XP) - ); - } - ApSafeBufferSize =3D EFI_PAGES_TO_SIZE ( EFI_SIZE_TO_PAGES ( CpuMpData->CpuCount * AP_SAFE_STACK_SIZE + + CpuMpData->AddressMap.RelocateApLoopFuncSize ) ); - Address =3D BASE_4GB - 1; - Status =3D gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - EFI_SIZE_TO_PAGES (ApSafeBufferSize), - &Address - ); - ASSERT_EFI_ERROR (Status); =20 - mReservedTopOfApStack =3D (UINTN)Address + ApSafeBufferSize; + mReservedTopOfApStack =3D (UINTN)AllocateReservedPages (EFI_SIZE_TO_PAGE= S (ApSafeBufferSize)); + ASSERT (mReservedTopOfApStack !=3D 0); ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) =3D= =3D 0); - CopyMem ( - mReservedApLoopFunc, - CpuMpData->AddressMap.RelocateApLoopFuncAddress, - CpuMpData->AddressMap.RelocateApLoopFuncSize - ); + ASSERT ((AP_SAFE_STACK_SIZE & (CPU_STACK_ALIGNMENT - 1)) =3D=3D 0); + + mReservedApLoopFunc =3D (VOID *)(mReservedTopOfApStack + CpuMpData->CpuC= ount * AP_SAFE_STACK_SIZE); + if (StandardSignatureIsAuthenticAMD ()) { + CopyMem ( + mReservedApLoopFunc, + CpuMpData->AddressMap.RelocateApLoopFuncAddressAmd, + CpuMpData->AddressMap.RelocateApLoopFuncSizeAmd + ); + } else { + MapAttribute.Uint64 =3D mReservedTopOfApStack; + MapAttribute.Bits.Present =3D 1; + MapAttribute.Bits.ReadWrite =3D 1; + + MapMask.Bits.PageTableBaseAddress =3D 1; + MapMask.Bits.Present =3D 1; + MapMask.Bits.ReadWrite =3D 1; + + PageTable =3D 0; + PageTableBufferSize =3D 0; + + CopyMem ( + mReservedApLoopFunc, + CpuMpData->AddressMap.RelocateApLoopFuncAddress, + CpuMpData->AddressMap.RelocateApLoopFuncSize + ); + // + // Allocate reserved memory for page table + // + Status =3D PageTableMap ( + &PageTable, + Paging4Level, + NULL, + &PageTableBufferSize, + mReservedTopOfApStack, + ApSafeBufferSize, + &MapAttribute, + &MapMask + ); + ASSERT (Status =3D=3D EFI_BUFFER_TOO_SMALL); + DEBUG ((DEBUG_INFO, "AP Page Table Buffer Size =3D %x\n", PageTableBuf= ferSize)); + + PageTableBuffer =3D AllocateReservedPages (EFI_SIZE_TO_PAGES (PageTabl= eBufferSize)); + ASSERT (PageTableBuffer !=3D NULL); + Status =3D PageTableMap ( + &PageTable, + Paging4Level, + PageTableBuffer, + &PageTableBufferSize, + mReservedTopOfApStack, + ApSafeBufferSize, + &MapAttribute, + &MapMask + ); + ASSERT_EFI_ERROR (Status); + mApPageTable =3D PageTable; + mReservedTopOfApStack +=3D CpuMpData->CpuCount * AP_SAFE_STACK_SIZE; + } =20 Status =3D gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 1102003a93..0ffad29f1a 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -392,12 +392,9 @@ typedef (EFIAPI *ASM_RELOCATE_AP_LOOP)( IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, - IN UINTN PmCodeSegment, IN UINTN TopOfApStack, IN UINTN NumberToFinish, - IN UINTN Pm16CodeSegment, - IN UINTN SevEsAPJumpTable, - IN UINTN WakeupBuffer + IN UINTN Cr3 ); =20 /** diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm b/UefiCpuPkg/Libr= ary/MpInitLib/X64/AmdSev.nasm index 47fc8e9325..b2d95adf6d 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.nasm @@ -514,4 +514,4 @@ DoHltAmd: jmp DoHltAmd =20 BITS 64 -AsmRelocateApLoopEndAmd: \ No newline at end of file +AsmRelocateApLoopEndAmd: diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Lib= rary/MpInitLib/X64/MpFuncs.nasm index 87b23b482e..78ac5427a7 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm @@ -279,120 +279,42 @@ CProcedureInvoke: RendezvousFunnelProcEnd: =20 ;-------------------------------------------------------------------------= ------------ -; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfAp= Stack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer); +; AsmRelocateApLoop (MwaitSupport, ApTargetCState, TopOfApStack, CountTof= inish, Cr3); +; This function is called during the finalizaiton of Mp initialization be= fore booting +; to OS, and aim to put Aps either in Mwait or HLT. ;-------------------------------------------------------------------------= ------------ -AsmRelocateApLoopStart: -BITS 64 - cmp qword [rsp + 56], 0 ; SevEsAPJumpTable - je NoSevEs - - ; - ; Perform some SEV-ES related setup before leaving 64-bit mode - ; - push rcx - push rdx - - ; - ; Get the RDX reset value using CPUID - ; - mov rax, 1 - cpuid - mov rsi, rax ; Save off the reset value for RDX - - ; - ; Prepare the GHCB for the AP_HLT_LOOP VMGEXIT call - ; - Must be done while in 64-bit long mode so that writes to - ; the GHCB memory will be unencrypted. - ; - No NAE events can be generated once this is set otherwise - ; the AP_RESET_HOLD SW_EXITCODE will be overwritten. - ; - mov rcx, 0xc0010130 - rdmsr ; Retrieve current GHCB address - shl rdx, 32 - or rdx, rax - - mov rdi, rdx - xor rax, rax - mov rcx, 0x800 - shr rcx, 3 - rep stosq ; Clear the GHCB - - mov rax, 0x80000004 ; VMGEXIT AP_RESET_HOLD - mov [rdx + 0x390], rax - mov rax, 114 ; Set SwExitCode valid bit - bts [rdx + 0x3f0], rax - inc rax ; Set SwExitInfo1 valid bit - bts [rdx + 0x3f0], rax - inc rax ; Set SwExitInfo2 valid bit - bts [rdx + 0x3f0], rax +; +----------------+ +; | Cr3 | rsp+40 +; +----------------+ +; | CountTofinish | r9 +; +----------------+ +; | TopOfApStack | r8 +; +----------------+ +; | ApTargetCState | rdx +; +----------------+ +; | MwaitSupport | rcx +; +----------------+ +; | the return | +; +----------------+ low address =20 - pop rdx - pop rcx - -NoSevEs: - cli ; Disable interrupt before switching to 3= 2-bit mode - mov rax, [rsp + 40] ; CountTofinish +AsmRelocateApLoopStart: + mov rax, r9 ; CountTofinish lock dec dword [rax] ; (*CountTofinish)-- =20 - mov r10, [rsp + 48] ; Pm16CodeSegment - mov rax, [rsp + 56] ; SevEsAPJumpTable - mov rbx, [rsp + 64] ; WakeupBuffer - mov rsp, r9 ; TopOfApStack - - push rax ; Save SevEsAPJumpTable - push rbx ; Save WakeupBuffer - push r10 ; Save Pm16CodeSegment - push rcx ; Save MwaitSupport - push rdx ; Save ApTargetCState - - lea rax, [PmEntry] ; rax <- The start address of transition = code - - push r8 - push rax - - ; - ; Clear R8 - R15, for reset, before going into 32-bit mode - ; - xor r8, r8 - xor r9, r9 - xor r10, r10 - xor r11, r11 - xor r12, r12 - xor r13, r13 - xor r14, r14 - xor r15, r15 - - ; - ; Far return into 32-bit mode - ; - retfq - -BITS 32 -PmEntry: - mov eax, cr0 - btr eax, 31 ; Clear CR0.PG - mov cr0, eax ; Disable paging and caches - - mov ecx, 0xc0000080 - rdmsr - and ah, ~ 1 ; Clear LME - wrmsr - mov eax, cr4 - and al, ~ (1 << 5) ; Clear PAE - mov cr4, eax - - pop edx - add esp, 4 - pop ecx, - add esp, 4 + mov rax, [rsp + 40] ; Cr3 + ; Do not push on old stack, since old stack is not mapped + ; in the page table pointed by cr3 + mov cr3, rax + mov rsp, r8 ; TopOfApStack =20 MwaitCheck: cmp cl, 1 ; Check mwait-monitor support jnz HltLoop - mov ebx, edx ; Save C-State to ebx + mov rbx, rdx ; Save C-State to ebx + MwaitLoop: cli - mov eax, esp ; Set Monitor Address + mov rax, rsp ; Set Monitor Address xor ecx, ecx ; ecx =3D 0 xor edx, edx ; edx =3D 0 monitor @@ -402,49 +324,10 @@ MwaitLoop: jmp MwaitLoop =20 HltLoop: - pop edx ; PM16CodeSegment - add esp, 4 - pop ebx ; WakeupBuffer - add esp, 4 - pop eax ; SevEsAPJumpTable - add esp, 4 - cmp eax, 0 ; Check for SEV-ES - je DoHlt - - cli - ; - ; SEV-ES is enabled, use VMGEXIT (GHCB information already - ; set by caller) - ; -BITS 64 - rep vmmcall -BITS 32 - - ; - ; Back from VMGEXIT AP_HLT_LOOP - ; Push the FLAGS/CS/IP values to use - ; - push word 0x0002 ; EFLAGS - xor ecx, ecx - mov cx, [eax + 2] ; CS - push cx - mov cx, [eax] ; IP - push cx - push word 0x0000 ; For alignment, will be discarded - - push edx - push ebx - - mov edx, esi ; Restore RDX reset value - - retf - -DoHlt: cli hlt - jmp DoHlt + jmp HltLoop =20 -BITS 64 AsmRelocateApLoopEnd: =20 ;-------------------------------------------------------------------------= ------------ --=20 2.36.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#97417): https://edk2.groups.io/g/devel/message/97417 Mute This Topic: https://groups.io/mt/95683383/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-