Commit ed1cd6de authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc: Activate CONFIG_THREAD_INFO_IN_TASK



This patch activates CONFIG_THREAD_INFO_IN_TASK which
moves the thread_info into task_struct.

Moving thread_info into task_struct has the following advantages:
  - It protects thread_info from corruption in the case of stack
    overflows.
  - Its address is harder to determine if stack addresses are leaked,
    making a number of attacks more difficult.

This has the following consequences:
  - thread_info is now located at the beginning of task_struct.
  - The 'cpu' field is now in task_struct, and only exists when
    CONFIG_SMP is active.
  - thread_info doesn't have anymore the 'task' field.

This patch:
  - Removes all recopy of thread_info struct when the stack changes.
  - Changes the CURRENT_THREAD_INFO() macro to point to current.
  - Selects CONFIG_THREAD_INFO_IN_TASK.
  - Modifies raw_smp_processor_id() to get ->cpu from current without
    including linux/sched.h to avoid circular inclusion and without
    including asm/asm-offsets.h to avoid symbol names duplication
    between ASM constants and C constants.
  - Modifies klp_init_thread_info() to take a task_struct pointer
    argument.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: default avatarNicholas Piggin <npiggin@gmail.com>
[mpe: Add task_stack.h to livepatch.h to fix build fails]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 7aef3766
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ config PPC
	select RTC_LIB
	select SPARSE_IRQ
	select SYSCTL_EXCEPTION_TRACE
	select THREAD_INFO_IN_TASK
	select VIRT_TO_BUS			if !PPC64
	#
	# Please keep this list sorted alphabetically.
+7 −0
Original line number Diff line number Diff line
@@ -427,6 +427,13 @@ else
endif
endif

ifdef CONFIG_SMP
prepare: task_cpu_prepare

task_cpu_prepare: prepare0
	$(eval KBUILD_CFLAGS += -D_TASK_CPU=$(shell awk '{if ($$2 == "TI_CPU") print $$3;}' include/generated/asm-offsets.h))
endif

# Check toolchain versions:
# - gcc-4.6 is the minimum kernel-wide version so nothing required.
checkbin:
+0 −4
Original line number Diff line number Diff line
@@ -51,9 +51,6 @@ struct pt_regs;
extern struct thread_info *critirq_ctx[NR_CPUS];
extern struct thread_info *dbgirq_ctx[NR_CPUS];
extern struct thread_info *mcheckirq_ctx[NR_CPUS];
extern void exc_lvl_ctx_init(void);
#else
#define exc_lvl_ctx_init()
#endif

/*
@@ -62,7 +59,6 @@ extern void exc_lvl_ctx_init(void);
extern struct thread_info *hardirq_ctx[NR_CPUS];
extern struct thread_info *softirq_ctx[NR_CPUS];

extern void irq_ctx_init(void);
void call_do_softirq(void *sp);
void call_do_irq(struct pt_regs *regs, void *sp);
extern void do_IRQ(struct pt_regs *regs);
+4 −3
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <linux/module.h>
#include <linux/ftrace.h>
#include <linux/sched/task_stack.h>

#ifdef CONFIG_LIVEPATCH
static inline int klp_check_compiler_support(void)
@@ -43,13 +44,13 @@ static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
	return ftrace_location_range(faddr, faddr + 16);
}

static inline void klp_init_thread_info(struct thread_info *ti)
static inline void klp_init_thread_info(struct task_struct *p)
{
	/* + 1 to account for STACK_END_MAGIC */
	ti->livepatch_sp = (unsigned long *)(ti + 1) + 1;
	task_thread_info(p)->livepatch_sp = end_of_stack(p) + 1;
}
#else
static void klp_init_thread_info(struct thread_info *ti) { }
static inline void klp_init_thread_info(struct task_struct *p) { }
#endif /* CONFIG_LIVEPATCH */

#endif /* _ASM_POWERPC_LIVEPATCH_H */
+16 −1
Original line number Diff line number Diff line
@@ -83,7 +83,22 @@ int is_cpu_dead(unsigned int cpu);
/* 32-bit */
extern int smp_hw_index[];

#define raw_smp_processor_id()	(current_thread_info()->cpu)
/*
 * This is particularly ugly: it appears we can't actually get the definition
 * of task_struct here, but we need access to the CPU this task is running on.
 * Instead of using task_struct we're using _TASK_CPU which is extracted from
 * asm-offsets.h by kbuild to get the current processor ID.
 *
 * This also needs to be safeguarded when building asm-offsets.s because at
 * that time _TASK_CPU is not defined yet. It could have been guarded by
 * _TASK_CPU itself, but we want the build to fail if _TASK_CPU is missing
 * when building something else than asm-offsets.s
 */
#ifdef GENERATING_ASM_OFFSETS
#define raw_smp_processor_id()		(0)
#else
#define raw_smp_processor_id()		(*(unsigned int *)((void *)current + _TASK_CPU))
#endif
#define hard_smp_processor_id() 	(smp_hw_index[smp_processor_id()])

static inline int get_hard_smp_processor_id(int cpu)
Loading