From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F13041C5D6A for ; Sun, 16 Nov 2025 22:06:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763330764; cv=none; b=dlQ3Oz0+6HpYF2Q8wZfd7GPPHGk6PUN/VvcezeRQNnahw0ZsbRDqpL0tZVnuOBm1Bf7P1enBuusg5wnxuArlrc2sYmCDzYFcFgLsFHo7Ed8Pldzf3OiB3kvM2Wfc7h075Yg1UNoZEBOMVkitZ7V13l2dhpsSh+wS+B8wbhZDL58= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763330764; c=relaxed/simple; bh=NoMZ3Y2ifizfF05AKV3r0/RVY9sTBUE7f9wUu6gFsq4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=lOj5ckUk2GX5gcqFHmjOs84lYUira927q6IUdV+SZbx1lBYHgcePRBtSDCdUEdJ5V+J8J5aCaAISRUiddFQEEjJ5uwJRbfqAscqIVUA6vE7cCLhDwe27XB5YHuN4a6Qoni0bOOjtGAmPpgYZM7oR5O43S2WxMWe6vBPmd0y4EIo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp; spf=pass smtp.mailfrom=0x0f.com; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b=nR6vsPCX; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=thingy.jp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=0x0f.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=thingy.jp header.i=@thingy.jp header.b="nR6vsPCX" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-7aae5f2633dso4144843b3a.3 for ; Sun, 16 Nov 2025 14:06:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=thingy.jp; s=google; t=1763330761; x=1763935561; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=kwPHPRDAP+avrRYrwmR4toIK8fXHAU0A+bdBUwmg6mQ=; b=nR6vsPCXA01Nisf0euLKe3/JbQkoHyHpyRq9Om1eadA8AteOxnkKY7iHNUxV46Lq6d Ppnwlz+gApQdDrfuBW5nR32uijRniMTXQZDZwownc+8dn6BkCx+a/XGlZV8pG4GY4f+O 2DfysV+P0z4QDTtiScC+As9XQ/GcoL/1xPEY8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763330761; x=1763935561; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=kwPHPRDAP+avrRYrwmR4toIK8fXHAU0A+bdBUwmg6mQ=; b=nw/FlT4shfbkyGwystezBMMip7iwQ6XvjNv0aFdw2x1joZh16gf+1gjPyzpbJ+mfq/ wva+j7kdZDRmBMmDSaCv7lI4NSrKbUAcqtzxqCrsEqgXm2+hul16N8DtZq9UBpdYMICh BrRxngpbrFFtstm70mWaJ5g7hlsKM/36geR9di5qkTln2nwvzWrpAkvdbiIjRa4MNiBE KfdevFibfKmEwe8/NPCIx02WJGptY625qkYwyJRsKjlUcZn7ZC5i4oMWtBg6JztIA96s rAfB0amx7sq4Z7EhTNBlot2lNF8AVsic4xFjbGvb7Kf+bvaLNFhiJ4s/9GxOsUkvAhqT qF8g== X-Gm-Message-State: AOJu0YwWHDhdIw//PYLZm36ITWaHjQPgoHrW53jfVVaviywxl08SlJ2e DGOpYwNR7VLpLzgjN1L05BE5k10BHrsVtS3ql096W5pngRZ6Y3zUYDdMpy/eCcpPA/w= X-Gm-Gg: ASbGncvkIKSFs6C7P/1G4IicJTeu8Z31AgqRAyLRbOBL9LIDxhwL4CKcWsrpV/QBJvv PssXJg8IjluSDReJaFc7bA5dJzkMw9DkA3uCRHDd7ZtrXWqC/0YHyuN2f+f/r+GWk7qvblEouln RRf2GWhNjFxoW1q91fhvkiwz5X0cN9Aly8abdPJu7N423Cz7ljNL05sik7MjJmZ3VGZNefPIO+h 7mB5irZgX4XcXY1PEhvM+svb7ulRL3ycmKH1sLnDis/RtL+IjJBDwvn2spcSfReYh6g+d8eOqdl NxjFRNdNcWylvraciXfH+jeXMCk3P//1j76/2iu252rwHFs3Hj8FStgT6ewp2Kux+0jcrAiY/9r aGxWXmBRukU7zRHSTAESU4McoRUmibQKxBW+8KsIm08rgvd5BrwdR31C8xW/BWms7wN8= X-Google-Smtp-Source: AGHT+IG+SSKSih/MoY+IPwcTb2Il/KY16m8hTqsMiKaO5XWtG7/0/rnS2tWfbIWmGccbDy8cZDCyEA== X-Received: by 2002:a05:6a00:c91:b0:7b9:d7c2:fdf9 with SMTP id d2e1a72fcca58-7ba3bb9528dmr10624068b3a.15.1763330761220; Sun, 16 Nov 2025 14:06:01 -0800 (PST) Received: from kinako ([2400:2200:5f7:2c14:5394:bb99:aaf4:3b1c]) by smtp.googlemail.com with ESMTPSA id d2e1a72fcca58-7b927c22c5fsm11023129b3a.67.2025.11.16.14.05.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Nov 2025 14:06:00 -0800 (PST) From: Daniel Palmer To: geert@linux-m68k.org, linux-m68k@lists.linux-m68k.org Cc: linux-kernel@vger.kernel.org, Daniel Palmer Subject: [PATCH] m68k: Implement kernel memory protection Date: Mon, 17 Nov 2025 07:05:08 +0900 Message-ID: <20251116220508.1513445-1-daniel@thingy.jp> X-Mailer: git-send-email 2.51.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- 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 -- 2.51.0