m68k: Remove set_fs()
authorChristoph Hellwig <hch@lst.de>
Thu, 16 Sep 2021 07:04:05 +0000 (09:04 +0200)
committerGeert Uytterhoeven <geert@linux-m68k.org>
Fri, 24 Sep 2021 11:35:07 +0000 (13:35 +0200)
Add a m68k-only set_fc helper to set the SFC and DFC registers for the
few places that need to override it for special MM operations, but
disconnect that from the deprecated kernel-wide set_fs() API.

Note that the SFC/DFC registers are context switched, so there is no need
to disable preemption.

Partially based on an earlier patch from
Linus Torvalds <torvalds@linux-foundation.org>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Link: https://lore.kernel.org/r/20210916070405.52750-7-hch@lst.de
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
22 files changed:
arch/m68k/68000/entry.S
arch/m68k/Kconfig
arch/m68k/coldfire/entry.S
arch/m68k/include/asm/processor.h
arch/m68k/include/asm/segment.h [deleted file]
arch/m68k/include/asm/thread_info.h
arch/m68k/include/asm/tlbflush.h
arch/m68k/include/asm/uaccess.h
arch/m68k/kernel/asm-offsets.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/process.c
arch/m68k/kernel/traps.c
arch/m68k/mac/misc.c
arch/m68k/mm/cache.c
arch/m68k/mm/init.c
arch/m68k/mm/kmap.c
arch/m68k/mm/memory.c
arch/m68k/mm/motorola.c
arch/m68k/sun3/config.c
arch/m68k/sun3/mmu_emu.c
arch/m68k/sun3/sun3ints.c
arch/m68k/sun3x/prom.c

index cce465e850fe6f7bf8bb8f34955411224bb72488..997b549330156dc87bf48de2a2c2435b4fdc62d2 100644 (file)
@@ -15,7 +15,6 @@
 #include <asm/unistd.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
-#include <asm/segment.h>
 #include <asm/traps.h>
 #include <asm/asm-offsets.h>
 #include <asm/entry.h>
index 774c35f47eeab5affbfba83c375452165cae16ba..0b50da08a9c56fc691aa1e918e5b641ae2dc7fae 100644 (file)
@@ -29,7 +29,6 @@ config M68K
        select NO_DMA if !MMU && !COLDFIRE
        select OLD_SIGACTION
        select OLD_SIGSUSPEND3
-       select SET_FS
        select UACCESS_MEMCPY if !MMU
        select VIRT_TO_BUS
        select ZONE_DMA
index 68adb7b5b296d4f9f7f3a9fa1bfcf6fe4cf9bc69..9f337c70243a39f75828675170028f2ed2c18980 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/thread_info.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
-#include <asm/segment.h>
 #include <asm/asm-offsets.h>
 #include <asm/entry.h>
 
index 3750819ac5a13bde46a73d0b9ae6af21dd5aa42f..f4d82c619a5c48ec7b3a87df334089c0e44873e6 100644 (file)
@@ -9,7 +9,6 @@
 #define __ASM_M68K_PROCESSOR_H
 
 #include <linux/thread_info.h>
-#include <asm/segment.h>
 #include <asm/fpu.h>
 #include <asm/ptrace.h>
 
@@ -75,11 +74,37 @@ static inline void wrusp(unsigned long usp)
 #define TASK_UNMAPPED_BASE     0
 #endif
 
