Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c7fcf76 authored by David Howells's avatar David Howells
Browse files

MN10300: Save frame pointer in thread_info struct rather than global var



Save the current exception frame pointer in the thread_info struct rather than
in a global variable as the latter makes SMP tricky, especially when preemption
is also enabled.

This also replaces __frame with current_frame() and rearranges header file
inclusions to make it all compile.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarAkira Takeuchi <takeuchi.akr@jp.panasonic.com>
parent a5e03ca2
Loading
Loading
Loading
Loading
+13 −43
Original line number Original line Diff line number Diff line
@@ -18,9 +18,7 @@
#ifndef __ASM_OFFSETS_H__
#ifndef __ASM_OFFSETS_H__
#include <asm/asm-offsets.h>
#include <asm/asm-offsets.h>
#endif
#endif
#ifdef CONFIG_SMP
#include <asm/thread_info.h>
#include <proc/smp-regs.h>
#endif


#define pi break
#define pi break


@@ -40,27 +38,15 @@
	movm	[d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
	movm	[d2,d3,a2,a3,exreg0,exreg1,exother],(sp)
	mov	sp,fp				# FRAME pointer in A3
	mov	sp,fp				# FRAME pointer in A3
	add	-12,sp				# allow for calls to be made
	add	-12,sp				# allow for calls to be made
#ifdef CONFIG_SMP
#ifdef CONFIG_PREEMPT /* FIXME */
	mov	epsw,d2
	and	~EPSW_IE,epsw
#endif
	mov	(CPUID),a0
	add	a0,a0
	add	a0,a0
	mov	(___frame,a0),a1
	mov	a1,(REG_NEXT,fp)
	mov	fp,(___frame,a0)
#ifdef CONFIG_PREEMPT /* FIXME */
	mov	d2,epsw
#endif
#else  /* CONFIG_SMP */
	mov	(__frame),a1
	mov	a1,(REG_NEXT,fp)
	mov	fp,(__frame)
#endif /* CONFIG_SMP */


	and	~EPSW_FE,epsw			# disable the FPU inside the kernel
	# push the exception frame onto the front of the list
	GET_THREAD_INFO a1
	mov	(TI_frame,a1),a0
	mov	a0,(REG_NEXT,fp)
	mov	fp,(TI_frame,a1)

	# disable the FPU inside the kernel
	and	~EPSW_FE,epsw


	# we may be holding current in E2
	# we may be holding current in E2
#ifdef CONFIG_MN10300_CURRENT_IN_E2
#ifdef CONFIG_MN10300_CURRENT_IN_E2
@@ -76,27 +62,11 @@
.macro RESTORE_ALL
.macro RESTORE_ALL
	# peel back the stack to the calling frame
	# peel back the stack to the calling frame
	# - this permits execve() to discard extra frames due to kernel syscalls
	# - this permits execve() to discard extra frames due to kernel syscalls
#ifdef  CONFIG_SMP
	GET_THREAD_INFO a0
#ifdef CONFIG_PREEMPT /* FIXME */
	mov	(TI_frame,a0),fp
	mov	epsw,d2
	and	~EPSW_IE,epsw
#endif
	mov	(CPUID),a0
	add	a0,a0
	add	a0,a0
	mov	(___frame,a0),fp
	mov	fp,sp
	mov	(REG_NEXT,fp),d0                # userspace has regs->next == 0
	mov	d0,(___frame,a0)
#ifdef CONFIG_PREEMPT /* FIXME */
	mov	d2,epsw
#endif
#else   /* CONFIG_SMP */
	mov	(__frame),fp
	mov	fp,sp
	mov	fp,sp
	mov	(REG_NEXT,fp),d0                # userspace has regs->next == 0
	mov	(REG_NEXT,fp),d0
	mov	d0,(__frame)
	mov	d0,(TI_frame,a0)                # userspace has regs->next == 0
#endif  /* CONFIG_SMP */


#ifndef CONFIG_MN10300_USING_JTAG
#ifndef CONFIG_MN10300_USING_JTAG
	mov	(REG_EPSW,fp),d0
	mov	(REG_EPSW,fp),d0
+5 −1
Original line number Original line Diff line number Diff line
@@ -18,7 +18,11 @@
#define ARCH_HAS_OWN_IRQ_REGS
#define ARCH_HAS_OWN_IRQ_REGS


#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
#define get_irq_regs() (__frame)
static inline __attribute__((const))
struct pt_regs *get_irq_regs(void)
{
	return current_frame();
}
#endif
#endif


#endif /* _ASM_IRQ_REGS_H */
#endif /* _ASM_IRQ_REGS_H */
+0 −1
Original line number Original line Diff line number Diff line
@@ -11,7 +11,6 @@
#ifndef _ASM_PGALLOC_H
#ifndef _ASM_PGALLOC_H
#define _ASM_PGALLOC_H
#define _ASM_PGALLOC_H


#include <asm/processor.h>
#include <asm/page.h>
#include <asm/page.h>
#include <linux/threads.h>
#include <linux/threads.h>
#include <linux/mm.h>		/* for struct page */
#include <linux/mm.h>		/* for struct page */
+18 −28
Original line number Original line Diff line number Diff line
@@ -13,10 +13,13 @@
#ifndef _ASM_PROCESSOR_H
#ifndef _ASM_PROCESSOR_H
#define _ASM_PROCESSOR_H
#define _ASM_PROCESSOR_H


#include <linux/threads.h>
#include <linux/thread_info.h>
#include <asm/page.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/ptrace.h>
#include <asm/cpu-regs.h>
#include <asm/cpu-regs.h>
#include <linux/threads.h>
#include <asm/uaccess.h>
#include <asm/current.h>


/* Forward declaration, a strange C thing */
/* Forward declaration, a strange C thing */
struct task_struct;
struct task_struct;
@@ -83,10 +86,6 @@ extern void dodgy_tsc(void);
 */
 */
#define TASK_UNMAPPED_BASE	0x30000000
#define TASK_UNMAPPED_BASE	0x30000000


typedef struct {
	unsigned long	seg;
} mm_segment_t;

struct fpu_state_struct {
struct fpu_state_struct {
	unsigned long	fs[32];		/* fpu registers */
	unsigned long	fs[32];		/* fpu registers */
	unsigned long	fpcr;		/* fpu control register */
	unsigned long	fpcr;		/* fpu control register */
@@ -99,7 +98,6 @@ struct thread_struct {
	unsigned long		a3;		/* kernel FP */
	unsigned long		a3;		/* kernel FP */
	unsigned long		wchan;
	unsigned long		wchan;
	unsigned long		usp;
	unsigned long		usp;
	struct pt_regs		*frame;
	unsigned long		fpu_flags;
	unsigned long		fpu_flags;
#define THREAD_USING_FPU	0x00000001	/* T if this task is using the FPU */
#define THREAD_USING_FPU	0x00000001	/* T if this task is using the FPU */
#define THREAD_HAS_FPU		0x00000002	/* T if this task owns the FPU right now */
#define THREAD_HAS_FPU		0x00000002	/* T if this task owns the FPU right now */
@@ -113,7 +111,6 @@ struct thread_struct {
	.sp	= 0,		\
	.sp	= 0,		\
	.a3	= 0,		\
	.a3	= 0,		\
	.wchan	= 0,		\
	.wchan	= 0,		\
	.frame	= NULL,		\
}
}


#define INIT_MMAP \
#define INIT_MMAP \
@@ -125,27 +122,20 @@ struct thread_struct {
 * - need to discard the frame stacked by the kernel thread invoking the execve
 * - need to discard the frame stacked by the kernel thread invoking the execve
 *   syscall (see RESTORE_ALL macro)
 *   syscall (see RESTORE_ALL macro)
 */
 */
#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) /* FIXME */
static inline void start_thread(struct pt_regs *regs,
#define start_thread(regs, new_pc, new_sp) do {		\
				unsigned long new_pc, unsigned long new_sp)
	int cpu;					\
{
	preempt_disable();				\
	struct thread_info *ti = current_thread_info();
	cpu = CPUID;					\
	struct pt_regs *frame0;
	set_fs(USER_DS);				\
	set_fs(USER_DS);
	___frame[cpu] = current->thread.uregs;		\

	___frame[cpu]->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;\
	frame0 = thread_info_to_uregs(ti);
	___frame[cpu]->pc = new_pc;			\
	frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
	___frame[cpu]->sp = new_sp;			\
	frame0->pc = new_pc;
	preempt_enable();				\
	frame0->sp = new_sp;
} while (0)
	ti->frame = frame0;
#else  /* CONFIG_SMP && CONFIG_PREEMPT */
}
#define start_thread(regs, new_pc, new_sp) do {		\

	set_fs(USER_DS);				\
	__frame = current->thread.uregs;		\
	__frame->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;	\
	__frame->pc = new_pc;				\
	__frame->sp = new_sp;				\
} while (0)
#endif /* CONFIG_SMP && CONFIG_PREEMPT */


/* Free all resources held by a thread. */
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
extern void release_thread(struct task_struct *);
+0 −6
Original line number Original line Diff line number Diff line
@@ -86,12 +86,6 @@ struct pt_regs {


#ifdef __KERNEL__
#ifdef __KERNEL__


#ifdef CONFIG_SMP
extern struct pt_regs *___frame[];	/* current frame pointer */
#else
extern struct pt_regs *__frame;		/* current frame pointer */
#endif

#define user_mode(regs)			(((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define user_mode(regs)			(((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define instruction_pointer(regs)	((regs)->pc)
#define instruction_pointer(regs)	((regs)->pc)
#define user_stack_pointer(regs)	((regs)->sp)
#define user_stack_pointer(regs)	((regs)->sp)
Loading