在 2023/1/4 11:10, xianglai li 写道:
> 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.
Can we split the patch into 4 small patches? All the fixes
are mixed together is hard to review :)
regards
bibo,mao
>
> Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org>
> Cc: Bibo Mao <maob...@loongson.cn>
> Cc: Chao Li <lic...@loongson.cn>
> Cc: Leif Lindholm <quic_llind...@quicinc.com>
> Cc: Liming Gao <gaolim...@byosoft.com.cn>
> Cc: Michael D Kinney <michael.d.kin...@intel.com>
> Signed-off-by: xianglai li <lixiang...@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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#97906): https://edk2.groups.io/g/devel/message/97906
Mute This Topic: https://groups.io/mt/96044050/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-