From: "xianglai" <lixianglai@loongson.cn>
To: devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
Bibo Mao <maobibo@loongson.cn>, Chao Li <lichao@loongson.cn>,
Leif Lindholm <quic_llindhol@quicinc.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Michael D Kinney <michael.d.kinney@intel.com>
Subject: [edk2-platforms][PATCH V1 4/4] Platform/Loongson: Fixed the bug during page table creation.
Date: Wed, 4 Jan 2023 11:10:35 +0800 [thread overview]
Message-ID: <a2d58a894b7d9ccf16bceecbf884967de04193cd.1672801654.git.lixianglai@loongson.cn> (raw)
In-Reply-To: <cover.1672801654.git.lixianglai@loongson.cn>
1.Open the NULL pointer protection policy.
2.Fixed the bug of converting huge page to page entry.
3.Adjust the access level of page entry.
4.Optimize the existence of page entry judgment functions.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Chao Li <lichao@loongson.cn>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: xianglai li <lixianglai@loongson.cn>
---
.../Library/MmuLib/MmuLibCore.c | 123 +++++++++++++-----
.../Library/MmuLib/MmuLibCorePei.c | 1 +
.../LoongArchQemuPkg/Library/MmuLib/page.h | 5 +-
.../Loongson/LoongArchQemuPkg/Loongson.dsc | 2 +
4 files changed, 99 insertions(+), 32 deletions(-)
diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c
index b932e3d568..42f92745be 100644
--- a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c
@@ -449,6 +449,29 @@ GetPteAddress (
return PteOffset (Pmd, Address);
}
+/**
+ Gets the Attributes of Huge Page.
+
+ @param Pmd A pointer to the page middle directory.
+
+ @retval Value of Attributes.
+**/
+UINTN
+GetHugePageAttributes (
+ IN PMD *Pmd
+ )
+{
+ UINTN Attributes;
+ UINTN GlobalFlag;
+ UINTN HugeVal = PMD_VAL(*Pmd);
+
+ Attributes = HugeVal & (~HUGEP_PAGE_MASK);
+ GlobalFlag = ((Attributes & (1 << PAGE_HGLOBAL_SHIFT)) >> PAGE_HGLOBAL_SHIFT) << PAGE_GLOBAL_SHIFT;
+ Attributes &= ~(1 << PAGE_HGLOBAL_SHIFT);
+ Attributes |= GlobalFlag;
+ return Attributes;
+}
+
/**
Establishes a page table entry based on the specified memory region.
@@ -477,13 +500,13 @@ MemoryMapPteRange (
return EFI_OUT_OF_RESOURCES;
}
+ DEBUG ((DEBUG_VERBOSE,
+ "%a %d Address %p End %p Attributes %llx\n",
+ __func__, __LINE__, Address, End, Attributes));
+
do {
UpDate = FALSE;
PteVal = MAKE_PTE (Address, Attributes);
- DEBUG ((DEBUG_VERBOSE,
- "%a %d Address %p PGD_INDEX %p PUD_INDEX %p PMD_INDEX %p PTE_INDEX %p MAKE_PTE %p\n",
- __func__, __LINE__, Address, PGD_INDEX (Address), PUD_INDEX (Address), PMD_INDEX (Address),
- PTE_INDEX (Address), PteVal));
if ((!pte_none (*Pte)) &&
(PTE_VAL(*Pte) != PTE_VAL(PteVal)))
@@ -500,6 +523,61 @@ MemoryMapPteRange (
return EFI_SUCCESS;
}
+/**
+ Convert Huge Page to Page.
+
+ @param Pmd A pointer to the page middle directory.
+ @param Address The memory space start address.
+ @param End The end address of the memory space.
+ @param Attributes Memory space Attributes.
+
+ @retval EFI_SUCCESS The page table entry was created successfully.
+ @retval EFI_OUT_OF_RESOURCES Page table entry establishment failed due to resource exhaustion.
+**/
+EFI_STATUS
+ConvertHugePageToPage (
+ IN PMD *Pmd,
+ IN UINTN Address,
+ IN UINTN End,
+ IN UINTN Attributes
+ )
+{
+ UINTN OldAttributes;
+ UINTN AddressEnd_HugePage;
+ UINTN AddressStart_HugePage;
+ EFI_STATUS Status;
+
+ if ((pmd_none (*Pmd)) ||
+ ((!pmd_none (*Pmd)) &&
+ (!IS_HUGE_PAGE (Pmd->PmdVal))))
+ {
+ Status |= MemoryMapPteRange (Pmd, Address, End, Attributes);
+ } else {
+ OldAttributes = GetHugePageAttributes(Pmd);
+ SetPmd (Pmd, (PTE *)PcdGet64 (PcdInvalidPte));
+ AddressStart_HugePage = Address & PMD_MASK;
+ AddressEnd_HugePage = AddressStart_HugePage + HUGE_PAGE_SIZE;
+ if (End >= AddressEnd_HugePage) {
+ if (Address > AddressStart_HugePage) {
+ Status |= MemoryMapPteRange (Pmd, AddressStart_HugePage, Address, OldAttributes);
+ Status |= MemoryMapPteRange (Pmd, Address, AddressEnd_HugePage, Attributes);
+ } else {
+ Status |= MemoryMapPteRange (Pmd, AddressStart_HugePage, AddressEnd_HugePage, Attributes);
+ }
+ } else {
+ if (Address > AddressStart_HugePage) {
+ Status |= MemoryMapPteRange (Pmd, AddressStart_HugePage, Address, OldAttributes);
+ Status |= MemoryMapPteRange (Pmd, Address, End, Attributes);
+ } else {
+ Status |= MemoryMapPteRange (Pmd, AddressStart_HugePage, End, Attributes);
+ }
+ Status |= MemoryMapPteRange (Pmd, End, AddressEnd_HugePage, OldAttributes);
+ }
+ }
+
+ return Status;
+}
+
/**
Establishes a page middle directory based on the specified memory region.
@@ -520,10 +598,7 @@ MemoryMapPmdRange (
)
{
PMD *Pmd;
- PTE *Pte;
UINTN Next;
- UINTN AddressStart_HugePage;
- UINTN AddressEnd_HugePage;
Pmd = PmdAllocGet (Pud, Address);
if (!Pmd) {
@@ -543,28 +618,7 @@ MemoryMapPmdRange (
SetPmd (Pmd, (PTE *)MAKE_HUGE_PTE (Address, Attributes));
} else {
- if ((pmd_none (*Pmd)) ||
- ((!pmd_none (*Pmd)) &&
- (!IS_HUGE_PAGE (Pmd->PmdVal))))
- {
- if (MemoryMapPteRange (Pmd, Address, Next, Attributes)) {
- return EFI_OUT_OF_RESOURCES;
- }
- } else {
- SetPmd (Pmd, (PTE *)PcdGet64 (PcdInvalidPte));
- AddressStart_HugePage = Address & PMD_MASK;
- AddressEnd_HugePage = AddressStart_HugePage + HUGE_PAGE_SIZE;
- if (MemoryMapPteRange (Pmd, AddressStart_HugePage, AddressEnd_HugePage, Attributes)) {
- return EFI_OUT_OF_RESOURCES;
- }
- Pte = GetPteAddress (AddressStart_HugePage);
- if (Pte == NULL) {
- continue ;
- }
- if (AddressEnd_HugePage > End) {
- Next = End;
- }
- }
+ ConvertHugePageToPage (Pmd, Address, Next, Attributes);
}
} while (Pmd++, Address = Next, Address != End);
@@ -671,7 +725,7 @@ EfiAttributeToLoongArchAttribute (
IN UINTN EfiAttributes
)
{
- UINTN LoongArchAttributes = PAGE_VALID | PAGE_DIRTY | CACHE_CC | PAGE_USER | PAGE_GLOBAL;
+ UINTN LoongArchAttributes = PAGE_VALID | PAGE_DIRTY | CACHE_CC | PLV_KERNEL | PAGE_GLOBAL;
switch (EfiAttributes & EFI_MEMORY_CACHETYPE_MASK) {
case EFI_MEMORY_UC:
LoongArchAttributes |= CACHE_SUC;
@@ -687,10 +741,16 @@ EfiAttributeToLoongArchAttribute (
}
// Write protection attributes
- if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
+ if (((EfiAttributes & EFI_MEMORY_RO) != 0) ||
+ ((EfiAttributes & EFI_MEMORY_WP) != 0))
+ {
LoongArchAttributes &= ~PAGE_DIRTY;
}
+ if (EfiAttributes & EFI_MEMORY_RP) {
+ LoongArchAttributes |= PAGE_NO_READ;
+ }
+
//eXecute protection attribute
if ((EfiAttributes & EFI_MEMORY_XP) != 0) {
LoongArchAttributes |= PAGE_NO_EXEC;
@@ -788,6 +848,7 @@ LoongArchSetMemoryAttributes (
Attributes = EfiAttributeToLoongArchAttribute (Attributes);
DEBUG ((DEBUG_VERBOSE, "%a %d %p %p %p.\n", __func__, __LINE__, BaseAddress , Length, Attributes));
MemoryMapPageRange (BaseAddress, BaseAddress + Length, Attributes);
+ DEBUG ((DEBUG_VERBOSE, "%a %d end.\n", __func__, __LINE__));
return EFI_SUCCESS;
}
diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c
index 32a7fc0beb..491b75552c 100644
--- a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCorePei.c
@@ -21,6 +21,7 @@
#include <Library/QemuFwCfgLib.h>
#include "MmuLibCore.h"
#include <Library/CacheMaintenanceLib.h>
+#include <Library/MmuLib.h>
/**
Return the Virtual Memory Map of your platform
diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h
index 6ab07e7900..927aeb018d 100644
--- a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h
+++ b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h
@@ -42,6 +42,9 @@
#define PFN_MASK (~(((UINTN)(1) << (EFI_PAGE_SHIFT)) - 1) & \
(((UINTN)(1) << (PAGE_PFN_END_SHIFT)) - 1))
+#define HUGEP_PAGE_MASK (~(((UINTN)(1) << (PMD_SHIFT)) - 1) & \
+ (((UINTN)(1) << (PAGE_PFN_END_SHIFT)) - 1))
+
typedef struct { UINTN PgdVal; } PGD;
typedef struct { UINTN PudVal; } PUD;
typedef struct { UINTN PmdVal; } PMD;
@@ -275,6 +278,6 @@ pte_none (
IN PTE pte
)
{
- return (!(PTE_VAL(pte) & (~PAGE_GLOBAL)));
+ return (!(PTE_VAL(pte) & (~PAGE_VALID)));
}
#endif // PAGE_H_
diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
index 650042662d..45be8d146d 100644
--- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
+++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
@@ -365,6 +365,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask | 1
+
################################################################################
#
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
--
2.31.1
next prev parent reply other threads:[~2023-01-04 3:11 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1672801654.git.lixianglai@loongson.cn>
2023-01-04 3:10 ` [edk2-platforms][PATCH V1 1/4] Platform/Loongson: add bootmode support xianglai
2023-01-04 3:10 ` [edk2-platforms][PATCH V1 2/4] Platform/Loongson:add nvme device driver for loongarch xianglai
2023-01-04 3:10 ` [edk2-platforms][PATCH V1 3/4] Platform/Loongson: Support pflash " xianglai
2023-01-04 3:57 ` maobibo
2023-01-04 3:10 ` xianglai [this message]
2023-01-04 4:14 ` [edk2-platforms][PATCH V1 4/4] Platform/Loongson: Fixed the bug during page table creation maobibo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a2d58a894b7d9ccf16bceecbf884967de04193cd.1672801654.git.lixianglai@loongson.cn \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox