Commit 0500871f authored by David Howells's avatar David Howells
Browse files

Construct init thread stack in the linker script rather than by union



Construct the init thread stack in the linker script rather than doing it
by means of a union so that ia64's init_task.c can be got rid of.

The following symbols are then made available from INIT_TASK_DATA() linker
script macro:

	init_thread_union
	init_stack

INIT_TASK_DATA() also expands the region to THREAD_SIZE to accommodate the
size of the init stack.  init_thread_union is given its own section so that
it can be placed into the stack space in the right order.  I'm assuming
that the ia64 ordering is correct and that the task_struct is first and the
thread_info second.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Tested-by: default avatarTony Luck <tony.luck@intel.com>
Tested-by: Will Deacon <will.deacon@arm.com> (arm64)
Tested-by: default avatarPalmer Dabbelt <palmer@sifive.com>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 13810193
......@@ -234,8 +234,8 @@ config ARCH_HAS_FORTIFY_SOURCE
config ARCH_HAS_SET_MEMORY
bool
# Select if arch init_task initializer is different to init/init_task.c
config ARCH_INIT_TASK
# Select if arch init_task must go in the __init_task_data section
config ARCH_TASK_STRUCT_ON_STACK
bool
# Select if arch has its private alloc_task_struct() function
......
......@@ -39,9 +39,6 @@ struct thread_info {
.preempt_count = INIT_PREEMPT_COUNT, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* How to get the thread information struct from C. */
register struct thread_info *__current_thread_info __asm__("$8");
#define current_thread_info() __current_thread_info
......
......@@ -62,9 +62,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
static inline __attribute_const__ struct thread_info *current_thread_info(void)
{
register unsigned long sp asm("sp");
......
......@@ -75,9 +75,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/*
* how to get the current stack pointer in C
*/
......
......@@ -51,8 +51,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_stack (init_thread_union.stack)
#define thread_saved_pc(tsk) \
((unsigned long)(tsk->thread.cpu_context.pc))
#define thread_saved_sp(tsk) \
......
......@@ -56,8 +56,6 @@ struct thread_info {
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* Given a task stack pointer, you can find its corresponding
* thread_info structure just by masking it to the THREAD_SIZE
......
......@@ -60,9 +60,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* get the thread information struct of current task */
static inline __attribute__((const))
struct thread_info *current_thread_info(void)
......
......@@ -52,8 +52,6 @@ static inline void release_thread(struct task_struct *dead_task)
/* Nothing needs to be done. */
}
#define init_stack (init_thread_union.stack)
#define cpu_relax() barrier()
void default_idle(void);
......
......@@ -63,8 +63,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#endif /* !__ASSEMBLY__ */
/*
......
......@@ -64,9 +64,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* how to get the thread information struct from C */
register struct thread_info *__current_thread_info asm("gr15");
......
......@@ -46,9 +46,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
......
......@@ -84,9 +84,6 @@ struct thread_info {
.regs = NULL, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* Tacky preprocessor trickery */
#define qqstr(s) qstr(s)
#define qstr(s) #s
......
......@@ -43,7 +43,7 @@ config IA64
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_IOMAP
select GENERIC_SMP_IDLE_THREAD
select ARCH_INIT_TASK
select ARCH_TASK_STRUCT_ON_STACK
select ARCH_TASK_STRUCT_ALLOCATOR
select ARCH_THREAD_STACK_ALLOCATOR
select ARCH_CLOCKSOURCE_DATA
......
......@@ -42,7 +42,7 @@ $(error Sorry, you need a newer version of the assember, one that is built from
endif
KBUILD_CFLAGS += $(cflags-y)
head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
head-y := arch/ia64/kernel/head.o
libs-y += arch/ia64/lib/
core-y += arch/ia64/kernel/ arch/ia64/mm/
......
......@@ -12,6 +12,8 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#define THREAD_SIZE KERNEL_STACK_SIZE
#ifndef __ASSEMBLY__
/*
......@@ -41,8 +43,6 @@ struct thread_info {
#endif
};
#define THREAD_SIZE KERNEL_STACK_SIZE
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
......
......@@ -7,7 +7,7 @@ ifdef CONFIG_DYNAMIC_FTRACE
CFLAGS_REMOVE_ftrace.o = -pg
endif
extra-y := head.o init_task.o vmlinux.lds
extra-y := head.o vmlinux.lds
obj-y := entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
......
// SPDX-License-Identifier: GPL-2.0
/*
* This is where we statically allocate and initialize the initial
* task.
*
* Copyright (C) 1999, 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <linux/uaccess.h>
#include <asm/pgtable.h>
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
/*
* Initial task structure.
*
* We need to make sure that this is properly aligned due to the way process stacks are
* handled. This is done by having a special ".data..init_task" section...
*/
#define init_thread_info init_task_mem.s.thread_info
#define init_stack init_task_mem.stack
union {
struct {
struct task_struct task;
struct thread_info thread_info;
} s;
unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
} init_task_mem asm ("init_task") __init_task_data =
{{
.task = INIT_TASK(init_task_mem.s.task),
.thread_info = INIT_THREAD_INFO(init_task_mem.s.task)
}};
EXPORT_SYMBOL(init_task);
......@@ -3,6 +3,7 @@
#include <asm/cache.h>
#include <asm/ptrace.h>
#include <asm/pgtable.h>
#include <asm/thread_info.h>
#include <asm-generic/vmlinux.lds.h>
......
......@@ -56,9 +56,6 @@ struct thread_info {
.addr_limit = KERNEL_DS, \
}
#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
......
......@@ -41,8 +41,6 @@ struct thread_info {
.preempt_count = INIT_PREEMPT_COUNT, \
}
#define init_stack (init_thread_union.stack)
#ifndef __ASSEMBLY__
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
......@@ -58,8 +56,6 @@ static inline struct thread_info *current_thread_info(void)
}
#endif
#define init_thread_info (init_thread_union.thread_info)
/* entry.S relies on these definitions!
* bits 0-7 are tested at every exception exit
* bits 8-15 are also tested at syscall exit
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment