summaryrefslogtreecommitdiffstats
path: root/arch/m68k/mm/cache.c
diff options
context:
space:
mode:
authorKees Cook <kees+treewide@kernel.org>2026-09-02 15:31:14 -0700
committerKees Cook <kees@kernel.org>2026-09-04 21:37:00 -0700
commit3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d (patch)
treec65086f9bdcd48c6360fb7cb4598bca084da1f32 /arch/m68k/mm/cache.c
downloadlinux-stable-3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d.tar.gz
linux-stable-3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d.zip
treewide: refresh kmalloc_obj() conversionsgrafted
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org>
Diffstat (limited to 'arch/m68k/mm/cache.c')
-rw-r--r--arch/m68k/mm/cache.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c
new file mode 100644
index 000000000..dde978e66
--- /dev/null
+++ b/arch/m68k/mm/cache.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/m68k/mm/cache.c
+ *
+ * Instruction cache handling
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
+
+static unsigned long virt_to_phys_slow(unsigned long vaddr)
+{
+ if (CPU_IS_060) {
+ unsigned long paddr;
+
+ /* The PLPAR instruction causes an access error if the translation
+ * is not possible. To catch this we use the same exception mechanism
+ * as for user space accesses in <asm/uaccess.h>. */
+ asm volatile (".chip 68060\n"
+ "1: plpar (%0)\n"
+ ".chip 68k\n"
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "3: sub.l %0,%0\n"
+ " jra 2b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 1b,3b\n"
+ ".previous"
+ : "=a" (paddr)
+ : "0" (vaddr));
+ return paddr;
+ } else if (CPU_IS_040) {
+ unsigned long mmusr;
+
+ asm volatile (".chip 68040\n\t"
+ "ptestr (%1)\n\t"
+ "movec %%mmusr, %0\n\t"
+ ".chip 68k"
+ : "=r" (mmusr)
+ : "a" (vaddr));
+
+ if (mmusr & MMU_R_040)
+ return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
+ } else {
+ WARN_ON_ONCE(!CPU_IS_040_OR_060);
+ }
+ return 0;
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
+void flush_icache_user_range(unsigned long address, unsigned long endaddr)
+{
+ if (CPU_IS_COLDFIRE) {
+ unsigned long start, end;
+ start = address & ICACHE_SET_MASK;
+ end = endaddr & ICACHE_SET_MASK;
+ if (start > end) {
+ flush_cf_icache(0, end);
+ end = ICACHE_MAX_ADDR;
+ }
+ flush_cf_icache(start, end);
+ } else if (CPU_IS_040_OR_060) {
+ address &= PAGE_MASK;
+
+ do {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys_slow(address)));
+ address += PAGE_SIZE;
+ } while (address < endaddr);
+ } else {
+ unsigned long tmp;
+ asm volatile ("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+void flush_icache_range(unsigned long address, unsigned long endaddr)
+{
+ set_fc(SUPER_DATA);
+ flush_icache_user_range(address, endaddr);
+ set_fc(USER_DATA);
+}
+EXPORT_SYMBOL(flush_icache_range);
+
+void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long addr, int len)
+{
+ if (CPU_IS_COLDFIRE) {
+ unsigned long start, end;
+ start = addr & ICACHE_SET_MASK;
+ end = (addr + len) & ICACHE_SET_MASK;
+ if (start > end) {
+ flush_cf_icache(0, end);
+ end = ICACHE_MAX_ADDR;
+ }
+ flush_cf_icache(start, end);
+
+ } else if (CPU_IS_040_OR_060) {
+ asm volatile ("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (page_to_phys(page)));
+ } else {
+ unsigned long tmp;
+ asm volatile ("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+