public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] FRV: Make switch_to() return previous task
@ 2005-02-04 17:30 David Howells
  0 siblings, 0 replies; only message in thread
From: David Howells @ 2005-02-04 17:30 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-kernel


The attached patch makes switch_to() on the FRV pass through and return the
previous task pointer rather than trusting to luck that it'll be left in the
correct register/variable.

Signed-Off-By: David Howells <dhowells@redhat.com>
---
warthog>diffstat -p1 frv-switchto-2611rc3.diff 
 arch/frv/kernel/entry.S     |    3 +--
 arch/frv/kernel/switch_to.S |   34 ++++++++++++++++++++++------------
 include/asm-frv/processor.h |    2 +-
 include/asm-frv/system.h    |   17 ++++++++++-------
 4 files changed, 34 insertions(+), 22 deletions(-)

diff -uNrp /warthog/kernels/linux-2.6.11-rc3/arch/frv/kernel/entry.S linux-2.6.11-rc3-frv/arch/frv/kernel/entry.S
--- /warthog/kernels/linux-2.6.11-rc3/arch/frv/kernel/entry.S	2005-02-04 11:49:30.000000000 +0000
+++ linux-2.6.11-rc3-frv/arch/frv/kernel/entry.S	2005-02-04 15:30:45.000000000 +0000
@@ -782,13 +782,12 @@ __entry_do_NMI:
 ###############################################################################
 #
 # the return path for a newly forked child process
-# - __switch_to() saved the old current pointer in GR27 for us
+# - __switch_to() saved the old current pointer in GR8 for us
 #
 ###############################################################################
 	.globl		ret_from_fork
 ret_from_fork:
 	LEDS		0x6100
-	ori.p		gr27,0,gr8
 	call		schedule_tail
 
 	# fork & co. return 0 to child
diff -uNrp /warthog/kernels/linux-2.6.11-rc3/arch/frv/kernel/switch_to.S linux-2.6.11-rc3-frv/arch/frv/kernel/switch_to.S
--- /warthog/kernels/linux-2.6.11-rc3/arch/frv/kernel/switch_to.S	2005-02-04 11:49:30.000000000 +0000
+++ linux-2.6.11-rc3-frv/arch/frv/kernel/switch_to.S	2005-02-04 15:31:14.000000000 +0000
@@ -43,20 +43,22 @@ __kernel_current_task:
 
 ###############################################################################
 #
-# struct task_struct *__switch_to(struct thread_struct *prev, struct thread_struct *next)
+# struct task_struct *__switch_to(struct thread_struct *prev_thread,
+#				  struct thread_struct *next_thread,
+#				  struct task_struct *prev)
 #
 ###############################################################################
 	.globl		__switch_to
 __switch_to:
 	# save outgoing process's context
