mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Greg Ungerer <gerg@kernel.org>
To: Daniel Palmer <daniel@thingy.jp>,
	geert@linux-m68k.org, linux-m68k@lists.linux-m68k.org
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH] m68k: Implement kernel memory protection
Date: Mon, 17 Nov 2025 13:04:39 +1000	[thread overview]
Message-ID: <e5ff379e-b679-4513-b390-fa9b604999f4@kernel.org> (raw)
In-Reply-To: <20251116220508.1513445-1-daniel@thingy.jp>

Hi Daniel,

On 17/11/25 08:05, Daniel Palmer wrote:
> Every time I boot linux on my various m68k machines I see
> "This architecture does not have kernel memory protection."
> 
> I wondered why this was as some of my machines even have one of
> those fancy MMU doodads. I worked out it was because we don't have
> CONFIG_ARCH_HAS_STRICT_KERNEL_RWX, found kernel_set_cachemode()
> seemed like it had the code for setting some extra flags for
> kernel pages and turned that into something that sets write
> protect for kernel pages.
> 
> So now we can make CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y and
> provide mark_rodata_ro() to mark the kernel text and rodata
> as write protected.
> 
> The test enabled by CONFIG_DEBUG_RODATA_TEST=y says this is
> working, but I've only tested on the virt machine.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>

Seems to work fine on real ColdFire hardware (tested on an M5475 -
that is one that has an MMU):

...
VFS: Mounted root (romfs filesystem) readonly on device 31:0.
Freeing unused kernel image (initmem) memory: 88K
Write protecting kernel text: 0x22000 - 0x393f70
Write protecting kernel read-only data: 0x394000 - 0x450000
Run /sbin/init as init process
Run /etc/init as init process
Run /bin/init as init process
process '/bin/init' started with executable stack
...

Tested-by: Greg Ungerer <gerg@linux-m68k.org>

Regards
Greg



> ---
>   arch/m68k/Kconfig   |  1 +
>   arch/m68k/mm/init.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 70 insertions(+)
> 
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index 11835eb59d94..2137fd19ffbd 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -8,6 +8,7 @@ config M68K
>   	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
>   	select ARCH_HAS_CURRENT_STACK_POINTER
>   	select ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA && !COLDFIRE
> +	select ARCH_HAS_STRICT_KERNEL_RWX if MMU
>   	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if M68K_NONCOHERENT_DMA
>   	select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
>   	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
> diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
> index 488411af1b3f..bc1147f25624 100644
> --- a/arch/m68k/mm/init.c
> +++ b/arch/m68k/mm/init.c
> @@ -123,3 +123,72 @@ void __init mem_init(void)
>   {
>   	init_pointer_tables();
>   }
> +
> +#ifdef CONFIG_MMU
> +/*
> + * Based on (basically copy/pasted) kernel_set_cachemode() because
> + * presumably that is correct and covers the required differences.
> + */
> +static void __mark_ro_data(unsigned long virtaddr, ssize_t size)
> +{
> +	pgd_t *pgd_dir;
> +	p4d_t *p4d_dir;
> +	pud_t *pud_dir;
> +	pmd_t *pmd_dir;
> +	pte_t *pte_dir;
> +
> +	while (size > 0) {
> +		pgd_dir = pgd_offset_k(virtaddr);
> +		p4d_dir = p4d_offset(pgd_dir, virtaddr);
> +		pud_dir = pud_offset(p4d_dir, virtaddr);
> +		if (pud_bad(*pud_dir)) {
> +			pud_clear(pud_dir);
> +			return;
> +		}
> +		pmd_dir = pmd_offset(pud_dir, virtaddr);
> +
> +#if CONFIG_PGTABLE_LEVELS == 3
> +		if (CPU_IS_020_OR_030) {
> +			unsigned long pmd = pmd_val(*pmd_dir);
> +
> +			if ((pmd & _DESCTYPE_MASK) == _PAGE_PRESENT) {
> +				*pmd_dir = __pmd(pmd | _PAGE_RONLY);
> +				virtaddr += PMD_SIZE;
> +				size -= PMD_SIZE;
> +				continue;
> +			}
> +		}
> +#endif
> +
> +		if (pmd_bad(*pmd_dir)) {
> +			pmd_clear(pmd_dir);
> +			return;
> +		}
> +		pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
> +
> +		set_pte(pte_dir, pte_wrprotect(*pte_dir));
> +		virtaddr += PAGE_SIZE;
> +		size -= PAGE_SIZE;
> +	}
> +}
> +
> +void mark_rodata_ro(void)
> +{
> +	unsigned long start;
> +	unsigned long end;
> +
> +	/* kernel text - kernel_pg_dir lives in the first page, so skip that */
> +	start = (unsigned long) _stext + PAGE_SIZE;
> +	end = (unsigned long) _etext;
> +	pr_info("Write protecting kernel text: 0x%lx - 0x%lx\n", start, end);
> +	__mark_ro_data(start, end - start);
> +
> +	/* ro data */
> +	start = (unsigned long) __start_rodata;
> +	end = (unsigned long) __end_rodata;
> +	pr_info("Write protecting kernel read-only data: 0x%lx - 0x%lx\n", start, end);
> +	__mark_ro_data(start, end - start);
> +
> +	flush_tlb_all();
> +}
> +#endif


  reply	other threads:[~2025-11-17  3:04 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-16 22:05 Daniel Palmer
2025-11-17  3:04 ` Greg Ungerer [this message]
2025-11-17  9:42   ` Daniel Palmer
2025-11-17 17:41     ` Michael Schmitz
2025-11-17 22:01       ` Daniel Palmer
2025-11-17 23:14         ` Michael Schmitz
2025-11-18 10:55           ` Daniel Palmer

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=e5ff379e-b679-4513-b390-fa9b604999f4@kernel.org \
    --to=gerg@kernel.org \
    --cc=daniel@thingy.jp \
    --cc=geert@linux-m68k.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    /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

all inboxes | Powered by JetHome®