All of lore.kernel.org
 help / color / mirror / Atom feed
* thread_info and kernel mode stack
@ 2005-07-26 20:36 eliad lubovsky
  0 siblings, 0 replies; only message in thread
From: eliad lubovsky @ 2005-07-26 20:36 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1156 bytes --]

Hi,
I am trying to work in a special configuration where the thread_info is
above the stack pointer. The SP though, start from the 
base stack address + THREAD_SIZE - THREAD_INFO_SECTION_SIZE (that is 128
bytes). 
The INIT_TSS macro looks like:
.esp0           = sizeof(init_stack)-THREAD_INFO_SECTION_SIZE +
(long)&init_stack,      \
So far it works.


When I am trying to move the init_thread_info to the top of the stack
the computer restart itself. What I am doing is replacing the union of
the init_thread_info with the following structure:

-union thread_union {
-        struct thread_info thread_info;
-        unsigned long stack[THREAD_SIZE/sizeof(long)];
-};

+struct thread_union {
+unsigned stack[(THREAD_SIZE-THREAD_INFO_SECTION_SIZE)/sizeof(long)];
+        struct thread_info thread_info;
+};

it means that when I am referencing the thread_info it is in offset
(THREAD_SIZE-THREAD_INFO_SECTION_SIZE)/sizeof(long) and not the base
address as it was when declared with a union.

I have changed other relevant places as in fork.c and so, although the
computer even doesn't start, I think its related to the init thread.
any clues?

-- 
Eliad

