Commit 9fde0348 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Geert Uytterhoeven
Browse files

m68k: Remove set_fs()



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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Link: https://lore.kernel.org/r/20210916070405.52750-7-hch@lst.de


Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent 8ade8339
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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>
+0 −1
Original line number Diff line number Diff line
@@ -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
+0 −1
Original line number Diff line number Diff line
@@ -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>

+28 −3
Original line number Diff line number Diff line
@@ -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,						\
}

/*

arch/m68k/include/asm/segment.h

deleted100644 → 0
+0 −59
Original line number Diff line number Diff line
/* 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 */
Loading