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.77637.1673579905161148000 for ; Thu, 12 Jan 2023 19:18:26 -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 _____8CxjfB_zcBjPWABAA--.4798S3; Fri, 13 Jan 2023 11:18:23 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Axvr5VzcBjisEYAA--.49868S9; Fri, 13 Jan 2023 11:18:23 +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 V4 7/8] Platform/Loongson: Optimize the huge page and page entry conversion. Date: Fri, 13 Jan 2023 11:17:37 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Axvr5VzcBjisEYAA--.49868S9 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjvJXoW3Gr1ftr1UZF17GFyUCF15urg_yoWxJFy5pr 9xCayxK3yUtrZrXFWkXwsI9r4DCr98Wa48Jr42yw1Fy3s8Xwn3uryqkr10qr47JFyfta1U Xay3tw47CFZ5X37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU bnkFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4 AK67xGY2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF 7I0E14v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7 CjxVAFwI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2 zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VCjz48v1sIEY20_WwAm72CE4IkC6x 0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxF aVAv8VWrMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxV Cjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY 6xIIjxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6x AIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Cr0_Gr1UMIIF0xvEx4A2jsIE c7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0zRVWlkUUUUU= Content-Transfer-Encoding: 8bit Optimize the process of converting huge pages to page table entries. 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 | 109 +++++++++++++----- .../LoongArchQemuPkg/Library/MmuLib/page.h | 3 + 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/MmuLibCore.c index 9e2bd3344a..dac38c63f2 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,55 @@ 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 HugePageEnd; + UINTN HugePageStart; + EFI_STATUS Status; + + if ((pmd_none (*Pmd)) || + (!IS_HUGE_PAGE (Pmd->PmdVal))) + { + Status |= MemoryMapPteRange (Pmd, Address, End, Attributes); + } else { + OldAttributes = GetHugePageAttributes(Pmd); + SetPmd (Pmd, (PTE *)PcdGet64 (PcdInvalidPte)); + HugePageStart = Address & PMD_MASK; + HugePageEnd = HugePageStart + HUGE_PAGE_SIZE; + ASSERT (HugePageEnd >= End); + + if (Address > HugePageStart) { + Status |= MemoryMapPteRange (Pmd, HugePageStart, Address, OldAttributes); + } + + Status |= MemoryMapPteRange (Pmd, Address, End, Attributes); + + if (End < HugePageEnd) { + Status |= MemoryMapPteRange (Pmd, End, HugePageEnd, OldAttributes); + } + } + + return Status; +} + /** Establishes a page middle directory based on the specified memory region. @@ -520,10 +592,7 @@ MemoryMapPmdRange ( ) { PMD *Pmd; - PTE *Pte; UINTN Next; - UINTN AddressStart_HugePage; - UINTN AddressEnd_HugePage; Pmd = PmdAllocGet (Pud, Address); if (!Pmd) { @@ -534,7 +603,7 @@ MemoryMapPmdRange ( Next = PMD_ADDRESS_END (Address, End); if (((Address & (~PMD_MASK)) == 0) && ((Next & (~PMD_MASK)) == 0) && - (pmd_none (*Pmd))) + (pmd_none (*Pmd) || IS_HUGE_PAGE (Pmd->PmdVal))) { DEBUG ((DEBUG_VERBOSE, "%a %d Address %p PGD_INDEX %p PUD_INDEX %p PMD_INDEX %p MAKE_HUGE_PTE %p\n", @@ -543,28 +612,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); @@ -788,6 +836,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/page.h b/Platform/Loongson/LoongArchQemuPkg/Library/MmuLib/page.h index 84c7c13919..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; -- 2.31.1