+/* Address spaces (or Function Codes in Motorola lingo) */
+#define USER_DATA     1
+#define USER_PROGRAM  2
+#define SUPER_DATA    5
+#define SUPER_PROGRAM 6
+#define CPU_SPACE     7
+
+#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES
+/*
+ * Set the SFC/DFC registers for special MM operations.  For most normal
+ * operation these remain set to USER_DATA for the uaccess routines.
+ */
+static inline void set_fc(unsigned long val)
+{
+       WARN_ON_ONCE(in_interrupt());
+
+       __asm__ __volatile__ ("movec %0,%/sfc\n\t"
+                             "movec %0,%/dfc\n\t"
+                             : /* no outputs */ : "r" (val) : "memory");
+}
+#else
+static inline void set_fc(unsigned long val)
+{
+}
+#endif /* CONFIG_CPU_HAS_ADDRESS_SPACES */
+
 struct thread_struct {
        unsigned long  ksp;             /* kernel stack pointer */
        unsigned long  usp;             /* user stack pointer */
        unsigned short sr;              /* saved status register */
-       unsigned short fs;              /* saved fs (sfc, dfc) */
+       unsigned short fc;              /* saved fc (sfc, dfc) */
        unsigned long  crp[2];          /* cpu root pointer */
        unsigned long  esp0;            /* points to SR of stack frame */
        unsigned long  faddr;           /* info about last fault */
@@ -92,7 +117,7 @@ struct thread_struct {
 #define INIT_THREAD  {                                                 \
        .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
        .sr     = PS_S,                                                 \
-       .fs     = __KERNEL_DS,                                          \
+       .fc     = USER_DATA,                                            \
 }
 
 /*
diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h
deleted file mode 100644 (file)
index 2b5e68a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA     (1)
-#ifndef __USER_DS
-#define __USER_DS     (USER_DATA)
-#endif
-#define USER_PROGRAM  (2)
-#define SUPER_DATA    (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS   (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE     (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-       unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-
-#ifdef CONFIG_CPU_HAS_ADDRESS_SPACES
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-#define USER_DS                MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS      MAKE_MM_SEG(__KERNEL_DS)
-
-static inline mm_segment_t get_fs(void)
-{
-       mm_segment_t _v;
-       __asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
-       return _v;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-       __asm__ __volatile__ ("movec %0,%/sfc\n\t"
-                             "movec %0,%/dfc\n\t"
-                             : /* no outputs */ : "r" (val.seg) : "memory");
-}
-
-#else
-#define USER_DS                MAKE_MM_SEG(TASK_SIZE)
-#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
-#define get_fs()       (current_thread_info()->addr_limit)
-#define set_fs(x)      (current_thread_info()->addr_limit = (x))
-#endif
-
-#define uaccess_kernel()       (get_fs().seg == KERNEL_DS.seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
index 15a757073fa58ffcab231b5b7f4190479b2d363b..c952658ba79223b028d9dd7baba20d8a3992d119 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <asm/types.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 
 /*
  * On machines with 4k pages we default to an 8k thread size, though we
@@ -27,7 +26,6 @@
 struct thread_info {
        struct task_struct      *task;          /* main task structure */
        unsigned long           flags;
-       mm_segment_t            addr_limit;     /* thread address space */
        int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
        __u32                   cpu;            /* should always be 0 on m68k */
        unsigned long           tp_value;       /* thread pointer */
@@ -37,7 +35,6 @@ struct thread_info {
 #define INIT_THREAD_INFO(tsk)                  \
 {                                              \
        .task           = &tsk,                 \
-       .addr_limit     = KERNEL_DS,            \
        .preempt_count  = INIT_PREEMPT_COUNT,   \
 }
 
index a6318ccd308fd3ae3bbf3e0a62f05aae7b6ed9d1..b882e2f4f5516f8d67c501596ec22df5c2f92610 100644 (file)
@@ -13,13 +13,12 @@ static inline void flush_tlb_kernel_page(void *addr)
        if (CPU_IS_COLDFIRE) {
                mmu_write(MMUOR, MMUOR_CNL);
        } else if (CPU_IS_040_OR_060) {
-               mm_segment_t old_fs = get_fs();
-               set_fs(KERNEL_DS);
+               set_fc(SUPER_DATA);
                __asm__ __volatile__(".chip 68040\n\t"
                                     "pflush (%0)\n\t"
                                     ".chip 68k"
                                     : : "a" (addr));
-               set_fs(old_fs);
+               set_fc(USER_DATA);
        } else if (CPU_IS_020_OR_030)
                __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
 }
