lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 16 Jul 2020 16:40:58 -0700
From:   Atish Patra <atish.patra@....com>
To:     linux-kernel@...r.kernel.org
Cc:     Atish Patra <atish.patra@....com>, Anup Patel <anup.patel@....com>,
        Ard Biesheuvel <ardb@...nel.org>,
        Arnd Bergmann <arnd@...db.de>,
        Greentime Hu <greentime.hu@...ive.com>,
        Kees Cook <keescook@...omium.org>, linux-efi@...r.kernel.org,
        linux-riscv@...ts.infradead.org,
        Mark Rutland <mark.rutland@....com>,
        Masahiro Yamada <masahiroy@...nel.org>,
        Mike Rapoport <rppt@...ux.ibm.com>,
        Palmer Dabbelt <palmer@...belt.com>,
        Paul Walmsley <paul.walmsley@...ive.com>,
        Will Deacon <will@...nel.org>, Zong Li <zong.li@...ive.com>,
        Heinrich Schuchardt <xypron.glpk@....de>,
        linux-arm-kernel@...ts.infradead.org
Subject: [RFT PATCH v3 3/9] RISC-V: Implement late mapping page table allocation functions

Currently, page table setup is done during setup_va_final where fixmap can
be used to create the temporary mappings. The physical frame is allocated
from memblock_alloc_* functions. However, this won't work if page table
mapping needs to be created for a different mm context (i.e. efi mm) at
a later point of time.

Use generic kernel page allocation function & macros for any mapping
after setup_vm_final.

Signed-off-by: Atish Patra <atish.patra@....com>
---
 arch/riscv/mm/init.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 62c90161765f..9f3129c76985 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -209,6 +209,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
 pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
 pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
 static bool mmu_enabled;
+static bool late_mapping;
 
 #define MAX_EARLY_MAPPING_SIZE	SZ_128M
 
@@ -233,7 +234,9 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
 
 static pte_t *__init get_pte_virt(phys_addr_t pa)
 {
-	if (mmu_enabled) {
+	if (late_mapping)
+		return (pte_t *) __va(pa);
+	else if (mmu_enabled) {
 		clear_fixmap(FIX_PTE);
 		return (pte_t *)set_fixmap_offset(FIX_PTE, pa);
 	} else {
@@ -243,13 +246,19 @@ static pte_t *__init get_pte_virt(phys_addr_t pa)
 
 static phys_addr_t __init alloc_pte(uintptr_t va)
 {
+	unsigned long vaddr;
 	/*
 	 * We only create PMD or PGD early mappings so we
 	 * should never reach here with MMU disabled.
 	 */
 	BUG_ON(!mmu_enabled);
-
-	return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
+	if (late_mapping) {
+		vaddr = __get_free_page(GFP_KERNEL);
+		if (!vaddr || !pgtable_pte_page_ctor(virt_to_page(vaddr)))
+			BUG();
+		return __pa(vaddr);
+	} else
+		return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
 }
 
 static void __init create_pte_mapping(pte_t *ptep,
@@ -278,7 +287,9 @@ pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE);
 
 static pmd_t *__init get_pmd_virt(phys_addr_t pa)
 {
-	if (mmu_enabled) {
+	if (late_mapping)
+		return (pmd_t *) __va(pa);
+	else if (mmu_enabled) {
 		clear_fixmap(FIX_PMD);
 		return (pmd_t *)set_fixmap_offset(FIX_PMD, pa);
 	} else {
@@ -289,8 +300,13 @@ static pmd_t *__init get_pmd_virt(phys_addr_t pa)
 static phys_addr_t __init alloc_pmd(uintptr_t va)
 {
 	uintptr_t pmd_num;
+	unsigned long vaddr;
 
-	if (mmu_enabled)
+	if (late_mapping) {
+		vaddr = __get_free_page(GFP_KERNEL);
+		BUG_ON(!vaddr);
+		return __pa(vaddr);
+	} else if (mmu_enabled)
 		return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
 
 	pmd_num = (va - PAGE_OFFSET) >> PGDIR_SHIFT;
@@ -528,6 +544,9 @@ static void __init setup_vm_final(void)
 	/* Move to swapper page table */
 	csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
 	local_flush_tlb_all();
+
+	/* generic page allocation function must be used to setup page table */
+	late_mapping = true;
 }
 #else
 void *dtb_early_va __initdata;
-- 
2.24.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