From nobody Mon Jun 8 05:24:56 2026 Received: from out-181.mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DCD9122D781 for ; Sat, 6 Jun 2026 13:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780752137; cv=none; b=FUs70TQJsysm7pFNchkhEwQlECAxU3vCk4VMqsMyUWZN7wj32fxx/aH6qnvKDW22989A3Kj9+xuZjbcvt8theWjVnj1xFJ/lzcPUutqETjKQRDEeXQqkXdTZpHax/xLwlk2oyqODyd0nOAp9ufn26v4CwUoPoZym3yHIuRmywgE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780752137; c=relaxed/simple; bh=YIgr/dfUitpAIGyrCeaAZGqybSo3r1gid59+ebeXEUY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aD9c0b2W6rQWtwTOZPKoMWSdBbuGFJSeLKk8+AlglLEa2A36bIvsmsu2pQ7F2Nate+EW2jM/dkfBkrp5cz/vOwqrsmoVUgsVXiiiV91yJCX6+8963ROv80WHtj9kzfnp9pxRxFCjpXB1lG5i4GQvy19GWe2B791q1cWoN/xdZx0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=g+6HDHxG; arc=none smtp.client-ip=91.218.175.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="g+6HDHxG" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780752133; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UFxVxYHIFN149JVmey/A/yRZIp9tC2WDA/G0gT2sg40=; b=g+6HDHxGrvGzzxOUMk1Cl+/leL9T5DZKWqByOIV3DQ7zjTp++tuMlrC0ZSz6pSNdHVUgS4 DJf+Ye4QM8yk9bXPmdLoPZFCi4ALfM39h+/8F5waPW+u/1GkY6/211SLvolvlaE2nHEfnJ 9wCplMQP4W6NbfjMeYCwNcLW1yLY6iA= 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 Subject: [PATCH 1/2] LoongArch: Move fixmap page tables to BSS segment Date: Sat, 6 Jun 2026 21:21:25 +0800 Message-Id: <20260606132126.562034-2-haoran.jiang@linux.dev> In-Reply-To: <20260606132126.562034-1-haoran.jiang@linux.dev> References: <20260606132126.562034-1-haoran.jiang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Haoran Jiang __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 --- 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/a= sm/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 { =20 extern void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags); +void __init early_fixmap_init(void); =20 #include =20 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 #include =20 +#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 =3D FIXADDR_START; + unsigned long end =3D FIXADDR_TOP; + + pgd_t *pgd =3D pgd_offset_k(addr); + p4d_t *p4d =3D p4d_offset(pgd, addr); + pud_t *pud; + pmd_t *pmd; + + unsigned long next; + + if (p4d_none(p4dp_get(p4d))) { + pud =3D bm_pud; + p4d_populate(&init_mm, p4d, pud); +#ifndef __PAGETABLE_PUD_FOLDED + pud_init(pud); +#endif +} + + pud =3D pud_offset(p4d, addr); + if (pud_none(pudp_get(pud))) { + pmd =3D bm_pmd; + pud_populate(&init_mm, pud, pmd); +#ifndef __PAGETABLE_PMD_FOLDED + pmd_init(pmd); +#endif +} + + pmd =3D pmd_offset(pud, addr); + do { + next =3D pmd_addr_end(addr, end); + if (!pmd_present(pmdp_get(pmd))) { + pte_t *pte; + + pte =3D bm_pte[BM_PTE_TABLE_IDX(addr)]; + pmd_populate_kernel(&init_mm, pmd, pte); + kernel_pte_init(pte); + } + } while (pmd++, addr =3D next, addr !=3D end); + +} + int __ref page_is_ram(unsigned long pfn) { unsigned long addr =3D PFN_PHYS(pfn); @@ -203,7 +266,7 @@ pte_t * __init populate_kernel_pte(unsigned long addr) return pte_offset_kernel(pmd, addr); } =20 -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 =3D __fix_to_virt(idx); @@ -211,11 +274,7 @@ void __init __set_fixmap(enum fixed_addresses idx, =20 BUG_ON(idx <=3D FIX_HOLE || idx >=3D __end_of_fixed_addresses); =20 - ptep =3D populate_kernel_pte(addr); - if (!pte_none(ptep_get(ptep))) { - pte_ERROR(*ptep); - return; - } + ptep =3D fixmap_pte(addr); =20 if (pgprot_val(flags)) set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags)); --=20 2.25.1 From nobody Mon Jun 8 05:24:56 2026 Received: from out-179.mta0.migadu.com (out-179.mta0.migadu.com [91.218.175.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1012133E351 for ; Sat, 6 Jun 2026 13:22:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780752141; cv=none; b=ePtY9cxVvhFX+VsPtHRhw/syUdUgqmgJBD0OcEgOy3EO9v3t6UEZ4eM88OVln3sp49tnWhQnQHEXozhld6TdUjJF4MxfC/gLurWaGOLu1wMm6QR+k4lzVulW4NyMpc0DZqwg9XFewkcd6KnJ+43vhTq5VfhUCTyTAmbbxAv1pMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780752141; c=relaxed/simple; bh=cGYAXNTu1qL+6NlNoQgQZsLFZ9jLAeaaG17bz5cBxEY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SyMxQoL73C8BOTMrtQtcGfLD9vpdVOVI1kplX43hsVFkMQ4aHfOUwEpNB4ldxAHB3RjiDuyb5GcdGairChXVLn0Z3VRx6SamWtVXNJ7i6gs598Tf5f5DqXIhL11RmK8j010Vxpaext2C61EmBneJYYgDiGQKRDBPSkHultwQzrA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=MrPx1NyW; arc=none smtp.client-ip=91.218.175.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="MrPx1NyW" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780752138; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QYRv0TFk5ixGCSvlT9n2D6Lg3SOtx0nM5GvZWeV4Xxc=; b=MrPx1NyWk3lsbvnBk7H+LV+6XYbw35POy3tNI79lVIAGwVPzowNRal+3gtR+8FuXuJoLl/ jo4kfTINQN3zmu4/jFlsMxuxs4yJFHXOJ4u38wBLB+mpjiPmtT4P2sLG0ZIaFx/cs5TW0R 4MAapgjGRk6IRx5qwVkaZSHmh6g3iTk= 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 Subject: [PATCH 2/2] LoongArch: Enable STRICT_MODULE_RWX for stricter modules memory permissions Date: Sat, 6 Jun 2026 21:21:26 +0800 Message-Id: <20260606132126.562034-3-haoran.jiang@linux.dev> In-Reply-To: <20260606132126.562034-1-haoran.jiang@linux.dev> References: <20260606132126.562034-1-haoran.jiang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Haoran Jiang Enable STRICT_MODULE_RWX to enforce strict memory permissions on modules,making the code region non-writable, the data region non-executable, and the read-only data region both non-writable and non-executable.Add patch_map interface to temporarily map read-only code sections via fixmap, enabling runtime code patching while preserving memory protection after modifications Signed-off-by: Haoran Jiang --- arch/loongarch/Kconfig | 2 ++ arch/loongarch/include/asm/fixmap.h | 1 + arch/loongarch/kernel/inst.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 606597da46b8..40d748a13c50 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -27,6 +27,7 @@ config LOONGARCH select ARCH_HAS_PTE_SPECIAL if 64BIT select ARCH_HAS_SET_MEMORY select ARCH_HAS_SET_DIRECT_MAP + select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN select ARCH_HAS_VDSO_ARCH_DATA @@ -197,6 +198,7 @@ config LOONGARCH select NUMA_MEMBLKS if NUMA select OF select OF_EARLY_FLATTREE + select ARCH_OPTIONAL_KERNEL_RWX select PCI select PCI_DOMAINS_GENERIC select PCI_ECAM if ACPI diff --git a/arch/loongarch/include/asm/fixmap.h b/arch/loongarch/include/a= sm/fixmap.h index 5a9b04c720bf..7d174eafdc21 100644 --- a/arch/loongarch/include/asm/fixmap.h +++ b/arch/loongarch/include/asm/fixmap.h @@ -22,6 +22,7 @@ enum fixed_addresses { FIX_KMAP_END =3D FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1, #endif FIX_EARLYCON_MEM_BASE, + FIX_TEXT_POKE0, __end_of_fixed_addresses }; =20 diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 0b9228b7c13a..7c4f60a7e892 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -9,9 +9,33 @@ =20 #include #include +#include =20 static DEFINE_RAW_SPINLOCK(patch_lock); =20 +static void __kprobes *patch_map(void *addr, const unsigned int fixmap) +{ + phys_addr_t phys; + + if ((unsigned long)addr < vm_map_base) { + return addr; + } else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) { + struct page *page =3D vmalloc_to_page(addr); + + BUG_ON(!page); + phys =3D page_to_phys(page) + offset_in_page(addr); + } else { + return addr; + } + + return (void *)set_fixmap_offset(fixmap, phys); +} + +static void __kprobes patch_unmap(int fixmap) +{ + clear_fixmap(fixmap); +} + void simu_pc(struct pt_regs *regs, union loongarch_instruction insn) { unsigned long pc =3D regs->csr_era; @@ -208,12 +232,15 @@ int larch_insn_write(void *addr, u32 insn) { int ret; unsigned long flags =3D 0; + void *waddr =3D addr; =20 if ((unsigned long)addr & 3) return -EINVAL; =20 raw_spin_lock_irqsave(&patch_lock, flags); - ret =3D copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE); + waddr =3D patch_map(addr, FIX_TEXT_POKE0); + ret =3D copy_to_kernel_nofault(waddr, &insn, LOONGARCH_INSN_SIZE); + patch_unmap(FIX_TEXT_POKE0); raw_spin_unlock_irqrestore(&patch_lock, flags); =20 return ret; --=20 2.25.1