@@ -84,12 +83,8 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 
 static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 {
-       if (vma->vm_mm == current->active_mm) {
-               mm_segment_t old_fs = force_uaccess_begin();
-
+       if (vma->vm_mm == current->active_mm)
                __flush_tlb_one(addr);
-               force_uaccess_end(old_fs);
-       }
 }
 
 static inline void flush_tlb_range(struct vm_area_struct *vma,
index 65581a7874d4d15fba7546364e585f2382017433..ba670523885c89ff72352f0147da5534b3773a1b 100644 (file)
@@ -9,7 +9,6 @@
  */
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/segment.h>
 #include <asm/extable.h>
 
 /* We let the MMU do all checking */
@@ -451,9 +450,6 @@ do {                                                                        \
                goto err_label;                                         \
 } while (0)
 
-#define user_addr_max() \
-       (uaccess_kernel() ? ~0UL : TASK_SIZE)
-
 extern long strncpy_from_user(char *dst, const char __user *src, long count);
 extern __must_check long strnlen_user(const char __user *str, long n);
 
index ccea355052efad8994f9682eed160b9fde6ba57c..906d73230537440fde199e779bd484683a0e8d9d 100644 (file)
@@ -31,7 +31,7 @@ int main(void)
        DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
        DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
        DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
-       DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
+       DEFINE(THREAD_FC, offsetof(struct thread_struct, fc));
        DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
        DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
        DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
index 8fa9822b5922e46d62872ec42726e73f6127b3d1..9434fca68de5d018b9f301f9b8813f7b6826c667 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/linkage.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
-#include <asm/segment.h>
 #include <asm/traps.h>
 #include <asm/unistd.h>
 #include <asm/asm-offsets.h>
@@ -337,7 +336,7 @@ resume:
 
        /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
        movec   %sfc,%d0
-       movew   %d0,%a0@(TASK_THREAD+THREAD_FS)
+       movew   %d0,%a0@(TASK_THREAD+THREAD_FC)
 
        /* save usp */
        /* it is better to use a movel here instead of a movew 8*) */
@@ -423,7 +422,7 @@ resume:
        movel   %a0,%usp
 
        /* restore fs (sfc,%dfc) */
-       movew   %a1@(TASK_THREAD+THREAD_FS),%a0
+       movew   %a1@(TASK_THREAD+THREAD_FC),%a0
        movec   %a0,%sfc
        movec   %a0,%dfc
 
index db49f90917112b8d76769050b5ed774e32b9550d..1ab692b952cd6235db7418cdb7b4cf6a83155f4e 100644 (file)
@@ -92,7 +92,7 @@ void show_regs(struct pt_regs * regs)
 
 void flush_thread(void)
 {
-       current->thread.fs = __USER_DS;
+       current->thread.fc = USER_DATA;
 #ifdef CONFIG_FPU
        if (!FPU_IS_EMU) {
                unsigned long zero = 0;
@@ -155,7 +155,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
         * Must save the current SFC/DFC value, NOT the value when
         * the parent was last descheduled - RGH  10-08-96
         */
-       p->thread.fs = get_fs().seg;
+       p->thread.fc = USER_DATA;
 
        if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
                /* kernel thread */
index 5b19fcdcd69e96e31cd3db25bce50f5ea0a227b0..9718ce94cc845ab36c393b6dda9a349247bc6da3 100644 (file)
@@ -181,9 +181,8 @@ static inline void access_error060 (struct frame *fp)
 static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
 {
        unsigned long mmusr;
-       mm_segment_t old_fs = get_fs();
 
-       set_fs(MAKE_MM_SEG(wbs));
+       set_fc(wbs);
 
        if (iswrite)
                asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
@@ -192,7 +191,7 @@ static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
 
        asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
 
-       set_fs(old_fs);
+       set_fc(USER_DATA);
 
        return mmusr;
 }
@@ -201,10 +200,8 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
                                   unsigned long wbd)
 {
        int res = 0;
-       mm_segment_t old_fs = get_fs();
 
-       /* set_fs can not be moved, otherwise put_user() may oops */
-       set_fs(MAKE_MM_SEG(wbs));
+       set_fc(wbs);
 
        switch (wbs & WBSIZ_040) {
        case BA_SIZE_BYTE:
@@ -218,9 +215,7 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
                break;
        }
 
-       /* set_fs can not be moved, otherwise put_user() may oops */
-       set_fs(old_fs);
-
+       set_fc(USER_DATA);
 
        pr_debug("do_040writeback1, res=%d\n", res);
 
index 90f4e9ca1276b5039ff95f9487bd3c996f6d5e00..4fab3479175865d47b579a965b1249fac4dbc4c3 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/uaccess.h>
 #include <asm/io.h>
-#include <asm/segment.h>
 #include <asm/setup.h>
 #include <asm/macintosh.h>
 #include <asm/mac_via.h>
index e7c1cabbfac459966ddcbd512d1011762f7d1d81..dde978e66f14fb311740b2f9b009a8d36e86e109 100644 (file)
@@ -90,11 +90,9 @@ void flush_icache_user_range(unsigned long address, unsigned long endaddr)
 
 void flush_icache_range(unsigned long address, unsigned long endaddr)
 {
-       mm_segment_t old_fs = get_fs();
-
-       set_fs(KERNEL_DS);
+       set_fc(SUPER_DATA);
        flush_icache_user_range(address, endaddr);
-       set_fs(old_fs);
+       set_fc(USER_DATA);
 }
 EXPORT_SYMBOL(flush_icache_range);
 
index 5d749e188246d736e2eda5d393dc22b3449e4c7b..1b47bec15832066542b6cfa53e3e46489459c147 100644 (file)
@@ -72,12 +72,6 @@ void __init paging_init(void)
        if (!empty_zero_page)
                panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
                      __func__, PAGE_SIZE, PAGE_SIZE);
-
-       /*
-        * Set up SFC/DFC registers (user data space).
-        */
-       set_fs (USER_DS);
-
        max_zone_pfn[ZONE_DMA] = end_mem >> PAGE_SHIFT;
        free_area_init(max_zone_pfn);
 }
index 1269d513b2217f84e725e8b6cda8503db104ee83..20ddf71b43d05a2c42819acbce516d2bc5a9444a 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/vmalloc.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/io.h>
 #include <asm/tlbflush.h>
index fe75aecfb238a3c7f0fdf24733ce1836cdb8de92..c2c03b0a1567f9d37c2fe417b19d5e9719ddb8b3 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/gfp.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
 #include <asm/page.h>
 #include <asm/traps.h>
 #include <asm/machdep.h>
index 3a653f0a4188d4af82046e8ff4283ff916c43c41..9f3f77785aa78a013ba26b31da01d12a2d5d645f 100644 (file)
@@ -467,7 +467,7 @@ void __init paging_init(void)
        /*
         * Set up SFC/DFC registers
         */
-       set_fs(KERNEL_DS);
+       set_fc(USER_DATA);
 
 #ifdef DEBUG
        printk ("before free_area_init\n");
index f7dd47232b6ca9207fc2e1ed28dfefecd18671aa..203f428a0344a73534ecd1ddc2068f108c282730 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/intersil.h>
 #include <asm/irq.h>
 #include <asm/sections.h>
-#include <asm/segment.h>
 #include <asm/sun3ints.h>
 
 char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
@@ -89,7 +88,7 @@ void __init sun3_init(void)
        sun3_reserved_pmeg[249] = 1;
        sun3_reserved_pmeg[252] = 1;
        sun3_reserved_pmeg[253] = 1;
-       set_fs(KERNEL_DS);
+       set_fc(USER_DATA);
 }
 
 /* Without this, Bad Things happen when something calls arch_reset. */
