Subject: [PATCH] x86-64 move thread_info into task_struct On x86-64, move thread_info from the stack into task_struct. This has benefits for the use of registers in entry.S when current is moved into a register. Take the easy approach of making GET_THREAD_INFO() return a pointer to current and make the asm-offset.c aware of this new usage. --- arch/i386/oprofile/nmi_int.c | 1 + arch/x86_64/kernel/asm-offsets.c | 2 +- arch/x86_64/kernel/genapic_cluster.c | 1 + arch/x86_64/kernel/genapic_flat.c | 1 + arch/x86_64/kernel/setup64.c | 2 +- include/asm-x86_64/desc.h | 1 + include/asm-x86_64/processor.h | 10 +++------- include/asm-x86_64/system.h | 6 ++---- include/asm-x86_64/thread_info.h | 31 ++++++++++++++----------------- 9 files changed, 25 insertions(+), 30 deletions(-) applies-to: 747a43be5747e1c8e25f5769bdb9e4a1b8029138 bb489ebe1733165426cbbaba24a2ed51d6952d88 diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index 0493e8b..1e91d22 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c index aaa6d38..66ebe60 100644 --- a/arch/x86_64/kernel/asm-offsets.c +++ b/arch/x86_64/kernel/asm-offsets.c @@ -29,7 +29,7 @@ int main(void) ENTRY(pid); BLANK(); #undef ENTRY -#define ENTRY(entry) DEFINE(threadinfo_ ## entry, offsetof(struct thread_info, entry)) +#define ENTRY(entry) DEFINE(threadinfo_ ## entry, offsetof(struct task_struct, thread.info.entry)) ENTRY(flags); ENTRY(addr_limit); ENTRY(preempt_count); diff --git a/arch/x86_64/kernel/genapic_cluster.c b/arch/x86_64/kernel/genapic_cluster.c index a472d62..42531a9 100644 --- a/arch/x86_64/kernel/genapic_cluster.c +++ b/arch/x86_64/kernel/genapic_cluster.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 9da3edb..28b775f 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 06dc354..3e81a04 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -126,7 +126,7 @@ void pda_init(int cpu) pda->cpunumber = cpu; pda->irqcount = -1; pda->kernelstack = - (unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; + (unsigned long)current->thread_info - PDA_STACKOFFSET + THREAD_SIZE; pda->active_mm = &init_mm; pda->mmu_state = 0; diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h index 3376486..ece54d4 100644 --- a/include/asm-x86_64/desc.h +++ b/include/asm-x86_64/desc.h @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index 4861246..7f24beb 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -20,6 +20,7 @@ #include #include #include +#include #define TF_MASK 0x00000100 #define IF_MASK 0x00000200 @@ -230,6 +231,7 @@ DECLARE_PER_CPU(struct tss_struct,init_t #define ARCH_MIN_TASKALIGN 16 struct thread_struct { + struct thread_info info; unsigned long rsp0; unsigned long rsp; unsigned long userrsp; /* Copy from PDA */ @@ -257,6 +259,7 @@ struct thread_struct { } __attribute__((aligned(16))); #define INIT_THREAD { \ + .info = INIT_THREAD_INFO(init_task), \ .rsp0 = (unsigned long)&init_stack + sizeof(init_stack) \ } @@ -467,13 +470,6 @@ static inline void __mwait(unsigned long : :"a" (eax), "c" (ecx)); } -#define stack_current() \ -({ \ - struct thread_info *ti; \ - asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ - ti->task; \ -}) - #define cache_line_size() (boot_cpu_data.x86_cache_alignment) extern unsigned long boot_option_idle_override; diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index 85348e0..d2cbbc3 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h @@ -34,17 +34,15 @@ ".globl thread_return\n" \ "thread_return:\n\t" \ "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ - "movq %P[thread_info](%%rsi),%%r8\n\t" \ - LOCK "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ + LOCK "btr %[tif_fork],%P[ti_flags](%%rsi)\n\t" \ "movq %%rax,%%rdi\n\t" \ "jc ret_from_fork\n\t" \ RESTORE_CONTEXT \ : "=a" (last) \ : [next] "S" (next), [prev] "D" (prev), \ [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \ - [ti_flags] "i" (offsetof(struct thread_info, flags)),\ + [ti_flags] "i" (offsetof(struct task_struct, thread.info.flags)),\ [tif_fork] "i" (TIF_FORK), \ - [thread_info] "i" (offsetof(struct task_struct, thread_info)), \ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ : "memory", "cc" __EXTRA_CLOBBER) diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h index 08eb6e4..0c90a18 100644 --- a/include/asm-x86_64/thread_info.h +++ b/include/asm-x86_64/thread_info.h @@ -57,20 +57,16 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) -static inline struct thread_info *current_thread_info(void) -{ - struct thread_info *ti; - ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); - return ti; -} - -/* do not use in interrupt context */ -static inline struct thread_info *stack_thread_info(void) -{ - struct thread_info *ti; - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1))); - return ti; -} +#define task_thread_info(t) (&(t)->thread.info) +#define current_thread_info() task_thread_info(current) + +#define setup_thread_stack(p, org) ({ \ + task_thread_info(p)->task = (p); \ +}) + +#define end_of_stack(p) ((unsigned long *)(p)->thread_info + 1) + +#define __HAVE_THREAD_FUNCTIONS /* thread information allocation */ #define alloc_thread_info(tsk) \ @@ -81,10 +77,11 @@ static inline struct thread_info *stack_ #else /* !__ASSEMBLY__ */ -/* how to get the thread information struct from ASM */ +/* How to get the thread information struct from ASM. We use a pointer to + * current and make the asm offsets point to * ->thread.info. + */ #define GET_THREAD_INFO(reg) \ - movq %gs:pda_kernelstack,reg ; \ - subq $(THREAD_SIZE-PDA_STACKOFFSET),reg + movq %gs:pda_pcurrent,reg #endif --- 0.99.9.GIT