public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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


  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