x86: Drop task from thread_info, add accessor functions
Add accessor functions to get a thread_info from a task_struct, and
vice-versa. This also allows the task_struct pointer to be dropped
from thread_info altogether.
This patch also adds some accessor functions to some of the thread_info
fields, mainly for ones that are derived from a task_struct to begin
with.
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 4df3437..8168ddf 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -23,7 +23,9 @@
#include <linux/atomic.h>
struct thread_info {
+#ifndef CONFIG_ARCH_TASK_THREAD_MERGED
struct task_struct *task; /* main task structure */
+#endif
struct exec_domain *exec_domain; /* execution domain */
__u32 flags; /* low level flags */
__u32 status; /* thread synchronous flags */
@@ -42,6 +44,19 @@
unsigned int uaccess_err:1; /* uaccess failed */
};
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .saved_preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
@@ -54,6 +69,7 @@
.fn = do_no_restart_syscall, \
}, \
}
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
#ifndef CONFIG_ARCH_TASK_THREAD_MERGED
#define init_thread_info (init_thread_union.thread_info)
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index d9c12d3..b0869a6 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -49,7 +49,11 @@
if (addr != (unsigned long)return_to_handler)
return;
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ task = thread_info_task(tinfo);
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
task = tinfo->task;
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
index = task->curr_ret_stack;
if (!task->ret_stack || index < *graph)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4902ef1..edada59 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2529,16 +2529,37 @@
return &tsk_ti->thread_info;
}
+
+static inline struct task_struct *thread_info_task(const struct thread_info *ti)
+{
+ struct task_thread_struct *tsk_ti;
+
+ tsk_ti = container_of(ti, struct task_thread_struct, thread_info);
+
+ return &tsk_ti->task;
+}
+static inline struct exec_domain *get_task_exec_domain(const struct task_struct *task)
+{
+ return task_thread_info(task)->exec_domain;
+}
+
+static inline struct exec_domain *get_ti_exec_domain(const struct thread_info *ti)
+{
+ return ti->exec_domain;
+}
#else
#define task_thread_info(task) ((struct thread_info *)(task)->stack)
-// change ->stack member to audit locations
-#endif
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
#define task_stack_page(task) ((task)->stack)
static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
{
*task_thread_info(p) = *task_thread_info(org);
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ *thread_info_task(task_thread_info(p)) = *p;
+#else
task_thread_info(p)->task = p;
+#endif
}
static inline unsigned long *end_of_stack(struct task_struct *p)
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 0dbeae3..c41fc26 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -49,8 +49,13 @@
{
set_personality(0);
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ if (get_ti_exec_domain(current_thread_info())->handler != default_handler)
+ get_ti_exec_domain(current_thread_info())->handler(segment, regp);
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
if (current_thread_info()->exec_domain->handler != default_handler)
current_thread_info()->exec_domain->handler(segment, regp);
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
else
send_sig(SIGSEGV, current, 1);
}
@@ -136,9 +141,17 @@
int __set_personality(unsigned int personality)
{
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ struct exec_domain *oep = get_ti_exec_domain(current_thread_info());
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
struct exec_domain *oep = current_thread_info()->exec_domain;
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ *get_ti_exec_domain(current_thread_info()) = *lookup_exec_domain(personality);
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
current_thread_info()->exec_domain = lookup_exec_domain(personality);
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
current->personality = personality;
module_put(oep->module);
diff --git a/kernel/exit.c b/kernel/exit.c
index 601a2e8..a77a38d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -806,7 +806,11 @@
if (group_dead)
disassociate_ctty(1);
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ module_put(get_task_exec_domain(tsk)->module);
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
module_put(task_thread_info(tsk)->exec_domain->module);
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
proc_exit_connector(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
index 73395a5..a2e17d7 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1147,10 +1147,6 @@
int trace)
{
int retval;
- // XXX - should be struct task_thread_struct *p
-#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
- struct thread_info *ti;
-#endif
struct task_struct *p;
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
@@ -1239,9 +1235,7 @@
#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
printk(KERN_INFO "pjw: before task_thread_info()\n");
- ti = task_thread_info(p);
- /* XXX - fixme accessors please */
- if (!try_module_get(ti->exec_domain->module))
+ if (!try_module_get(get_task_exec_domain(p)->module))
goto bad_fork_cleanup_count;
#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
if (!try_module_get(task_thread_info(p)->exec_domain->module))
@@ -1556,7 +1550,11 @@
threadgroup_change_end(current);
cgroup_exit(p, 0);
delayacct_tsk_free(p);
+#ifdef CONFIG_ARCH_TASK_THREAD_MERGED
+ module_put(get_task_exec_domain(p)->module);
+#else /* CONFIG_ARCH_TASK_THREAD_MERGED */
module_put(task_thread_info(p)->exec_domain->module);
+#endif /* CONFIG_ARCH_TASK_THREAD_MERGED */
bad_fork_cleanup_count:
atomic_dec(&p->cred->user->processes);
exit_creds(p);