[-- Attachment #2: ti_and_stack.patch --]
[-- Type: text/x-patch, Size: 6278 bytes --]

diff -urNp linux-2.6.9.orig/arch/i386/kernel/head.S linux-2.6.9.changes/arch/i386/kernel/head.S
--- linux-2.6.9.orig/arch/i386/kernel/head.S	2004-10-18 23:53:13.000000000 +0200
+++ linux-2.6.9.changes/arch/i386/kernel/head.S	2005-07-26 15:42:20.000000000 +0300
@@ -425,7 +425,7 @@ ENTRY(empty_zero_page)
 .data
 
 ENTRY(stack_start)
-	.long init_thread_union+THREAD_SIZE
+        .long init_thread_union+THREAD_SIZE-THREAD_INFO_SECTION_SIZE
 	.long __BOOT_DS
 
 ready:	.byte 0
diff -urNp linux-2.6.9.orig/arch/i386/kernel/init_task.c linux-2.6.9.changes/arch/i386/kernel/init_task.c
--- linux-2.6.9.orig/arch/i386/kernel/init_task.c	2004-10-18 23:55:28.000000000 +0200
+++ linux-2.6.9.changes/arch/i386/kernel/init_task.c	2005-07-26 22:56:29.036709328 +0300
@@ -25,9 +25,7 @@ EXPORT_SYMBOL(init_mm);
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
-		{ INIT_THREAD_INFO(init_task) };
+struct thread_union init_thread_union = { {0}, INIT_THREAD_INFO(init_task) };
 
 /*
  * Initial task structure.
diff -urNp linux-2.6.9.orig/arch/i386/kernel/process.c linux-2.6.9.changes/arch/i386/kernel/process.c
--- linux-2.6.9.orig/arch/i386/kernel/process.c	2004-10-18 23:53:05.000000000 +0200
+++ linux-2.6.9.changes/arch/i386/kernel/process.c	2005-07-26 22:55:42.853730208 +0300
@@ -364,7 +364,7 @@ int copy_thread(int nr, unsigned long cl
 	struct task_struct *tsk;
 	int err;
 
-	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+        childregs = ((struct pt_regs *) ((THREAD_SIZE-THREAD_INFO_SECTION_SIZE) + (unsigned long) p->thread_info)) - 1;
 	*childregs = *regs;
 	childregs->eax = 0;
 	childregs->esp = esp;
@@ -665,8 +665,8 @@ out:
 	return error;
 }
 
-#define top_esp                (THREAD_SIZE - sizeof(unsigned long))
-#define top_ebp                (THREAD_SIZE - 2*sizeof(unsigned long))
+#define top_esp                ((THREAD_SIZE-THREAD_INFO_SECTION_SIZE) - sizeof(unsigned long))
+#define top_ebp                ((THREAD_SIZE-THREAD_INFO_SECTION_SIZE) - 2*sizeof(unsigned long))
 
 unsigned long get_wchan(struct task_struct *p)
 {
diff -urNp linux-2.6.9.orig/drivers/char/ip2main.c linux-2.6.9.changes/drivers/char/ip2main.c
--- linux-2.6.9.orig/drivers/char/ip2main.c	2004-10-18 23:55:36.000000000 +0200
+++ linux-2.6.9.changes/drivers/char/ip2main.c	2004-10-18 23:55:36.000000000 +0200
@@ -1179,7 +1179,7 @@ ip2_interrupt_bh(i2eBordStrPtr pB)
 /* Parameters: irq - interrupt number                                         */
 /*             pointer to optional device ID structure                        */
 /*             pointer to register structure                                  */
-/* Returns:    Nothing              $                                         */
+/* Returns:    Nothing                                                        */
 /*                                                                            */
 /* Description:                                                               */
 /*                                                                            */
diff -urNp linux-2.6.9.orig/include/asm-i386/processor.h linux-2.6.9.changes/include/asm-i386/processor.h
--- linux-2.6.9.orig/include/asm-i386/processor.h	2004-10-18 23:53:07.000000000 +0200
+++ linux-2.6.9.changes/include/asm-i386/processor.h	2005-07-26 15:43:30.000000000 +0300
@@ -450,7 +450,7 @@ struct thread_struct {
  * be within the limit.
  */
 #define INIT_TSS  {							\
-	.esp0		= sizeof(init_stack) + (long)&init_stack,	\
+	.esp0		= sizeof(init_stack)-THREAD_INFO_SECTION_SIZE + (long)&init_stack,	\
 	.ss0		= __KERNEL_DS,					\
 	.ss1		= __KERNEL_CS,					\
 	.ldt		= GDT_ENTRY_LDT,				\
diff -urNp linux-2.6.9.orig/include/asm-i386/thread_info.h linux-2.6.9.changes/include/asm-i386/thread_info.h
--- linux-2.6.9.orig/include/asm-i386/thread_info.h	2004-10-18 23:53:21.000000000 +0200
+++ linux-2.6.9.changes/include/asm-i386/thread_info.h	2005-07-26 23:08:59.000000000 +0300
@@ -51,11 +51,13 @@ struct thread_info {
 
 #endif
 
+#define THREAD_INFO_SECTION_SIZE	128
+
 #define PREEMPT_ACTIVE		0x4000000
 #ifdef CONFIG_4KSTACKS
 #define THREAD_SIZE            (4096)
 #else
-#define THREAD_SIZE		(8192)
+#define THREAD_SIZE		(4096)
 #endif
 
 #define STACK_WARN             (THREAD_SIZE/8)
@@ -88,6 +90,7 @@ static inline struct thread_info *curren
 {
 	struct thread_info *ti;
 	__asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));
+	ti = (struct thread_info *)((char*)(ti)+(THREAD_SIZE-THREAD_INFO_SECTION_SIZE));
 	return ti;
 }
 
diff -urNp linux-2.6.9.orig/include/linux/sched.h linux-2.6.9.changes/include/linux/sched.h
--- linux-2.6.9.orig/include/linux/sched.h	2004-10-18 23:53:13.000000000 +0200
+++ linux-2.6.9.changes/include/linux/sched.h	2005-07-26 23:07:30.000000000 +0300
@@ -654,9 +654,9 @@ void yield(void);
  */
 extern struct exec_domain	default_exec_domain;
 
-union thread_union {
+struct thread_union {
+	unsigned long stack[(THREAD_SIZE-THREAD_INFO_SECTION_SIZE)/sizeof(long)];
 	struct thread_info thread_info;
-	unsigned long stack[THREAD_SIZE/sizeof(long)];
 };
 
 #ifndef __HAVE_ARCH_KSTACK_END
@@ -669,7 +669,7 @@ static inline int kstack_end(void *addr)
 }
 #endif
 
-extern union thread_union init_thread_union;
+extern struct thread_union init_thread_union;
 extern struct task_struct init_task;
 
 extern struct   mm_struct init_mm;
diff -urNp linux-2.6.9.orig/kernel/fork.c linux-2.6.9.changes/kernel/fork.c
--- linux-2.6.9.orig/kernel/fork.c	2004-10-18 23:53:13.000000000 +0200
+++ linux-2.6.9.changes/kernel/fork.c	2005-07-26 23:06:24.000000000 +0300
@@ -79,7 +79,9 @@ static kmem_cache_t *task_struct_cachep;
 
 void free_task(struct task_struct *tsk)
 {
-	free_thread_info(tsk->thread_info);
+	void * tmp = (void*)(tsk->thread_info);
+	tmp -= (THREAD_SIZE - THREAD_INFO_SECTION_SIZE);
+	free_thread_info(tmp);
 	free_task_struct(tsk);
 }
 EXPORT_SYMBOL(free_task);
@@ -270,6 +272,8 @@ static struct task_struct *dup_task_stru
 		return NULL;
 	}
 
+        ti = (struct thread_info*)((char*)ti + (THREAD_SIZE-THREAD_INFO_SECTION_SIZE));
+
 	*ti = *orig->thread_info;
 	*tsk = *orig;
 	tsk->thread_info = ti;

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

only message in thread, other threads:[~2005-07-26 20:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-26 20:36 thread_info and kernel mode stack eliad lubovsky

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.