index 7aa879b7c7ff57423ff792a6275807e5e725c34d..7ec20817c0c9eaffe487a5347aecd1c280866b03 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/uaccess.h>
 #include <asm/page.h>
 #include <asm/sun3mmu.h>
-#include <asm/segment.h>
 #include <asm/oplib.h>
 #include <asm/mmu_context.h>
 #include <asm/dvma.h>
@@ -191,14 +190,13 @@ void __init mmu_emu_init(unsigned long bootmem_end)
        for(seg = 0; seg < PAGE_OFFSET; seg += SUN3_PMEG_SIZE)
                sun3_put_segmap(seg, SUN3_INVALID_PMEG);
 
-       set_fs(MAKE_MM_SEG(3));
+       set_fc(3);
        for(seg = 0; seg < 0x10000000; seg += SUN3_PMEG_SIZE) {
                i = sun3_get_segmap(seg);
                for(j = 1; j < CONTEXTS_NUM; j++)
                        (*(romvec->pv_setctxt))(j, (void *)seg, i);
        }
-       set_fs(KERNEL_DS);
-
+       set_fc(USER_DATA);
 }
 
 /* erase the mappings for a dead context.  Uses the pg_dir for hints
index 41ae422119d32826c92b6d7bcd35608bd9735176..36cc280a4505f5d2456b6c917c8c4eb03225a859 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
-#include <asm/segment.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
 #include <asm/sun3ints.h>
index 74d2fe57524b36694d2e6c5d08e7d8ff5f2ee8c0..64c23bfaa90c5ba9006002c6e91969c776b6bf0c 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/traps.h>
 #include <asm/sun3xprom.h>
 #include <asm/idprom.h>
-#include <asm/segment.h>
 #include <asm/sun3ints.h>
 #include <asm/openprom.h>
 #include <asm/machines.h>