From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 17A8C81EBD for ; Wed, 23 Nov 2016 06:01:46 -0800 (PST) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga104.fm.intel.com with ESMTP; 23 Nov 2016 06:01:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,538,1473145200"; d="scan'208";a="904743596" Received: from jfan12-desk.ccr.corp.intel.com ([10.239.9.5]) by orsmga003.jf.intel.com with ESMTP; 23 Nov 2016 06:01:44 -0800 From: Jeff Fan To: edk2-devel@lists.01.org Cc: Laszlo Ersek , Feng Tian , Michael D Kinney Date: Wed, 23 Nov 2016 22:01:37 +0800 Message-Id: <20161123140138.15976-3-jeff.fan@intel.com> X-Mailer: git-send-email 2.9.3.windows.2 In-Reply-To: <20161123140138.15976-1-jeff.fan@intel.com> References: <20161123140138.15976-1-jeff.fan@intel.com> Subject: [PATCH 2/3] UefiCpuPkg/DxeMpLib: Allocate new safe stack < 4GB X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2016 14:01:46 -0000 For long mode DXE, we will disable paging on AP to protected mode to execute AP safe loop code in ACPI NVS range under 4GB. But we forget to allocate stack for AP under 4GB and AP still are using original AP stack. If original AP stack is larger than 4GB, it cannot be used after AP is transferred to protected mode. Moreover, even though AP stack is always under 4GB on protected mode DXE, AP stack(in BootServiceData) maybe crashed by OS after Exit Boot Service event. This fix is to allocate ACPI NVS range under 4GB together with AP safe loop code. APs will switch to new stack at beginning of safe loop code. Cc: Laszlo Ersek Cc: Feng Tian Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan --- UefiCpuPkg/Library/MpInitLib/DxeMpLib.c | 19 +++++++++++++++++-- UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm | 9 +++++++-- UefiCpuPkg/Library/MpInitLib/MpLib.h | 3 ++- UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm | 3 +++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index a0d5eeb..d0f9f7e 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -18,6 +18,7 @@ #include #define AP_CHECK_INTERVAL (EFI_TIMER_PERIOD_MILLISECONDS (100)) +#define AP_SAFT_STACK_SIZE 128 CPU_MP_DATA *mCpuMpData = NULL; EFI_EVENT mCheckAllApsEvent = NULL; @@ -25,6 +26,7 @@ EFI_EVENT mMpInitExitBootServicesEvent = NULL; EFI_EVENT mLegacyBootEvent = NULL; volatile BOOLEAN mStopCheckAllApsStatus = TRUE; VOID *mReservedApLoopFunc = NULL; +UINTN mReservedTopOfApStack; /** Get the pointer to CPU MP Data structure. @@ -241,11 +243,18 @@ RelocateApLoop ( CPU_MP_DATA *CpuMpData; BOOLEAN MwaitSupport; ASM_RELOCATE_AP_LOOP AsmRelocateApLoopFunc; + UINTN ProcessorNumber; + MpInitLibWhoAmI (&ProcessorNumber); CpuMpData = GetCpuMpData (); MwaitSupport = IsMwaitSupport (); AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc; - AsmRelocateApLoopFunc (MwaitSupport, CpuMpData->ApTargetCState, CpuMpData->PmCodeSegment); + AsmRelocateApLoopFunc ( + MwaitSupport, + CpuMpData->ApTargetCState, + CpuMpData->PmCodeSegment, + mReservedTopOfApStack - ProcessorNumber * AP_SAFT_STACK_SIZE + ); // // It should never reach here // @@ -289,6 +298,7 @@ InitMpGlobalData ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Address; + UINTN ApSafeBufferSize; SaveCpuMpData (CpuMpData); @@ -307,16 +317,21 @@ InitMpGlobalData ( // Allocating it in advance since memory services are not available in // Exit Boot Services callback function. // + ApSafeBufferSize = CpuMpData->AddressMap.RelocateApLoopFuncSize; + ApSafeBufferSize += CpuMpData->CpuCount * AP_SAFT_STACK_SIZE; + Address = BASE_4GB - 1; Status = gBS->AllocatePages ( AllocateMaxAddress, EfiReservedMemoryType, - EFI_SIZE_TO_PAGES (sizeof (CpuMpData->AddressMap.RelocateApLoopFuncSize)), + EFI_SIZE_TO_PAGES (ApSafeBufferSize), &Address ); ASSERT_EFI_ERROR (Status); mReservedApLoopFunc = (VOID *) (UINTN) Address; ASSERT (mReservedApLoopFunc != NULL); + mReservedTopOfApStack = (UINTN) Address + EFI_SIZE_TO_PAGES (ApSafeBufferSize) * SIZE_4KB; + ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0); CopyMem ( mReservedApLoopFunc, CpuMpData->AddressMap.RelocateApLoopFuncAddress, diff --git a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm index 64e51d8..4e55760 100644 --- a/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm @@ -217,14 +217,19 @@ RendezvousFunnelProcEnd: global ASM_PFX(AsmRelocateApLoop) ASM_PFX(AsmRelocateApLoop): AsmRelocateApLoopStart: - cmp byte [esp + 4], 1 + push ebp + mov ebp, esp + mov ecx, [ebp + 8] ; MwaitSupport + mov ebx, [ebp + 12] ; ApTargetCState + mov esp, [ebp + 20] ; TopOfApStack + cmp cl, 1 ; Check mwait-monitor support jnz HltLoop MwaitLoop: mov eax, esp xor ecx, ecx xor edx, edx monitor - mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4] + mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4] shl eax, 4 mwait jmp MwaitLoop diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index f73a469..e6dea18 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -250,7 +250,8 @@ VOID (EFIAPI * ASM_RELOCATE_AP_LOOP) ( IN BOOLEAN MwaitSupport, IN UINTN ApTargetCState, - IN UINTN PmCodeSegment + IN UINTN PmCodeSegment, + IN UINTN TopOfApStack ); /** diff --git a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm index aaabb50..7c8fa45 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm +++ b/UefiCpuPkg/Library/MpInitLib/X64/MpFuncs.nasm @@ -224,6 +224,9 @@ RendezvousFunnelProcEnd: global ASM_PFX(AsmRelocateApLoop) ASM_PFX(AsmRelocateApLoop): AsmRelocateApLoopStart: + push rbp + mov rbp, rsp + mov rsp, r9 push rcx push rdx -- 2.9.3.windows.2