Skip to content

Commit

Permalink
Merge branch 'tj-percpu' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/tj/misc into core/percpu
  • Loading branch information
Ingo Molnar committed Jan 20, 2009
2 parents 5cdc5e9 + 6b7c38d commit 8f5d36e
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 212 deletions.
45 changes: 0 additions & 45 deletions arch/x86/include/asm/pda.h

This file was deleted.

6 changes: 0 additions & 6 deletions arch/x86/include/asm/percpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ do { \
/* We can use this directly for local CPU (faster). */
DECLARE_PER_CPU(unsigned long, this_cpu_off);

#ifdef CONFIG_X86_64
extern void load_pda_offset(int cpu);
#else
static inline void load_pda_offset(int cpu) { }
#endif

#endif /* !__ASSEMBLY__ */

#ifdef CONFIG_SMP
Expand Down
1 change: 0 additions & 1 deletion arch/x86/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <asm/processor.h>
#include <linux/bitops.h>
#include <linux/threads.h>
#include <asm/pda.h>

extern pud_t level3_kernel_pgt[512];
extern pud_t level3_ident_pgt[512];
Expand Down
23 changes: 22 additions & 1 deletion arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,29 @@ union thread_xstate {
#ifdef CONFIG_X86_64
DECLARE_PER_CPU(struct orig_ist, orig_ist);

DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack);
union irq_stack_union {
char irq_stack[IRQ_STACK_SIZE];
/*
* GCC hardcodes the stack canary as %gs:40. Since the
* irq_stack is the object at %gs:0, we reserve the bottom
* 48 bytes of the irq stack for the canary.
*/
struct {
char gs_base[40];
unsigned long stack_canary;
};
};

DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
DECLARE_PER_CPU(char *, irq_stack_ptr);

static inline void load_gs_base(int cpu)
{
/* Memory clobbers used to order pda/percpu accesses */
mb();
wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
mb();
}
#endif

extern void print_cpu_info(struct cpuinfo_x86 *);
Expand Down
1 change: 0 additions & 1 deletion arch/x86/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
# include <asm/io_apic.h>
# endif
#endif
#include <asm/pda.h>
#include <asm/thread_info.h>
#include <asm/cpumask.h>

Expand Down
17 changes: 8 additions & 9 deletions arch/x86/include/asm/stackprotector.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define _ASM_STACKPROTECTOR_H 1

#include <asm/tsc.h>
#include <asm/pda.h>
#include <asm/processor.h>

/*
* Initialize the stackprotector canary value.
Expand All @@ -16,13 +16,12 @@ static __always_inline void boot_init_stack_canary(void)
u64 tsc;

/*
* If we're the non-boot CPU, nothing set the PDA stack
* canary up for us - and if we are the boot CPU we have
* a 0 stack canary. This is a good place for updating
* it, as we wont ever return from this function (so the
* invalid canaries already on the stack wont ever
* trigger).
*
* Build time only check to make sure the stack_canary is at
* offset 40 in the pda; this is a gcc ABI requirement
*/
BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40);

/*
* We both use the random pool and the current TSC as a source
* of randomness. The TSC only matters for very early init,
* there it already has some randomness on most systems. Later
Expand All @@ -33,7 +32,7 @@ static __always_inline void boot_init_stack_canary(void)
canary += tsc + (tsc << 32UL);

current->stack_canary = canary;
write_pda(stack_canary, canary);
percpu_write(irq_stack_union.stack_canary, canary);
}

#endif
22 changes: 16 additions & 6 deletions arch/x86/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,28 @@ do { \
, "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
"r12", "r13", "r14", "r15"

#ifdef CONFIG_CC_STACKPROTECTOR
#define __switch_canary \
"movq %P[task_canary](%%rsi),%%r8\n\t" \
"movq %%r8,%%gs:%P[gs_canary]\n\t"
#define __switch_canary_param \
, [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \
, [gs_canary] "i" (offsetof(union irq_stack_union, stack_canary))
#else /* CC_STACKPROTECTOR */
#define __switch_canary
#define __switch_canary_param
#endif /* CC_STACKPROTECTOR */

/* Save restore flags to clear handle leaking NT */
#define switch_to(prev, next, last) \
asm volatile(SAVE_CONTEXT \
asm volatile(SAVE_CONTEXT \
"movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \
"movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \
"call __switch_to\n\t" \
".globl thread_return\n" \
"thread_return:\n\t" \
"movq "__percpu_arg([current_task])",%%rsi\n\t" \
"movq %P[task_canary](%%rsi),%%r8\n\t" \
"movq %%r8,%%gs:%P[pda_canary]\n\t" \
__switch_canary \
"movq %P[thread_info](%%rsi),%%r8\n\t" \
LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
"movq %%rax,%%rdi\n\t" \
Expand All @@ -108,9 +119,8 @@ do { \
[ti_flags] "i" (offsetof(struct thread_info, flags)), \
[tif_fork] "i" (TIF_FORK), \
[thread_info] "i" (offsetof(struct task_struct, stack)), \
[task_canary] "i" (offsetof(struct task_struct, stack_canary)),\
[current_task] "m" (per_cpu_var(current_task)), \
[pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
[current_task] "m" (per_cpu_var(current_task)) \
__switch_canary_param \
: "memory", "cc" __EXTRA_CLOBBER)
#endif

Expand Down
5 changes: 0 additions & 5 deletions arch/x86/kernel/asm-offsets_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <linux/hardirq.h>
#include <linux/suspend.h>
#include <linux/kbuild.h>
#include <asm/pda.h>
#include <asm/processor.h>
#include <asm/segment.h>
#include <asm/thread_info.h>
Expand Down Expand Up @@ -48,10 +47,6 @@ int main(void)
#endif
BLANK();
#undef ENTRY
#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
DEFINE(pda_size, sizeof(struct x8664_pda));
BLANK();
#undef ENTRY
#ifdef CONFIG_PARAVIRT
BLANK();
OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
Expand Down
21 changes: 6 additions & 15 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <asm/genapic.h>
#endif

#include <asm/pda.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/desc.h>
Expand Down Expand Up @@ -881,12 +880,13 @@ __setup("clearcpuid=", setup_disablecpuid);
#ifdef CONFIG_X86_64
struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };

DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack);
DEFINE_PER_CPU_FIRST(union irq_stack_union,
irq_stack_union) __aligned(PAGE_SIZE);
#ifdef CONFIG_SMP
DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */
#else
DEFINE_PER_CPU(char *, irq_stack_ptr) =
per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64;
per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
#endif

DEFINE_PER_CPU(unsigned long, kernel_stack) =
Expand All @@ -895,15 +895,6 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack);

