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: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Add task_stack.h to livepatch.h to fix build fails]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
committed by
Michael Ellerman
parent
7aef376679
commit
ed1cd6deb0
@ -673,24 +673,9 @@ void do_IRQ(struct pt_regs *regs)
|
||||
set_irq_regs(old_regs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prepare the thread_info in the irq stack */
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
|
||||
/* Copy the preempt_count so that the [soft]irq checks work. */
|
||||
irqtp->preempt_count = curtp->preempt_count;
|
||||
|
||||
/* Switch stack and call */
|
||||
call_do_irq(regs, irqtp);
|
||||
|
||||
/* Restore stack limit */
|
||||
irqtp->task = NULL;
|
||||
|
||||
/* Copy back updates to the thread_info */
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
@ -698,85 +683,23 @@ void __init init_IRQ(void)
|
||||
{
|
||||
if (ppc_md.init_IRQ)
|
||||
ppc_md.init_IRQ();
|
||||
|
||||
exc_lvl_ctx_init();
|
||||
|
||||
irq_ctx_init();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
|
||||
struct thread_info *critirq_ctx[NR_CPUS] __read_mostly;
|
||||
struct thread_info *dbgirq_ctx[NR_CPUS] __read_mostly;
|
||||
struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
|
||||
|
||||
void exc_lvl_ctx_init(void)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
int i, cpu_nr;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
#ifdef CONFIG_PPC64
|
||||
cpu_nr = i;
|
||||
#else
|
||||
#ifdef CONFIG_SMP
|
||||
cpu_nr = get_hard_smp_processor_id(i);
|
||||
#else
|
||||
cpu_nr = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
tp = critirq_ctx[cpu_nr];
|
||||
tp->cpu = cpu_nr;
|
||||
tp->preempt_count = 0;
|
||||
|
||||
#ifdef CONFIG_BOOKE
|
||||
tp = dbgirq_ctx[cpu_nr];
|
||||
tp->cpu = cpu_nr;
|
||||
tp->preempt_count = 0;
|
||||
|
||||
tp = mcheckirq_ctx[cpu_nr];
|
||||
tp->cpu = cpu_nr;
|
||||
tp->preempt_count = HARDIRQ_OFFSET;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
|
||||
struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly;
|
||||
|
||||
void irq_ctx_init(void)
|
||||
{
|
||||
struct thread_info *tp;
|
||||
int i;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
tp = softirq_ctx[i];
|
||||
tp->cpu = i;
|
||||
klp_init_thread_info(tp);
|
||||
|
||||
tp = hardirq_ctx[i];
|
||||
tp->cpu = i;
|
||||
klp_init_thread_info(tp);
|
||||
}
|
||||
}
|
||||
|
||||
void do_softirq_own_stack(void)
|
||||
{
|
||||
struct thread_info *curtp, *irqtp;
|
||||
struct thread_info *irqtp;
|
||||
|
||||
curtp = current_thread_info();
|
||||
irqtp = softirq_ctx[smp_processor_id()];
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
call_do_softirq(irqtp);
|
||||
irqtp->task = NULL;
|
||||
|
||||
/* Set any flag that may have been set on the
|
||||
* alternate stack
|
||||
*/
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
}
|
||||
|
||||
irq_hw_number_t virq_to_hw(unsigned int virq)
|
||||
|
||||
Reference in New Issue
Block a user