All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.