From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.31; helo=mga06.intel.com; envelope-from=jian.j.wang@intel.com; receiver=edk2-devel@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (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 AB3F020355227 for ; Wed, 8 Nov 2017 02:48:28 -0800 (PST) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP; 08 Nov 2017 02:52:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,363,1505804400"; d="scan'208";a="173630202" Received: from jwang36-mobl2.ccr.corp.intel.com ([10.239.192.49]) by fmsmga006.fm.intel.com with ESMTP; 08 Nov 2017 02:52:27 -0800 From: Jian J Wang To: edk2-devel@lists.01.org Cc: Eric Dong , Jiewen Yao , Laszlo Ersek Date: Wed, 8 Nov 2017 18:52:24 +0800 Message-Id: <20171108105224.9560-1-jian.j.wang@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 Subject: [PATCH v3] UefiCpuPkg/CpuDxe: Fix multiple entries of RT_CODE in memory map X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Nov 2017 10:48:28 -0000 > v3: > a. Add comment to explain more on updating memory capabilities > b. Fix logic hole in updating attributes > c. Instead of checking illegal memory space address and size, use return > status of gDS->SetMemorySpaceCapabilities() to skip memory block which > cannot be updated with new capabilities. > v2 > a. Fix an issue which will cause setting capability failure if size is smaller > than a page. More than one entry of RT_CODE memory might cause boot problem for some old OSs. This patch will fix this issue to keep OS compatibility as much as possible. More detailed information, please refer to https://bugzilla.tianocore.org/show_bug.cgi?id=753 Cc: Eric Dong Cc: Jiewen Yao Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang --- UefiCpuPkg/CpuDxe/CpuPageTable.c | 48 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTable.c index d312eb66f8..455c713dfc 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.c +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c @@ -789,7 +789,6 @@ RefreshGcdMemoryAttributesFromPaging ( UINT64 BaseAddress; UINT64 PageStartAddress; UINT64 Attributes; - UINT64 Capabilities; BOOLEAN DoUpdate; UINTN Index; @@ -803,7 +802,6 @@ RefreshGcdMemoryAttributesFromPaging ( GetCurrentPagingContext (&PagingContext); DoUpdate = FALSE; - Capabilities = 0; Attributes = 0; BaseAddress = 0; PageLength = 0; @@ -813,6 +811,27 @@ RefreshGcdMemoryAttributesFromPaging ( continue; } + // + // Sync the actual paging related capabilities back to GCD service first. + // As a side effect (good one), this can also help to avoid unnecessary + // memory map entries due to the different capabilities of the same type + // memory, such as multiple RT_CODE and RT_DATA entries in memory map, + // which could cause boot failure of some old Linux distro (before v4.3). + // + Status = gDS->SetMemorySpaceCapabilities ( + MemorySpaceMap[Index].BaseAddress, + MemorySpaceMap[Index].Length, + MemorySpaceMap[Index].Capabilities | + EFI_MEMORY_PAGETYPE_MASK + ); + if (EFI_ERROR (Status)) { + // + // If we cannot udpate the capabilities, we cannot update its + // attributes either. So just simply skip current block of memory. + // + continue; + } + if (MemorySpaceMap[Index].BaseAddress >= (BaseAddress + PageLength)) { // // Current memory space starts at a new page. Resetting PageLength will @@ -826,7 +845,9 @@ RefreshGcdMemoryAttributesFromPaging ( PageLength -= (MemorySpaceMap[Index].BaseAddress - BaseAddress); } - // Sync real page attributes to GCD + // + // Sync actual page attributes to GCD + // BaseAddress = MemorySpaceMap[Index].BaseAddress; MemorySpaceLength = MemorySpaceMap[Index].Length; while (MemorySpaceLength > 0) { @@ -845,8 +866,6 @@ RefreshGcdMemoryAttributesFromPaging ( if (Attributes != (MemorySpaceMap[Index].Attributes & EFI_MEMORY_PAGETYPE_MASK)) { DoUpdate = TRUE; - Attributes |= (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_PAGETYPE_MASK); - Capabilities = Attributes | MemorySpaceMap[Index].Capabilities; } else { DoUpdate = FALSE; } @@ -854,11 +873,20 @@ RefreshGcdMemoryAttributesFromPaging ( Length = MIN (PageLength, MemorySpaceLength); if (DoUpdate) { - gDS->SetMemorySpaceCapabilities (BaseAddress, Length, Capabilities); - gDS->SetMemorySpaceAttributes (BaseAddress, Length, Attributes); - DEBUG ((DEBUG_INFO, "Update memory space attribute: [%02d] %016lx - %016lx (%08lx -> %08lx)\r\n", - Index, BaseAddress, BaseAddress + Length - 1, - MemorySpaceMap[Index].Attributes, Attributes)); + Status = gDS->SetMemorySpaceAttributes ( + BaseAddress, + Length, + (MemorySpaceMap[Index].Attributes + & ~EFI_MEMORY_PAGETYPE_MASK) | Attributes + ); + ASSERT_EFI_ERROR (Status); + DEBUG (( + DEBUG_INFO, + "Update memory space attribute: [%02d] %016lx - %016lx (%016lx -> %016lx)\r\n", + Index, BaseAddress, BaseAddress + Length - 1, + MemorySpaceMap[Index].Attributes, + (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_PAGETYPE_MASK) | Attributes + )); } PageLength -= Length; -- 2.14.1.windows.1