-	sethi.p		%hi(__switch_back),gr11
-	setlo		%lo(__switch_back),gr11
-	movsg		lr,gr10
+	sethi.p		%hi(__switch_back),gr13
+	setlo		%lo(__switch_back),gr13
+	movsg		lr,gr12
 
 	stdi		gr28,@(gr8,#__THREAD_FRAME)
 	sti		sp  ,@(gr8,#__THREAD_SP)
 	sti		fp  ,@(gr8,#__THREAD_FP)
-	stdi		gr10,@(gr8,#__THREAD_LR)
+	stdi		gr12,@(gr8,#__THREAD_LR)
 	stdi		gr16,@(gr8,#__THREAD_GR(16))
 	stdi		gr18,@(gr8,#__THREAD_GR(18))
 	stdi		gr20,@(gr8,#__THREAD_GR(20))
@@ -68,14 +70,14 @@ __switch_to:
 	ldi.p		@(gr8,#__THREAD_USER),gr8
 	call		save_user_regs
 	or		gr22,gr22,gr8
-
+	
 	# retrieve the new context
 	sethi.p		%hi(__kernel_frame0_ptr),gr6
 	setlo		%lo(__kernel_frame0_ptr),gr6
 	movsg		psr,gr4
 
 	lddi.p		@(gr9,#__THREAD_FRAME),gr10
-	or		gr29,gr29,gr27		; ret_from_fork needs to know old current
+	or		gr10,gr10,gr27		; save prev for the return value
 
 	ldi		@(gr11,#4),gr19		; get new_current->thread_info
 
@@ -88,8 +90,8 @@ __switch_to:
 	andi		gr4,#~PSR_ET,gr5
 	movgs		gr5,psr
 
-	or.p		gr10,gr0,gr28
-	or		gr11,gr0,gr29
+	or.p		gr10,gr0,gr28		; set __frame
+	or		gr11,gr0,gr29		; set __current
 	or.p		gr12,gr0,sp
 	or		gr13,gr0,fp
 	or		gr19,gr0,gr15		; set __current_thread_info
@@ -108,14 +110,17 @@ __switch_to:
 111:
 
 	# jump to __switch_back or ret_from_fork as appropriate
+	# - move prev to GR8
 	movgs		gr4,psr
-	jmpl		@(gr18,gr0)
+	jmpl.p		@(gr18,gr0)
+	or		gr27,gr27,gr8
 
 ###############################################################################
 #
 # restore incoming process's context
 # - on entry:
 #   - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately
+#   - GR8 will point to the outgoing task_struct
 #   - GR9 will point to the incoming thread_struct
 #
 ###############################################################################
@@ -128,12 +133,16 @@ __switch_back:
 	lddi		@(gr9,#__THREAD_GR(26)),gr26
 
 	# fall through into restore_user_regs()
-	ldi		@(gr9,#__THREAD_USER),gr8
+	ldi.p		@(gr9,#__THREAD_USER),gr8
+	or		gr8,gr8,gr9
 
 ###############################################################################
 #
 # restore extra general regs and FP/Media regs
-# - void restore_user_regs(const struct user_context *target)
+# - void *restore_user_regs(const struct user_context *target, void *retval)
+# - on entry:
+#   - GR8 will point to the user context to swap in
+#   - GR9 will contain the value to be returned in GR8 (prev task on context switch)
 #
 ###############################################################################
 	.globl		restore_user_regs
@@ -245,6 +254,7 @@ __restore_skip_fr32_fr63:
 	lddi		@(gr8,#__FPMEDIA_FNER(0)),gr4
 	movsg		fner0,gr4
 	movsg		fner1,gr5
+	or.p		gr9,gr9,gr8
 	bralr
 
 	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
diff -uNrp /warthog/kernels/linux-2.6.11-rc3/include/asm-frv/processor.h linux-2.6.11-rc3-frv/include/asm-frv/processor.h
--- /warthog/kernels/linux-2.6.11-rc3/include/asm-frv/processor.h	2005-02-04 11:50:21.000000000 +0000
+++ linux-2.6.11-rc3-frv/include/asm-frv/processor.h	2005-02-04 15:33:28.484022068 +0000
@@ -113,7 +113,7 @@ static inline void release_thread(struct
 
 extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 extern asmlinkage void save_user_regs(struct user_context *target);
-extern asmlinkage void restore_user_regs(const struct user_context *target);
+extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
 
 #define copy_segments(tsk, mm)		do { } while (0)
 #define release_segments(mm)		do { } while (0)
diff -uNrp /warthog/kernels/linux-2.6.11-rc3/include/asm-frv/system.h linux-2.6.11-rc3-frv/include/asm-frv/system.h
--- /warthog/kernels/linux-2.6.11-rc3/include/asm-frv/system.h	2005-02-04 11:50:21.000000000 +0000
+++ linux-2.6.11-rc3-frv/include/asm-frv/system.h	2005-02-04 16:12:47.113598875 +0000
@@ -26,13 +26,16 @@ struct thread_struct;
  * The `mb' is to tell GCC not to cache `current' across this call.
  */
 extern asmlinkage
-void __switch_to(struct thread_struct *prev, struct thread_struct *next);
-
-#define switch_to(prev, next, last)						\
-do {										\
-	prev->thread.sched_lr = (unsigned long) __builtin_return_address(0);	\
-	__switch_to(&prev->thread, &next->thread);				\
-	mb();									\
+struct task_struct *__switch_to(struct thread_struct *prev_thread,
+				struct thread_struct *next_thread,
+				struct task_struct *prev);
+
+#define switch_to(prev, next, last)					\
+do {									\
+	(prev)->thread.sched_lr =					\
+		(unsigned long) __builtin_return_address(0);		\
+	(last) = __switch_to(&(prev)->thread, &(next)->thread, (prev));	\
+	mb();								\
 } while(0)
 
 /*

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-02-04 17:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-04 17:30 [PATCH] FRV: Make switch_to() return previous task David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox