LoongArch architecture development
 help / color / mirror / Atom feed
From: haoran.jiang@linux.dev
To: loongarch@lists.linux.dev
Cc: linux-kernel@vger.kernel.org, chenhuacai@kernel.org,
	kernel@xen0n.name, akpm@linux-foundation.org, jbohac@suse.cz,
	kees@kernel.org, yangtiezhu@loongson.cn,
	Haoran Jiang <jianghaoran@kylinos.cn>
Subject: [PATCH 1/2] LoongArch: Move fixmap page tables to BSS segment
Date: Sat,  6 Jun 2026 21:21:25 +0800	[thread overview]
Message-ID: <20260606132126.562034-2-haoran.jiang@linux.dev> (raw)
In-Reply-To: <20260606132126.562034-1-haoran.jiang@linux.dev>

From: Haoran Jiang <jianghaoran@kylinos.cn>

__set_fixmap() is not only used during initialization
but may also be invoked after the kernel is up.
Before this change, fixmap page tables resided in memblock.
After the change, they are placed in the BSS segment.
Thus, the fixmap becomes usable both during early boot and
after kernel startup.

Signed-off-by: Haoran Jiang <jianghaoran@kylinos.cn>
---
 arch/loongarch/include/asm/fixmap.h |  1 +
 arch/loongarch/kernel/setup.c       |  1 +
 arch/loongarch/mm/init.c            | 71 ++++++++++++++++++++++++++---
 3 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/arch/loongarch/include/asm/fixmap.h b/arch/loongarch/include/asm/fixmap.h
index dce2da6ba787..5a9b04c720bf 100644
--- a/arch/loongarch/include/asm/fixmap.h
+++ b/arch/loongarch/include/asm/fixmap.h
@@ -31,6 +31,7 @@ enum fixed_addresses {
 
 extern void __set_fixmap(enum fixed_addresses idx,
 			 phys_addr_t phys, pgprot_t flags);
+void __init early_fixmap_init(void);
 
 #include <asm-generic/fixmap.h>
 
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 839b23edee87..2724d67a96cc 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -599,6 +599,7 @@ void __init setup_arch(char **cmdline_p)
 	fdt_setup();
 	memblock_init();
 	pagetable_init();
+	early_fixmap_init();
 	bootcmdline_init(cmdline_p);
 	parse_early_param();
 	reserve_initrd_mem();
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 031b39eb081c..4046d31f0266 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -36,6 +36,69 @@
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 
+#define SPAN_NR_ENTRIES(vstart, vend, shift) \
+	((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1)
+
+#define NR_BM_PTE_TABLES \
+	SPAN_NR_ENTRIES(FIXADDR_START, FIXADDR_TOP, PMD_SHIFT)
+
+#define __BM_TABLE_IDX(addr, shift) \
+	(((addr) >> (shift)) - (FIXADDR_START >> (shift)))
+
+#define BM_PTE_TABLE_IDX(addr)  __BM_TABLE_IDX(addr, PMD_SHIFT)
+
+static pte_t bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __page_aligned_bss;
+static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
+static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;
+
+static inline pte_t *fixmap_pte(unsigned long addr)
+{
+	return &bm_pte[BM_PTE_TABLE_IDX(addr)][pte_index(addr)];
+}
+
+void __init early_fixmap_init(void)
+{
+	unsigned long addr = FIXADDR_START;
+	unsigned long end = FIXADDR_TOP;
+
+	pgd_t *pgd = pgd_offset_k(addr);
+	p4d_t *p4d = p4d_offset(pgd, addr);
+	pud_t *pud;
+	pmd_t *pmd;
+
+	unsigned long next;
+
+	if (p4d_none(p4dp_get(p4d))) {
+		pud = bm_pud;
+		p4d_populate(&init_mm, p4d, pud);
+#ifndef __PAGETABLE_PUD_FOLDED
+		pud_init(pud);
+#endif
+}
+
+	pud = pud_offset(p4d, addr);
+	if (pud_none(pudp_get(pud))) {
+		pmd = bm_pmd;
+		pud_populate(&init_mm, pud, pmd);
+#ifndef __PAGETABLE_PMD_FOLDED
+		pmd_init(pmd);
+#endif
+}
+
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		if (!pmd_present(pmdp_get(pmd))) {
+			pte_t *pte;
+
+			pte = bm_pte[BM_PTE_TABLE_IDX(addr)];
+			pmd_populate_kernel(&init_mm, pmd, pte);
+			kernel_pte_init(pte);
+		}
+	} while (pmd++, addr = next, addr != end);
+
+}
+
 int __ref page_is_ram(unsigned long pfn)
 {
 	unsigned long addr = PFN_PHYS(pfn);
@@ -203,7 +266,7 @@ pte_t * __init populate_kernel_pte(unsigned long addr)
 	return pte_offset_kernel(pmd, addr);
 }
 
-void __init __set_fixmap(enum fixed_addresses idx,
+void  __set_fixmap(enum fixed_addresses idx,
 			       phys_addr_t phys, pgprot_t flags)
 {
 	unsigned long addr = __fix_to_virt(idx);
@@ -211,11 +274,7 @@ void __init __set_fixmap(enum fixed_addresses idx,
 
 	BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);
 
-	ptep = populate_kernel_pte(addr);
-	if (!pte_none(ptep_get(ptep))) {
-		pte_ERROR(*ptep);
-		return;
-	}
+	ptep = fixmap_pte(addr);
 
 	if (pgprot_val(flags))
 		set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
-- 
2.25.1


  reply	other threads:[~2026-06-06 13:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-06 13:21 [PATCH 0/2] Enable STRICT_MODULE_RWX haoran.jiang
2026-06-06 13:21 ` haoran.jiang [this message]
2026-06-06 13:21 ` [PATCH 2/2] LoongArch: Enable STRICT_MODULE_RWX for stricter modules memory permissions haoran.jiang
2026-06-06 14:04 ` [PATCH 0/2] Enable STRICT_MODULE_RWX Huacai Chen

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-all 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=20260606132126.562034-2-haoran.jiang@linux.dev \
    --to=haoran.jiang@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=chenhuacai@kernel.org \
    --cc=jbohac@suse.cz \
    --cc=jianghaoran@kylinos.cn \
    --cc=kees@kernel.org \
    --cc=kernel@xen0n.name \
    --cc=linux-kernel@vger.kernel.org \
    --cc=loongarch@lists.linux.dev \
    --cc=yangtiezhu@loongson.cn \
    /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