DEFINE_PER_CPU(unsigned int, irq_count) = -1;

void __cpuinit pda_init(int cpu)
{
/* Setup up data that may be needed in __get_free_pages early */
loadsegment(fs, 0);
loadsegment(gs, 0);

load_pda_offset(cpu);
}

static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
__aligned(PAGE_SIZE);
Expand Down Expand Up @@ -967,9 +958,9 @@ void __cpuinit cpu_init(void)
struct task_struct *me;
int i;

/* CPU 0 is initialised in head64.c */
if (cpu != 0)
pda_init(cpu);
loadsegment(fs, 0);
loadsegment(gs, 0);
load_gs_base(cpu);

#ifdef CONFIG_NUMA
if (cpu != 0 && percpu_read(node_number) == 0 &&
Expand Down
2 changes: 0 additions & 2 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
if (console_loglevel == 10)
early_printk("Kernel alive\n");

pda_init(0);

x86_64_start_reservations(real_mode_data);
}

Expand Down
37 changes: 13 additions & 24 deletions arch/x86/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -207,19 +207,15 @@ ENTRY(secondary_startup_64)

#ifdef CONFIG_SMP
/*
* early_gdt_base should point to the gdt_page in static percpu init
* data area. Computing this requires two symbols - __per_cpu_load
* and per_cpu__gdt_page. As linker can't do no such relocation, do
* it by hand. As early_gdt_descr is manipulated by C code for
* secondary CPUs, this should be done only once for the boot CPU
* when early_gdt_descr_base contains zero.
* Fix up static pointers that need __per_cpu_load added. The assembler
* is unable to do this directly. This is only needed for the boot cpu.
* These values are set up with the correct base addresses by C code for
* secondary cpus.
*/
movq early_gdt_descr_base(%rip), %rax
testq %rax, %rax
jnz 1f
movq $__per_cpu_load, %rax
addq $per_cpu__gdt_page, %rax
movq %rax, early_gdt_descr_base(%rip)
movq initial_gs(%rip), %rax
cmpl $0, per_cpu__cpu_number(%rax)
jne 1f
addq %rax, early_gdt_descr_base(%rip)
1:
#endif
/*
Expand All @@ -246,13 +242,10 @@ ENTRY(secondary_startup_64)

/* Set up %gs.
*
* On SMP, %gs should point to the per-cpu area. For initial
* boot, make %gs point to the init data section. For a
* secondary CPU,initial_gs should be set to its pda address
* before the CPU runs this code.
*
* On UP, initial_gs points to PER_CPU_VAR(__pda) and doesn't
* change.
* The base of %gs always points to the bottom of the irqstack
* union. If the stack protector canary is enabled, it is
* located at %gs:40. Note that, on SMP, the boot cpu uses
* init data section till per cpu areas are set up.
*/
movl $MSR_GS_BASE,%ecx
movq initial_gs(%rip),%rax
Expand Down Expand Up @@ -285,7 +278,7 @@ ENTRY(secondary_startup_64)
#ifdef CONFIG_SMP
.quad __per_cpu_load
#else
.quad PER_CPU_VAR(__pda)
.quad PER_CPU_VAR(irq_stack_union)
#endif
__FINITDATA

Expand Down Expand Up @@ -431,12 +424,8 @@ NEXT_PAGE(level2_spare_pgt)
.globl early_gdt_descr
early_gdt_descr:
.word GDT_ENTRIES*8-1
#ifdef CONFIG_SMP
early_gdt_descr_base:
.quad 0x0000000000000000
#else
.quad per_cpu__gdt_page
#endif

ENTRY(phys_base)
/* This must match the first entry in level2_kernel_pgt */
Expand Down
8 changes: 0 additions & 8 deletions arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/mmu_context.h>
#include <asm/pda.h>
#include <asm/prctl.h>
#include <asm/desc.h>
#include <asm/proto.h>
Expand Down Expand Up @@ -638,13 +637,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
percpu_write(kernel_stack,
(unsigned long)task_stack_page(next_p) +
THREAD_SIZE - KERNEL_STACK_OFFSET);
#ifdef CONFIG_CC_STACKPROTECTOR
/*
* Build time only check to make sure the stack_canary is at
* offset 40 in the pda; this is a gcc ABI requirement
*/
BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
#endif

/*
* Now maybe reload the debug registers and handle I/O bitmaps
Expand Down
Loading

0 comments on commit 8f5d36e

Please sign in to comment.