UefiCpuPkg/MpInitLib: Enable 5-level paging for AP when BSP's enabled

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2008

MpInitLib is the library that's responsible to wake up APs to provide
MP PPI and Protocol services.

The patch synchronizes BSP's CR4.LA57 to each AP's CR4.LA57.
Without this change, AP may enter to GP fault when BSP's 5-level page
table is set to AP during AP wakes up.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Eric Dong <eric.dong@intel.com>
This commit is contained in:
Ni, Ray 2019-08-01 17:58:24 +08:00 committed by Eric Dong
parent 1ab7d72651
commit 09f69a877b
4 changed files with 32 additions and 2 deletions

View File

@ -790,6 +790,7 @@ FillExchangeInfoData (
volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo; volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
UINTN Size; UINTN Size;
IA32_SEGMENT_DESCRIPTOR *Selector; IA32_SEGMENT_DESCRIPTOR *Selector;
IA32_CR4 Cr4;
ExchangeInfo = CpuMpData->MpCpuExchangeInfo; ExchangeInfo = CpuMpData->MpCpuExchangeInfo;
ExchangeInfo->Lock = 0; ExchangeInfo->Lock = 0;
@ -814,6 +815,18 @@ FillExchangeInfoData (
ExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits; ExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits;
//
// We can check either CPUID(7).ECX[bit16] or check CR4.LA57[bit12]
// to determin whether 5-Level Paging is enabled.
// CPUID(7).ECX[bit16] shows CPU's capability, CR4.LA57[bit12] shows
// current system setting.
// Using latter way is simpler because it also eliminates the needs to
// check whether platform wants to enable it.
//
Cr4.UintN = AsmReadCr4 ();
ExchangeInfo->Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);
DEBUG ((DEBUG_INFO, "%a: 5-Level Paging = %d\n", gEfiCallerBaseName, ExchangeInfo->Enable5LevelPaging));
// //
// Get the BSP's data of GDT and IDT // Get the BSP's data of GDT and IDT
// //

View File

@ -185,6 +185,10 @@ typedef struct {
UINT16 ModeTransitionSegment; UINT16 ModeTransitionSegment;
UINT32 ModeHighMemory; UINT32 ModeHighMemory;
UINT16 ModeHighSegment; UINT16 ModeHighSegment;
//
// Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.
//
BOOLEAN Enable5LevelPaging;
} MP_CPU_EXCHANGE_INFO; } MP_CPU_EXCHANGE_INFO;
#pragma pack() #pragma pack()

View File

@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR> ; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; SPDX-License-Identifier: BSD-2-Clause-Patent
; ;
; Module Name: ; Module Name:
@ -40,3 +40,4 @@ ModeTransitionMemoryLocation equ LockLocation + 94h
ModeTransitionSegmentLocation equ LockLocation + 98h ModeTransitionSegmentLocation equ LockLocation + 98h
ModeHighMemoryLocation equ LockLocation + 9Ah ModeHighMemoryLocation equ LockLocation + 9Ah
ModeHighSegmentLocation equ LockLocation + 9Eh ModeHighSegmentLocation equ LockLocation + 9Eh
Enable5LevelPagingLocation equ LockLocation + 0A0h

View File

@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> ; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; SPDX-License-Identifier: BSD-2-Clause-Patent
; ;
; Module Name: ; Module Name:
@ -100,6 +100,18 @@ SkipEnableExecuteDisableBit:
; ;
mov eax, cr4 mov eax, cr4
bts eax, 5 bts eax, 5
mov esi, Enable5LevelPagingLocation
cmp byte [ebx + esi], 0
jz SkipEnable5LevelPaging
;
; Enable 5 Level Paging
;
bts eax, 12 ; Set LA57=1.
SkipEnable5LevelPaging:
mov cr4, eax mov cr4, eax
; ;