From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from loongson.cn (loongson.cn [114.242.206.163]) by mx.groups.io with SMTP id smtpd.web10.3254.1672801916318129727 for ; Tue, 03 Jan 2023 19:11:56 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: loongson.cn, ip: 114.242.206.163, mailfrom: lixianglai@loongson.cn) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8Bx3+t77rRj7koKAA--.22611S3; Wed, 04 Jan 2023 11:11:55 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Bxc+Vz7rRjbXYTAA--.61792S5; Wed, 04 Jan 2023 11:11:54 +0800 (CST) From: "xianglai" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Bibo Mao , Chao Li , Leif Lindholm , Liming Gao , Michael D Kinney 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 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Bxc+Vz7rRjbXYTAA--.61792S5 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvJXoW3Gr1ftr1rKr1rGw1kAw1DZFb_yoWfWFyxpr ZxCayIkr4UtrZrXFWDXwsI9Fs7Cr98Wa4UJr47tr1Yk3sxXwn3uryqk3W8tr47JryftayU XayrKw47uFZYvrDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bn8Fc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4 AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF 7I0E14v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Cr0_Gr1UM28EF7xvwVC2z280aVCY1x 0267AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E 6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4IE7x kEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x0EwIxGrwCF04k20xvE74AGY7Cv 6cx26rWl4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x 8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE 2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42 xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6xkF 7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvj4RC_MaUUUUU Content-Transfer-Encoding: 8bit 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 Cc: Bibo Mao Cc: Chao Li Cc: Leif Lindholm Cc: Liming Gao Cc: Michael D Kinney Signed-off-by: xianglai li --- .../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 #include "MmuLibCore.h" #include +#include /** 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