From: eliad lubovsky <eliadl@013.net>
To: linux-kernel@vger.kernel.org
Subject: thread_info and kernel mode stack
Date: Tue, 26 Jul 2005 23:36:04 +0300 [thread overview]
Message-ID: <1122410164.3524.72.camel@localhost.localdomain> (raw)
[-- 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;
reply other threads:[~2005-07-26 20:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1122410164.3524.72.camel@localhost.localdomain \
--to=eliadl@013.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox