diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-18 12:15:49 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-18 12:15:49 -0500 |
commit | af37501c792107c2bde1524bdae38d9a247b841a (patch) | |
tree | b50ee90d29e72956b8b7d8d19677fe5996755d49 /arch/x86/include | |
parent | d859e29fe34cb833071b20aef860ee94fbad9bb2 (diff) | |
parent | 99937d6455cea95405ac681c86a857d0fcd530bd (diff) |
Merge branch 'core/percpu' into perfcounters/core
Conflicts:
arch/x86/include/asm/pda.h
We merge tip/core/percpu into tip/perfcounters/core because of a
semantic and contextual conflict: the former eliminates the PDA,
while the latter extends it with apic_perf_irqs field.
Resolve the conflict by moving the new field to the irq_cpustat
structure on 64-bit too.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include')
29 files changed, 282 insertions, 376 deletions
diff --git a/arch/x86/include/asm/apicnum.h b/arch/x86/include/asm/apicnum.h new file mode 100644 index 000000000000..82f613c607ce --- /dev/null +++ b/arch/x86/include/asm/apicnum.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef _ASM_X86_APICNUM_H | ||
2 | #define _ASM_X86_APICNUM_H | ||
3 | |||
4 | /* define MAX_IO_APICS */ | ||
5 | #ifdef CONFIG_X86_32 | ||
6 | # define MAX_IO_APICS 64 | ||
7 | #else | ||
8 | # define MAX_IO_APICS 128 | ||
9 | # define MAX_LOCAL_APIC 32768 | ||
10 | #endif | ||
11 | |||
12 | #endif /* _ASM_X86_APICNUM_H */ | ||
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index e02a359d2aa5..02b47a603fc8 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Copyright 1992, Linus Torvalds. | 5 | * Copyright 1992, Linus Torvalds. |
6 | * | ||
7 | * Note: inlines with more than a single statement should be marked | ||
8 | * __always_inline to avoid problems with older gcc's inlining heuristics. | ||
6 | */ | 9 | */ |
7 | 10 | ||
8 | #ifndef _LINUX_BITOPS_H | 11 | #ifndef _LINUX_BITOPS_H |
@@ -53,7 +56,8 @@ | |||
53 | * Note that @nr may be almost arbitrarily large; this function is not | 56 | * Note that @nr may be almost arbitrarily large; this function is not |
54 | * restricted to acting on a single-word quantity. | 57 | * restricted to acting on a single-word quantity. |
55 | */ | 58 | */ |
56 | static inline void set_bit(unsigned int nr, volatile unsigned long *addr) | 59 | static __always_inline void |
60 | set_bit(unsigned int nr, volatile unsigned long *addr) | ||
57 | { | 61 | { |
58 | if (IS_IMMEDIATE(nr)) { | 62 | if (IS_IMMEDIATE(nr)) { |
59 | asm volatile(LOCK_PREFIX "orb %1,%0" | 63 | asm volatile(LOCK_PREFIX "orb %1,%0" |
@@ -90,7 +94,8 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) | |||
90 | * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() | 94 | * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() |
91 | * in order to ensure changes are visible on other processors. | 95 | * in order to ensure changes are visible on other processors. |
92 | */ | 96 | */ |
93 | static inline void clear_bit(int nr, volatile unsigned long *addr) | 97 | static __always_inline void |
98 | clear_bit(int nr, volatile unsigned long *addr) | ||
94 | { | 99 | { |
95 | if (IS_IMMEDIATE(nr)) { | 100 | if (IS_IMMEDIATE(nr)) { |
96 | asm volatile(LOCK_PREFIX "andb %1,%0" | 101 | asm volatile(LOCK_PREFIX "andb %1,%0" |
@@ -204,7 +209,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) | |||
204 | * | 209 | * |
205 | * This is the same as test_and_set_bit on x86. | 210 | * This is the same as test_and_set_bit on x86. |
206 | */ | 211 | */ |
207 | static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr) | 212 | static __always_inline int |
213 | test_and_set_bit_lock(int nr, volatile unsigned long *addr) | ||
208 | { | 214 | { |
209 | return test_and_set_bit(nr, addr); | 215 | return test_and_set_bit(nr, addr); |
210 | } | 216 | } |
@@ -300,7 +306,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
300 | return oldbit; | 306 | return oldbit; |
301 | } | 307 | } |
302 | 308 | ||
303 | static inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) |
304 | { | 310 | { |
305 | return ((1UL << (nr % BITS_PER_LONG)) & | 311 | return ((1UL << (nr % BITS_PER_LONG)) & |
306 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; | 312 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; |
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index bae482df6039..f03b23e32864 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h | |||
@@ -7,6 +7,20 @@ | |||
7 | #include <linux/nodemask.h> | 7 | #include <linux/nodemask.h> |
8 | #include <linux/percpu.h> | 8 | #include <linux/percpu.h> |
9 | 9 | ||
10 | #ifdef CONFIG_SMP | ||
11 | |||
12 | extern void prefill_possible_map(void); | ||
13 | |||
14 | #else /* CONFIG_SMP */ | ||
15 | |||
16 | static inline void prefill_possible_map(void) {} | ||
17 | |||
18 | #define cpu_physical_id(cpu) boot_cpu_physical_apicid | ||
19 | #define safe_smp_processor_id() 0 | ||
20 | #define stack_smp_processor_id() 0 | ||
21 | |||
22 | #endif /* CONFIG_SMP */ | ||
23 | |||
10 | struct x86_cpu { | 24 | struct x86_cpu { |
11 | struct cpu cpu; | 25 | struct cpu cpu; |
12 | }; | 26 | }; |
@@ -17,4 +31,11 @@ extern void arch_unregister_cpu(int); | |||
17 | #endif | 31 | #endif |
18 | 32 | ||
19 | DECLARE_PER_CPU(int, cpu_state); | 33 | DECLARE_PER_CPU(int, cpu_state); |
34 | |||
35 | #ifdef CONFIG_X86_HAS_BOOT_CPU_ID | ||
36 | extern unsigned char boot_cpu_id; | ||
37 | #else | ||
38 | #define boot_cpu_id 0 | ||
39 | #endif | ||
40 | |||
20 | #endif /* _ASM_X86_CPU_H */ | 41 | #endif /* _ASM_X86_CPU_H */ |
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h new file mode 100644 index 000000000000..26c6dad90479 --- /dev/null +++ b/arch/x86/include/asm/cpumask.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _ASM_X86_CPUMASK_H | ||
2 | #define _ASM_X86_CPUMASK_H | ||
3 | #ifndef __ASSEMBLY__ | ||
4 | #include <linux/cpumask.h> | ||
5 | |||
6 | #ifdef CONFIG_X86_64 | ||
7 | |||
8 | extern cpumask_var_t cpu_callin_mask; | ||
9 | extern cpumask_var_t cpu_callout_mask; | ||
10 | extern cpumask_var_t cpu_initialized_mask; | ||
11 | extern cpumask_var_t cpu_sibling_setup_mask; | ||
12 | |||
13 | #else /* CONFIG_X86_32 */ | ||
14 | |||
15 | extern cpumask_t cpu_callin_map; | ||
16 | extern cpumask_t cpu_callout_map; | ||
17 | extern cpumask_t cpu_initialized; | ||
18 | extern cpumask_t cpu_sibling_setup_map; | ||
19 | |||
20 | #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) | ||
21 | #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) | ||
22 | #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) | ||
23 | #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) | ||
24 | |||
25 | #endif /* CONFIG_X86_32 */ | ||
26 | |||
27 | #endif /* __ASSEMBLY__ */ | ||
28 | #endif /* _ASM_X86_CPUMASK_H */ | ||
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index 0930b4f8d672..c68c361697e1 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h | |||
@@ -1,39 +1,21 @@ | |||
1 | #ifndef _ASM_X86_CURRENT_H | 1 | #ifndef _ASM_X86_CURRENT_H |
2 | #define _ASM_X86_CURRENT_H | 2 | #define _ASM_X86_CURRENT_H |
3 | 3 | ||
4 | #ifdef CONFIG_X86_32 | ||
5 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
6 | #include <asm/percpu.h> | 5 | #include <asm/percpu.h> |
7 | 6 | ||
7 | #ifndef __ASSEMBLY__ | ||
8 | struct task_struct; | 8 | struct task_struct; |
9 | 9 | ||
10 | DECLARE_PER_CPU(struct task_struct *, current_task); | 10 | DECLARE_PER_CPU(struct task_struct *, current_task); |
11 | static __always_inline struct task_struct *get_current(void) | ||
12 | { | ||
13 | return x86_read_percpu(current_task); | ||
14 | } | ||
15 | |||
16 | #else /* X86_32 */ | ||
17 | |||
18 | #ifndef __ASSEMBLY__ | ||
19 | #include <asm/pda.h> | ||
20 | |||
21 | struct task_struct; | ||
22 | 11 | ||
23 | static __always_inline struct task_struct *get_current(void) | 12 | static __always_inline struct task_struct *get_current(void) |
24 | { | 13 | { |
25 | return read_pda(pcurrent); | 14 | return percpu_read(current_task); |
26 | } | 15 | } |
27 | 16 | ||
28 | #else /* __ASSEMBLY__ */ | 17 | #define current get_current() |
29 | |||
30 | #include <asm/asm-offsets.h> | ||
31 | #define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg | ||
32 | 18 | ||
33 | #endif /* __ASSEMBLY__ */ | 19 | #endif /* __ASSEMBLY__ */ |
34 | 20 | ||
35 | #endif /* X86_32 */ | ||
36 | |||
37 | #define current get_current() | ||
38 | |||
39 | #endif /* _ASM_X86_CURRENT_H */ | 21 | #endif /* _ASM_X86_CURRENT_H */ |
diff --git a/arch/x86/include/asm/hardirq_32.h b/arch/x86/include/asm/hardirq_32.h index 7a07897a7888..7838276bfe51 100644 --- a/arch/x86/include/asm/hardirq_32.h +++ b/arch/x86/include/asm/hardirq_32.h | |||
@@ -20,6 +20,9 @@ typedef struct { | |||
20 | 20 | ||
21 | DECLARE_PER_CPU(irq_cpustat_t, irq_stat); | 21 | DECLARE_PER_CPU(irq_cpustat_t, irq_stat); |
22 | 22 | ||
23 | /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ | ||
24 | #define MAX_HARDIRQS_PER_CPU NR_VECTORS | ||
25 | |||
23 | #define __ARCH_IRQ_STAT | 26 | #define __ARCH_IRQ_STAT |
24 | #define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member) | 27 | #define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member) |
25 | 28 | ||
diff --git a/arch/x86/include/asm/hardirq_64.h b/arch/x86/include/asm/hardirq_64.h index b5a6b5d56704..42930b279215 100644 --- a/arch/x86/include/asm/hardirq_64.h +++ b/arch/x86/include/asm/hardirq_64.h | |||
@@ -3,22 +3,37 @@ | |||
3 | 3 | ||
4 | #include <linux/threads.h> | 4 | #include <linux/threads.h> |
5 | #include <linux/irq.h> | 5 | #include <linux/irq.h> |
6 | #include <asm/pda.h> | ||
7 | #include <asm/apic.h> | 6 | #include <asm/apic.h> |
8 | 7 | ||
8 | typedef struct { | ||
9 | unsigned int __softirq_pending; | ||
10 | unsigned int __nmi_count; /* arch dependent */ | ||
11 | unsigned int apic_timer_irqs; /* arch dependent */ | ||
12 | unsigned int apic_perf_irqs; /* arch dependent */ | ||
13 | unsigned int irq0_irqs; | ||
14 | unsigned int irq_resched_count; | ||
15 | unsigned int irq_call_count; | ||
16 | unsigned int irq_tlb_count; | ||
17 | unsigned int irq_thermal_count; | ||
18 | unsigned int irq_spurious_count; | ||
19 | unsigned int irq_threshold_count; | ||
20 | } ____cacheline_aligned irq_cpustat_t; | ||
21 | |||
22 | DECLARE_PER_CPU(irq_cpustat_t, irq_stat); | ||
23 | |||
9 | /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ | 24 | /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ |
10 | #define MAX_HARDIRQS_PER_CPU NR_VECTORS | 25 | #define MAX_HARDIRQS_PER_CPU NR_VECTORS |
11 | 26 | ||
12 | #define __ARCH_IRQ_STAT 1 | 27 | #define __ARCH_IRQ_STAT 1 |
13 | 28 | ||
14 | #define inc_irq_stat(member) add_pda(member, 1) | 29 | #define inc_irq_stat(member) percpu_add(irq_stat.member, 1) |
15 | 30 | ||
16 | #define local_softirq_pending() read_pda(__softirq_pending) | 31 | #define local_softirq_pending() percpu_read(irq_stat.__softirq_pending) |
17 | 32 | ||
18 | #define __ARCH_SET_SOFTIRQ_PENDING 1 | 33 | #define __ARCH_SET_SOFTIRQ_PENDING 1 |
19 | 34 | ||
20 | #define set_softirq_pending(x) write_pda(__softirq_pending, (x)) | 35 | #define set_softirq_pending(x) percpu_write(irq_stat.__softirq_pending, (x)) |
21 | #define or_softirq_pending(x) or_pda(__softirq_pending, (x)) | 36 | #define or_softirq_pending(x) percpu_or(irq_stat.__softirq_pending, (x)) |
22 | 37 | ||
23 | extern void ack_bad_irq(unsigned int irq); | 38 | extern void ack_bad_irq(unsigned int irq); |
24 | 39 | ||
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 7a1f44ac1f17..08ec793aa043 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
@@ -114,38 +114,16 @@ struct IR_IO_APIC_route_entry { | |||
114 | extern int nr_ioapics; | 114 | extern int nr_ioapics; |
115 | extern int nr_ioapic_registers[MAX_IO_APICS]; | 115 | extern int nr_ioapic_registers[MAX_IO_APICS]; |
116 | 116 | ||
117 | /* | ||
118 | * MP-BIOS irq configuration table structures: | ||
119 | */ | ||
120 | |||
121 | #define MP_MAX_IOAPIC_PIN 127 | 117 | #define MP_MAX_IOAPIC_PIN 127 |
122 | 118 | ||
123 | struct mp_config_ioapic { | ||
124 | unsigned long mp_apicaddr; | ||
125 | unsigned int mp_apicid; | ||
126 | unsigned char mp_type; | ||
127 | unsigned char mp_apicver; | ||
128 | unsigned char mp_flags; | ||
129 | }; | ||
130 | |||
131 | struct mp_config_intsrc { | ||
132 | unsigned int mp_dstapic; | ||
133 | unsigned char mp_type; | ||
134 | unsigned char mp_irqtype; | ||
135 | unsigned short mp_irqflag; | ||
136 | unsigned char mp_srcbus; | ||
137 | unsigned char mp_srcbusirq; | ||
138 | unsigned char mp_dstirq; | ||
139 | }; | ||
140 | |||
141 | /* I/O APIC entries */ | 119 | /* I/O APIC entries */ |
142 | extern struct mp_config_ioapic mp_ioapics[MAX_IO_APICS]; | 120 | extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; |
143 | 121 | ||
144 | /* # of MP IRQ source entries */ | 122 | /* # of MP IRQ source entries */ |
145 | extern int mp_irq_entries; | 123 | extern int mp_irq_entries; |
146 | 124 | ||
147 | /* MP IRQ source entries */ | 125 | /* MP IRQ source entries */ |
148 | extern struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; | 126 | extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; |
149 | 127 | ||
150 | /* non-0 if default (table-less) MP configuration */ | 128 | /* non-0 if default (table-less) MP configuration */ |
151 | extern int mpc_default_type; | 129 | extern int mpc_default_type; |
diff --git a/arch/x86/include/asm/irq_regs_32.h b/arch/x86/include/asm/irq_regs_32.h index 86afd7473457..d7ed33ee94e9 100644 --- a/arch/x86/include/asm/irq_regs_32.h +++ b/arch/x86/include/asm/irq_regs_32.h | |||
@@ -15,7 +15,7 @@ DECLARE_PER_CPU(struct pt_regs *, irq_regs); | |||
15 | 15 | ||
16 | static inline struct pt_regs *get_irq_regs(void) | 16 | static inline struct pt_regs *get_irq_regs(void) |
17 | { | 17 | { |
18 | return x86_read_percpu(irq_regs); | 18 | return percpu_read(irq_regs); |
19 | } | 19 | } |
20 | 20 | ||
21 | static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) | 21 | static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) |
@@ -23,7 +23,7 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) | |||
23 | struct pt_regs *old_regs; | 23 | struct pt_regs *old_regs; |
24 | 24 | ||
25 | old_regs = get_irq_regs(); | 25 | old_regs = get_irq_regs(); |
26 | x86_write_percpu(irq_regs, new_regs); | 26 | percpu_write(irq_regs, new_regs); |
27 | 27 | ||
28 | return old_regs; | 28 | return old_regs; |
29 | } | 29 | } |
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 21a0b92027f5..1554d0236e03 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h | |||
@@ -110,6 +110,8 @@ | |||
110 | 110 | ||
111 | #if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER) | 111 | #if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER) |
112 | 112 | ||
113 | #include <asm/apicnum.h> /* need MAX_IO_APICS */ | ||
114 | |||
113 | #ifndef CONFIG_SPARSE_IRQ | 115 | #ifndef CONFIG_SPARSE_IRQ |
114 | # if NR_CPUS < MAX_IO_APICS | 116 | # if NR_CPUS < MAX_IO_APICS |
115 | # define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) | 117 | # define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) |
@@ -117,11 +119,12 @@ | |||
117 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) | 119 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) |
118 | # endif | 120 | # endif |
119 | #else | 121 | #else |
120 | # if (8 * NR_CPUS) > (32 * MAX_IO_APICS) | 122 | |
121 | # define NR_IRQS (NR_VECTORS + (8 * NR_CPUS)) | 123 | # define NR_IRQS \ |
122 | # else | 124 | ((8 * NR_CPUS) > (32 * MAX_IO_APICS) ? \ |
123 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) | 125 | (NR_VECTORS + (8 * NR_CPUS)) : \ |
124 | # endif | 126 | (NR_VECTORS + (32 * MAX_IO_APICS))) \ |
127 | |||
125 | #endif | 128 | #endif |
126 | 129 | ||
127 | #elif defined(CONFIG_X86_VOYAGER) | 130 | #elif defined(CONFIG_X86_VOYAGER) |
diff --git a/arch/x86/include/asm/mach-default/mach_wakecpu.h b/arch/x86/include/asm/mach-default/mach_wakecpu.h index ceb013660146..89897a6a65b9 100644 --- a/arch/x86/include/asm/mach-default/mach_wakecpu.h +++ b/arch/x86/include/asm/mach-default/mach_wakecpu.h | |||
@@ -24,7 +24,13 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) | |||
24 | { | 24 | { |
25 | } | 25 | } |
26 | 26 | ||
27 | #ifdef CONFIG_SMP | ||
27 | extern void __inquire_remote_apic(int apicid); | 28 | extern void __inquire_remote_apic(int apicid); |
29 | #else /* CONFIG_SMP */ | ||
30 | static inline void __inquire_remote_apic(int apicid) | ||
31 | { | ||
32 | } | ||
33 | #endif /* CONFIG_SMP */ | ||
28 | 34 | ||
29 | static inline void inquire_remote_apic(int apicid) | 35 | static inline void inquire_remote_apic(int apicid) |
30 | { | 36 | { |
diff --git a/arch/x86/include/asm/mmu_context_32.h b/arch/x86/include/asm/mmu_context_32.h index 7e98ce1d2c0e..08b53454f831 100644 --- a/arch/x86/include/asm/mmu_context_32.h +++ b/arch/x86/include/asm/mmu_context_32.h | |||
@@ -4,8 +4,8 @@ | |||
4 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 4 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) |
5 | { | 5 | { |
6 | #ifdef CONFIG_SMP | 6 | #ifdef CONFIG_SMP |
7 | if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) | 7 | if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) |
8 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_LAZY); | 8 | percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); |
9 | #endif | 9 | #endif |
10 | } | 10 | } |
11 | 11 | ||
@@ -19,8 +19,8 @@ static inline void switch_mm(struct mm_struct *prev, | |||
19 | /* stop flush ipis for the previous mm */ | 19 | /* stop flush ipis for the previous mm */ |
20 | cpu_clear(cpu, prev->cpu_vm_mask); | 20 | cpu_clear(cpu, prev->cpu_vm_mask); |
21 | #ifdef CONFIG_SMP | 21 | #ifdef CONFIG_SMP |
22 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); | 22 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
23 | x86_write_percpu(cpu_tlbstate.active_mm, next); | 23 | percpu_write(cpu_tlbstate.active_mm, next); |
24 | #endif | 24 | #endif |
25 | cpu_set(cpu, next->cpu_vm_mask); | 25 | cpu_set(cpu, next->cpu_vm_mask); |
26 | 26 | ||
@@ -35,8 +35,8 @@ static inline void switch_mm(struct mm_struct *prev, | |||
35 | } | 35 | } |
36 | #ifdef CONFIG_SMP | 36 | #ifdef CONFIG_SMP |
37 | else { | 37 | else { |
38 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); | 38 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
39 | BUG_ON(x86_read_percpu(cpu_tlbstate.active_mm) != next); | 39 | BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); |
40 | 40 | ||
41 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { | 41 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { |
42 | /* We were in lazy tlb mode and leave_mm disabled | 42 | /* We were in lazy tlb mode and leave_mm disabled |
diff --git a/arch/x86/include/asm/mmu_context_64.h b/arch/x86/include/asm/mmu_context_64.h index 677d36e9540a..c4572505ab3e 100644 --- a/arch/x86/include/asm/mmu_context_64.h +++ b/arch/x86/include/asm/mmu_context_64.h | |||
@@ -1,13 +1,11 @@ | |||
1 | #ifndef _ASM_X86_MMU_CONTEXT_64_H | 1 | #ifndef _ASM_X86_MMU_CONTEXT_64_H |
2 | #define _ASM_X86_MMU_CONTEXT_64_H | 2 | #define _ASM_X86_MMU_CONTEXT_64_H |
3 | 3 | ||
4 | #include <asm/pda.h> | ||
5 | |||
6 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 4 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) |
7 | { | 5 | { |
8 | #ifdef CONFIG_SMP | 6 | #ifdef CONFIG_SMP |
9 | if (read_pda(mmu_state) == TLBSTATE_OK) | 7 | if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) |
10 | write_pda(mmu_state, TLBSTATE_LAZY); | 8 | percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); |
11 | #endif | 9 | #endif |
12 | } | 10 | } |
13 | 11 | ||
@@ -19,8 +17,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
19 | /* stop flush ipis for the previous mm */ | 17 | /* stop flush ipis for the previous mm */ |
20 | cpu_clear(cpu, prev->cpu_vm_mask); | 18 | cpu_clear(cpu, prev->cpu_vm_mask); |
21 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
22 | write_pda(mmu_state, TLBSTATE_OK); | 20 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
23 | write_pda(active_mm, next); | 21 | percpu_write(cpu_tlbstate.active_mm, next); |
24 | #endif | 22 | #endif |
25 | cpu_set(cpu, next->cpu_vm_mask); | 23 | cpu_set(cpu, next->cpu_vm_mask); |
26 | load_cr3(next->pgd); | 24 | load_cr3(next->pgd); |
@@ -30,9 +28,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
30 | } | 28 | } |
31 | #ifdef CONFIG_SMP | 29 | #ifdef CONFIG_SMP |
32 | else { | 30 | else { |
33 | write_pda(mmu_state, TLBSTATE_OK); | 31 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); |
34 | if (read_pda(active_mm) != next) | 32 | BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); |
35 | BUG(); | 33 | |
36 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { | 34 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { |
37 | /* We were in lazy tlb mode and leave_mm disabled | 35 | /* We were in lazy tlb mode and leave_mm disabled |
38 | * tlb flush IPI delivery. We must reload CR3 | 36 | * tlb flush IPI delivery. We must reload CR3 |
diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h index 59568bc4767f..4a7f96d7c188 100644 --- a/arch/x86/include/asm/mpspec_def.h +++ b/arch/x86/include/asm/mpspec_def.h | |||
@@ -24,17 +24,18 @@ | |||
24 | # endif | 24 | # endif |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | struct intel_mp_floating { | 27 | /* Intel MP Floating Pointer Structure */ |
28 | char mpf_signature[4]; /* "_MP_" */ | 28 | struct mpf_intel { |
29 | unsigned int mpf_physptr; /* Configuration table address */ | 29 | char signature[4]; /* "_MP_" */ |
30 | unsigned char mpf_length; /* Our length (paragraphs) */ | 30 | unsigned int physptr; /* Configuration table address */ |
31 | unsigned char mpf_specification;/* Specification version */ | 31 | unsigned char length; /* Our length (paragraphs) */ |
32 | unsigned char mpf_checksum; /* Checksum (makes sum 0) */ | 32 | unsigned char specification; /* Specification version */ |
33 | unsigned char mpf_feature1; /* Standard or configuration ? */ | 33 | unsigned char checksum; /* Checksum (makes sum 0) */ |
34 | unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */ | 34 | unsigned char feature1; /* Standard or configuration ? */ |
35 | unsigned char mpf_feature3; /* Unused (0) */ | 35 | unsigned char feature2; /* Bit7 set for IMCR|PIC */ |
36 | unsigned char mpf_feature4; /* Unused (0) */ | 36 | unsigned char feature3; /* Unused (0) */ |
37 | unsigned char mpf_feature5; /* Unused (0) */ | 37 | unsigned char feature4; /* Unused (0) */ |
38 | unsigned char feature5; /* Unused (0) */ | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | #define MPC_SIGNATURE "PCMP" | 41 | #define MPC_SIGNATURE "PCMP" |
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index cb988aab716d..14080d22edb3 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h | |||
@@ -58,15 +58,15 @@ struct mtrr_gentry { | |||
58 | #endif /* !__i386__ */ | 58 | #endif /* !__i386__ */ |
59 | 59 | ||
60 | struct mtrr_var_range { | 60 | struct mtrr_var_range { |
61 | u32 base_lo; | 61 | __u32 base_lo; |
62 | u32 base_hi; | 62 | __u32 base_hi; |
63 | u32 mask_lo; | 63 | __u32 mask_lo; |
64 | u32 mask_hi; | 64 | __u32 mask_hi; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | /* In the Intel processor's MTRR interface, the MTRR type is always held in | 67 | /* In the Intel processor's MTRR interface, the MTRR type is always held in |
68 | an 8 bit field: */ | 68 | an 8 bit field: */ |
69 | typedef u8 mtrr_type; | 69 | typedef __u8 mtrr_type; |
70 | 70 | ||
71 | #define MTRR_NUM_FIXED_RANGES 88 | 71 | #define MTRR_NUM_FIXED_RANGES 88 |
72 | #define MTRR_MAX_VAR_RANGES 256 | 72 | #define MTRR_MAX_VAR_RANGES 256 |
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 5ebca29f44f0..e27fdbe5f9e4 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h | |||
@@ -13,8 +13,8 @@ | |||
13 | #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) | 13 | #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) |
14 | #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) | 14 | #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) |
15 | 15 | ||
16 | #define IRQSTACK_ORDER 2 | 16 | #define IRQ_STACK_ORDER 2 |
17 | #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) | 17 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) |
18 | 18 | ||
19 | #define STACKFAULT_STACK 1 | 19 | #define STACKFAULT_STACK 1 |
20 | #define DOUBLEFAULT_STACK 2 | 20 | #define DOUBLEFAULT_STACK 2 |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index ba3e2ff6aedc..c26c6bf4da00 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -244,7 +244,8 @@ struct pv_mmu_ops { | |||
244 | void (*flush_tlb_user)(void); | 244 | void (*flush_tlb_user)(void); |
245 | void (*flush_tlb_kernel)(void); | 245 | void (*flush_tlb_kernel)(void); |
246 | void (*flush_tlb_single)(unsigned long addr); | 246 | void (*flush_tlb_single)(unsigned long addr); |
247 | void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm, | 247 | void (*flush_tlb_others)(const struct cpumask *cpus, |
248 | struct mm_struct *mm, | ||
248 | unsigned long va); | 249 | unsigned long va); |
249 | 250 | ||
250 | /* Hooks for allocating and freeing a pagetable top-level */ | 251 | /* Hooks for allocating and freeing a pagetable top-level */ |
@@ -984,10 +985,11 @@ static inline void __flush_tlb_single(unsigned long addr) | |||
984 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); | 985 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); |
985 | } | 986 | } |
986 | 987 | ||
987 | static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, | 988 | static inline void flush_tlb_others(const struct cpumask *cpumask, |
989 | struct mm_struct *mm, | ||
988 | unsigned long va) | 990 | unsigned long va) |
989 | { | 991 | { |
990 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va); | 992 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va); |
991 | } | 993 | } |
992 | 994 | ||
993 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | 995 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) |
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 90a8d9d4206b..c31ca048a901 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h | |||
@@ -5,134 +5,41 @@ | |||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/cache.h> | 7 | #include <linux/cache.h> |
8 | #include <linux/threads.h> | ||
8 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | #include <asm/percpu.h> | ||
9 | 11 | ||
10 | /* Per processor datastructure. %gs points to it while the kernel runs */ | 12 | /* Per processor datastructure. %gs points to it while the kernel runs */ |
11 | struct x8664_pda { | 13 | struct x8664_pda { |
12 | struct task_struct *pcurrent; /* 0 Current process */ | 14 | unsigned long unused1; |
13 | unsigned long data_offset; /* 8 Per cpu data offset from linker | 15 | unsigned long unused2; |
14 | address */ | 16 | unsigned long unused3; |
15 | unsigned long kernelstack; /* 16 top of kernel stack for current */ | 17 | unsigned long unused4; |
16 | unsigned long oldrsp; /* 24 user rsp for system call */ | 18 | int unused5; |
17 | int irqcount; /* 32 Irq nesting counter. Starts -1 */ | 19 | unsigned int unused6; /* 36 was cpunumber */ |
18 | unsigned int cpunumber; /* 36 Logical CPU number */ | ||
19 | #ifdef CONFIG_CC_STACKPROTECTOR | 20 | #ifdef CONFIG_CC_STACKPROTECTOR |
20 | unsigned long stack_canary; /* 40 stack canary value */ | 21 | unsigned long stack_canary; /* 40 stack canary value */ |
21 | /* gcc-ABI: this canary MUST be at | 22 | /* gcc-ABI: this canary MUST be at |
22 | offset 40!!! */ | 23 | offset 40!!! */ |
23 | #endif | 24 | #endif |
24 | char *irqstackptr; | ||
25 | short nodenumber; /* number of current node (32k max) */ | ||
26 | short in_bootmem; /* pda lives in bootmem */ | 25 | short in_bootmem; /* pda lives in bootmem */ |
27 | unsigned int __softirq_pending; | ||
28 | unsigned int __nmi_count; /* number of NMI on this CPUs */ | ||
29 | short mmu_state; | ||
30 | short isidle; | ||
31 | struct mm_struct *active_mm; | ||
32 | unsigned apic_timer_irqs; | ||
33 | unsigned apic_perf_irqs; | ||
34 | unsigned irq0_irqs; | ||
35 | unsigned irq_resched_count; | ||
36 | unsigned irq_call_count; | ||
37 | unsigned irq_tlb_count; | ||
38 | unsigned irq_thermal_count; | ||
39 | unsigned irq_threshold_count; | ||
40 | unsigned irq_spurious_count; | ||
41 | } ____cacheline_aligned_in_smp; | 26 | } ____cacheline_aligned_in_smp; |
42 | 27 | ||
43 | extern struct x8664_pda **_cpu_pda; | 28 | DECLARE_PER_CPU(struct x8664_pda, __pda); |
44 | extern void pda_init(int); | 29 | extern void pda_init(int); |
45 | 30 | ||
46 | #define cpu_pda(i) (_cpu_pda[i]) | 31 | #define cpu_pda(cpu) (&per_cpu(__pda, cpu)) |
47 | 32 | ||
48 | /* | 33 | #define read_pda(field) percpu_read(__pda.field) |
49 | * There is no fast way to get the base address of the PDA, all the accesses | 34 | #define write_pda(field, val) percpu_write(__pda.field, val) |
50 | * have to mention %fs/%gs. So it needs to be done this Torvaldian way. | 35 | #define add_pda(field, val) percpu_add(__pda.field, val) |
51 | */ | 36 | #define sub_pda(field, val) percpu_sub(__pda.field, val) |
52 | extern void __bad_pda_field(void) __attribute__((noreturn)); | 37 | #define or_pda(field, val) percpu_or(__pda.field, val) |
53 | |||
54 | /* | ||
55 | * proxy_pda doesn't actually exist, but tell gcc it is accessed for | ||
56 | * all PDA accesses so it gets read/write dependencies right. | ||
57 | */ | ||
58 | extern struct x8664_pda _proxy_pda; | ||
59 | |||
60 | #define pda_offset(field) offsetof(struct x8664_pda, field) | ||
61 | |||
62 | #define pda_to_op(op, field, val) \ | ||
63 | do { \ | ||
64 | typedef typeof(_proxy_pda.field) T__; \ | ||
65 | if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ | ||
66 | switch (sizeof(_proxy_pda.field)) { \ | ||
67 | case 2: \ | ||
68 | asm(op "w %1,%%gs:%c2" : \ | ||
69 | "+m" (_proxy_pda.field) : \ | ||
70 | "ri" ((T__)val), \ | ||
71 | "i"(pda_offset(field))); \ | ||
72 | break; \ | ||
73 | case 4: \ | ||
74 | asm(op "l %1,%%gs:%c2" : \ | ||
75 | "+m" (_proxy_pda.field) : \ | ||
76 | "ri" ((T__)val), \ | ||
77 | "i" (pda_offset(field))); \ | ||
78 | break; \ | ||
79 | case 8: \ | ||
80 | asm(op "q %1,%%gs:%c2": \ | ||
81 | "+m" (_proxy_pda.field) : \ | ||
82 | "ri" ((T__)val), \ | ||
83 | "i"(pda_offset(field))); \ | ||
84 | break; \ | ||
85 | default: \ | ||
86 | __bad_pda_field(); \ | ||
87 | } \ | ||
88 | } while (0) | ||
89 | |||
90 | #define pda_from_op(op, field) \ | ||
91 | ({ \ | ||
92 | typeof(_proxy_pda.field) ret__; \ | ||
93 | switch (sizeof(_proxy_pda.field)) { \ | ||
94 | case 2: \ | ||
95 | asm(op "w %%gs:%c1,%0" : \ | ||
96 | "=r" (ret__) : \ | ||
97 | "i" (pda_offset(field)), \ | ||
98 | "m" (_proxy_pda.field)); \ | ||
99 | break; \ | ||
100 | case 4: \ | ||
101 | asm(op "l %%gs:%c1,%0": \ | ||
102 | "=r" (ret__): \ | ||
103 | "i" (pda_offset(field)), \ | ||
104 | "m" (_proxy_pda.field)); \ | ||
105 | break; \ | ||
106 | case 8: \ | ||
107 | asm(op "q %%gs:%c1,%0": \ | ||
108 | "=r" (ret__) : \ | ||
109 | "i" (pda_offset(field)), \ | ||
110 | "m" (_proxy_pda.field)); \ | ||
111 | break; \ | ||
112 | default: \ | ||
113 | __bad_pda_field(); \ | ||
114 | } \ | ||
115 | ret__; \ | ||
116 | }) | ||
117 | |||
118 | #define read_pda(field) pda_from_op("mov", field) | ||
119 | #define write_pda(field, val) pda_to_op("mov", field, val) | ||
120 | #define add_pda(field, val) pda_to_op("add", field, val) | ||
121 | #define sub_pda(field, val) pda_to_op("sub", field, val) | ||
122 | #define or_pda(field, val) pda_to_op("or", field, val) | ||
123 | 38 | ||
124 | /* This is not atomic against other CPUs -- CPU preemption needs to be off */ | 39 | /* This is not atomic against other CPUs -- CPU preemption needs to be off */ |
125 | #define test_and_clear_bit_pda(bit, field) \ | 40 | #define test_and_clear_bit_pda(bit, field) \ |
126 | ({ \ | 41 | x86_test_and_clear_bit_percpu(bit, __pda.field) |
127 | int old__; \ | ||
128 | asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ | ||
129 | : "=r" (old__), "+m" (_proxy_pda.field) \ | ||
130 | : "dIr" (bit), "i" (pda_offset(field)) : "memory");\ | ||
131 | old__; \ | ||
132 | }) | ||
133 | 42 | ||
134 | #endif | 43 | #endif |
135 | 44 | ||
136 | #define PDA_STACKOFFSET (5*8) | ||
137 | |||
138 | #endif /* _ASM_X86_PDA_H */ | 45 | #endif /* _ASM_X86_PDA_H */ |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index ece72053ba63..165d5272ece1 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
@@ -2,53 +2,12 @@ | |||
2 | #define _ASM_X86_PERCPU_H | 2 | #define _ASM_X86_PERCPU_H |
3 | 3 | ||
4 | #ifdef CONFIG_X86_64 | 4 | #ifdef CONFIG_X86_64 |
5 | #include <linux/compiler.h> | 5 | #define __percpu_seg gs |
6 | 6 | #define __percpu_mov_op movq | |
7 | /* Same as asm-generic/percpu.h, except that we store the per cpu offset | 7 | #else |
8 | in the PDA. Longer term the PDA and every per cpu variable | 8 | #define __percpu_seg fs |
9 | should be just put into a single section and referenced directly | 9 | #define __percpu_mov_op movl |
10 | from %gs */ | ||
11 | |||
12 | #ifdef CONFIG_SMP | ||
13 | #include <asm/pda.h> | ||
14 | |||
15 | #define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) | ||
16 | #define __my_cpu_offset read_pda(data_offset) | ||
17 | |||
18 | #define per_cpu_offset(x) (__per_cpu_offset(x)) | ||
19 | |||
20 | #endif | 10 | #endif |
21 | #include <asm-generic/percpu.h> | ||
22 | |||
23 | DECLARE_PER_CPU(struct x8664_pda, pda); | ||
24 | |||
25 | /* | ||
26 | * These are supposed to be implemented as a single instruction which | ||
27 | * operates on the per-cpu data base segment. x86-64 doesn't have | ||
28 | * that yet, so this is a fairly inefficient workaround for the | ||
29 | * meantime. The single instruction is atomic with respect to | ||
30 | * preemption and interrupts, so we need to explicitly disable | ||
31 | * interrupts here to achieve the same effect. However, because it | ||
32 | * can be used from within interrupt-disable/enable, we can't actually | ||
33 | * disable interrupts; disabling preemption is enough. | ||
34 | */ | ||
35 | #define x86_read_percpu(var) \ | ||
36 | ({ \ | ||
37 | typeof(per_cpu_var(var)) __tmp; \ | ||
38 | preempt_disable(); \ | ||
39 | __tmp = __get_cpu_var(var); \ | ||
40 | preempt_enable(); \ | ||
41 | __tmp; \ | ||
42 | }) | ||
43 | |||
44 | #define x86_write_percpu(var, val) \ | ||
45 | do { \ | ||
46 | preempt_disable(); \ | ||
47 | __get_cpu_var(var) = (val); \ | ||
48 | preempt_enable(); \ | ||
49 | } while(0) | ||
50 | |||
51 | #else /* CONFIG_X86_64 */ | ||
52 | 11 | ||
53 | #ifdef __ASSEMBLY__ | 12 | #ifdef __ASSEMBLY__ |
54 | 13 | ||
@@ -65,47 +24,26 @@ DECLARE_PER_CPU(struct x8664_pda, pda); | |||
65 | * PER_CPU(cpu_gdt_descr, %ebx) | 24 | * PER_CPU(cpu_gdt_descr, %ebx) |
66 | */ | 25 | */ |
67 | #ifdef CONFIG_SMP | 26 | #ifdef CONFIG_SMP |
68 | #define PER_CPU(var, reg) \ | 27 | #define PER_CPU(var, reg) \ |
69 | movl %fs:per_cpu__##this_cpu_off, reg; \ | 28 | __percpu_mov_op %__percpu_seg:per_cpu__this_cpu_off, reg; \ |
70 | lea per_cpu__##var(reg), reg | 29 | lea per_cpu__##var(reg), reg |
71 | #define PER_CPU_VAR(var) %fs:per_cpu__##var | 30 | #define PER_CPU_VAR(var) %__percpu_seg:per_cpu__##var |
72 | #else /* ! SMP */ | 31 | #else /* ! SMP */ |
73 | #define PER_CPU(var, reg) \ | 32 | #define PER_CPU(var, reg) \ |
74 | movl $per_cpu__##var, reg | 33 | __percpu_mov_op $per_cpu__##var, reg |
75 | #define PER_CPU_VAR(var) per_cpu__##var | 34 | #define PER_CPU_VAR(var) per_cpu__##var |
76 | #endif /* SMP */ | 35 | #endif /* SMP */ |
77 | 36 | ||
78 | #else /* ...!ASSEMBLY */ | 37 | #else /* ...!ASSEMBLY */ |
79 | 38 | ||
80 | /* | 39 | #include <linux/stringify.h> |
81 | * PER_CPU finds an address of a per-cpu variable. | ||
82 | * | ||
83 | * Args: | ||
84 | * var - variable name | ||
85 | * cpu - 32bit register containing the current CPU number | ||
86 | * | ||
87 | * The resulting address is stored in the "cpu" argument. | ||
88 | * | ||
89 | * Example: | ||
90 | * PER_CPU(cpu_gdt_descr, %ebx) | ||
91 | */ | ||
92 | #ifdef CONFIG_SMP | ||
93 | |||
94 | #define __my_cpu_offset x86_read_percpu(this_cpu_off) | ||
95 | |||
96 | /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ | ||
97 | #define __percpu_seg "%%fs:" | ||
98 | |||
99 | #else /* !SMP */ | ||
100 | 40 | ||
101 | #define __percpu_seg "" | 41 | #ifdef CONFIG_SMP |
102 | 42 | #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x | |
103 | #endif /* SMP */ | 43 | #define __my_cpu_offset percpu_read(this_cpu_off) |
104 | 44 | #else | |
105 | #include <asm-generic/percpu.h> | 45 | #define __percpu_arg(x) "%" #x |
106 | 46 | #endif | |
107 | /* We can use this directly for local CPU (faster). */ | ||
108 | DECLARE_PER_CPU(unsigned long, this_cpu_off); | ||
109 | 47 | ||
110 | /* For arch-specific code, we can use direct single-insn ops (they | 48 | /* For arch-specific code, we can use direct single-insn ops (they |
111 | * don't give an lvalue though). */ | 49 | * don't give an lvalue though). */ |
@@ -120,20 +58,25 @@ do { \ | |||
120 | } \ | 58 | } \ |
121 | switch (sizeof(var)) { \ | 59 | switch (sizeof(var)) { \ |
122 | case 1: \ | 60 | case 1: \ |
123 | asm(op "b %1,"__percpu_seg"%0" \ | 61 | asm(op "b %1,"__percpu_arg(0) \ |
124 | : "+m" (var) \ | 62 | : "+m" (var) \ |
125 | : "ri" ((T__)val)); \ | 63 | : "ri" ((T__)val)); \ |
126 | break; \ | 64 | break; \ |
127 | case 2: \ | 65 | case 2: \ |
128 | asm(op "w %1,"__percpu_seg"%0" \ | 66 | asm(op "w %1,"__percpu_arg(0) \ |
129 | : "+m" (var) \ | 67 | : "+m" (var) \ |
130 | : "ri" ((T__)val)); \ | 68 | : "ri" ((T__)val)); \ |
131 | break; \ | 69 | break; \ |
132 | case 4: \ | 70 | case 4: \ |
133 | asm(op "l %1,"__percpu_seg"%0" \ | 71 | asm(op "l %1,"__percpu_arg(0) \ |
134 | : "+m" (var) \ | 72 | : "+m" (var) \ |
135 | : "ri" ((T__)val)); \ | 73 | : "ri" ((T__)val)); \ |
136 | break; \ | 74 | break; \ |
75 | case 8: \ | ||
76 | asm(op "q %1,"__percpu_arg(0) \ | ||
77 | : "+m" (var) \ | ||
78 | : "r" ((T__)val)); \ | ||
79 | break; \ | ||
137 | default: __bad_percpu_size(); \ | 80 | default: __bad_percpu_size(); \ |
138 | } \ | 81 | } \ |
139 | } while (0) | 82 | } while (0) |
@@ -143,17 +86,22 @@ do { \ | |||
143 | typeof(var) ret__; \ | 86 | typeof(var) ret__; \ |
144 | switch (sizeof(var)) { \ | 87 | switch (sizeof(var)) { \ |
145 | case 1: \ | 88 | case 1: \ |
146 | asm(op "b "__percpu_seg"%1,%0" \ | 89 | asm(op "b "__percpu_arg(1)",%0" \ |
147 | : "=r" (ret__) \ | 90 | : "=r" (ret__) \ |
148 | : "m" (var)); \ | 91 | : "m" (var)); \ |
149 | break; \ | 92 | break; \ |
150 | case 2: \ | 93 | case 2: \ |
151 | asm(op "w "__percpu_seg"%1,%0" \ | 94 | asm(op "w "__percpu_arg(1)",%0" \ |
152 | : "=r" (ret__) \ | 95 | : "=r" (ret__) \ |
153 | : "m" (var)); \ | 96 | : "m" (var)); \ |
154 | break; \ | 97 | break; \ |
155 | case 4: \ | 98 | case 4: \ |
156 | asm(op "l "__percpu_seg"%1,%0" \ | 99 | asm(op "l "__percpu_arg(1)",%0" \ |
100 | : "=r" (ret__) \ | ||
101 | : "m" (var)); \ | ||
102 | break; \ | ||
103 | case 8: \ | ||
104 | asm(op "q "__percpu_arg(1)",%0" \ | ||
157 | : "=r" (ret__) \ | 105 | : "=r" (ret__) \ |
158 | : "m" (var)); \ | 106 | : "m" (var)); \ |
159 | break; \ | 107 | break; \ |
@@ -162,13 +110,36 @@ do { \ | |||
162 | ret__; \ | 110 | ret__; \ |
163 | }) | 111 | }) |
164 | 112 | ||
165 | #define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var) | 113 | #define percpu_read(var) percpu_from_op("mov", per_cpu__##var) |
166 | #define x86_write_percpu(var, val) percpu_to_op("mov", per_cpu__##var, val) | 114 | #define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) |
167 | #define x86_add_percpu(var, val) percpu_to_op("add", per_cpu__##var, val) | 115 | #define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) |
168 | #define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val) | 116 | #define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) |
169 | #define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val) | 117 | #define percpu_and(var, val) percpu_to_op("and", per_cpu__##var, val) |
118 | #define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val) | ||
119 | #define percpu_xor(var, val) percpu_to_op("xor", per_cpu__##var, val) | ||
120 | |||
121 | /* This is not atomic against other CPUs -- CPU preemption needs to be off */ | ||
122 | #define x86_test_and_clear_bit_percpu(bit, var) \ | ||
123 | ({ \ | ||
124 | int old__; \ | ||
125 | asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0" \ | ||
126 | : "=r" (old__), "+m" (per_cpu__##var) \ | ||
127 | : "dIr" (bit)); \ | ||
128 | old__; \ | ||
129 | }) | ||
130 | |||
131 | #include <asm-generic/percpu.h> | ||
132 | |||
133 | /* We can use this directly for local CPU (faster). */ | ||
134 | DECLARE_PER_CPU(unsigned long, this_cpu_off); | ||
135 | |||
136 | #ifdef CONFIG_X86_64 | ||
137 | extern void load_pda_offset(int cpu); | ||
138 | #else | ||
139 | static inline void load_pda_offset(int cpu) { } | ||
140 | #endif | ||
141 | |||
170 | #endif /* !__ASSEMBLY__ */ | 142 | #endif /* !__ASSEMBLY__ */ |
171 | #endif /* !CONFIG_X86_64 */ | ||
172 | 143 | ||
173 | #ifdef CONFIG_SMP | 144 | #ifdef CONFIG_SMP |
174 | 145 | ||
@@ -195,9 +166,9 @@ do { \ | |||
195 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) | 166 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) |
196 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) | 167 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) |
197 | #define early_per_cpu(_name, _cpu) \ | 168 | #define early_per_cpu(_name, _cpu) \ |
198 | (early_per_cpu_ptr(_name) ? \ | 169 | *(early_per_cpu_ptr(_name) ? \ |
199 | early_per_cpu_ptr(_name)[_cpu] : \ | 170 | &early_per_cpu_ptr(_name)[_cpu] : \ |
200 | per_cpu(_name, _cpu)) | 171 | &per_cpu(_name, _cpu)) |
201 | 172 | ||
202 | #else /* !CONFIG_SMP */ | 173 | #else /* !CONFIG_SMP */ |
203 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ | 174 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 83e69f4a37f0..06bbcbd66e9c 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -341,6 +341,25 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | |||
341 | 341 | ||
342 | #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) | 342 | #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) |
343 | 343 | ||
344 | static inline int is_new_memtype_allowed(unsigned long flags, | ||
345 | unsigned long new_flags) | ||
346 | { | ||
347 | /* | ||
348 | * Certain new memtypes are not allowed with certain | ||
349 | * requested memtype: | ||
350 | * - request is uncached, return cannot be write-back | ||
351 | * - request is write-combine, return cannot be write-back | ||
352 | */ | ||
353 | if ((flags == _PAGE_CACHE_UC_MINUS && | ||
354 | new_flags == _PAGE_CACHE_WB) || | ||
355 | (flags == _PAGE_CACHE_WC && | ||
356 | new_flags == _PAGE_CACHE_WB)) { | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | return 1; | ||
361 | } | ||
362 | |||
344 | #ifndef __ASSEMBLY__ | 363 | #ifndef __ASSEMBLY__ |
345 | /* Indicate that x86 has its own track and untrack pfn vma functions */ | 364 | /* Indicate that x86 has its own track and untrack pfn vma functions */ |
346 | #define __HAVE_PFNMAP_TRACKING | 365 | #define __HAVE_PFNMAP_TRACKING |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 091cd8855f2e..f511246fa6cd 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -378,6 +378,9 @@ union thread_xstate { | |||
378 | 378 | ||
379 | #ifdef CONFIG_X86_64 | 379 | #ifdef CONFIG_X86_64 |
380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); | 380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); |
381 | |||
382 | DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); | ||
383 | DECLARE_PER_CPU(char *, irq_stack_ptr); | ||
381 | #endif | 384 | #endif |
382 | 385 | ||
383 | extern void print_cpu_info(struct cpuinfo_x86 *); | 386 | extern void print_cpu_info(struct cpuinfo_x86 *); |
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index ebe858cdc8a3..536949749bc2 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h | |||
@@ -100,7 +100,6 @@ extern unsigned long init_pg_tables_start; | |||
100 | extern unsigned long init_pg_tables_end; | 100 | extern unsigned long init_pg_tables_end; |
101 | 101 | ||
102 | #else | 102 | #else |
103 | void __init x86_64_init_pda(void); | ||
104 | void __init x86_64_start_kernel(char *real_mode); | 103 | void __init x86_64_start_kernel(char *real_mode); |
105 | void __init x86_64_start_reservations(char *real_mode_data); | 104 | void __init x86_64_start_reservations(char *real_mode_data); |
106 | 105 | ||
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 19953df61c52..68636e767a91 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
@@ -17,32 +17,7 @@ | |||
17 | #endif | 17 | #endif |
18 | #include <asm/pda.h> | 18 | #include <asm/pda.h> |
19 | #include <asm/thread_info.h> | 19 | #include <asm/thread_info.h> |
20 | 20 | #include <asm/cpumask.h> | |
21 | #ifdef CONFIG_X86_64 | ||
22 | |||
23 | extern cpumask_var_t cpu_callin_mask; | ||
24 | extern cpumask_var_t cpu_callout_mask; | ||
25 | extern cpumask_var_t cpu_initialized_mask; | ||
26 | extern cpumask_var_t cpu_sibling_setup_mask; | ||
27 | |||
28 | #else /* CONFIG_X86_32 */ | ||
29 | |||
30 | extern cpumask_t cpu_callin_map; | ||
31 | extern cpumask_t cpu_callout_map; | ||
32 | extern cpumask_t cpu_initialized; | ||
33 | extern cpumask_t cpu_sibling_setup_map; | ||
34 | |||
35 | #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) | ||
36 | #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) | ||
37 | #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) | ||
38 | #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) | ||
39 | |||
40 | #endif /* CONFIG_X86_32 */ | ||
41 | |||
42 | extern void (*mtrr_hook)(void); | ||
43 | extern void zap_low_mappings(void); | ||
44 | |||
45 | extern int __cpuinit get_local_pda(int cpu); | ||
46 | 21 | ||
47 | extern int smp_num_siblings; | 22 | extern int smp_num_siblings; |
48 | extern unsigned int num_processors; | 23 | extern unsigned int num_processors; |
@@ -50,9 +25,7 @@ extern unsigned int num_processors; | |||
50 | DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); | 25 | DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); |
51 | DECLARE_PER_CPU(cpumask_t, cpu_core_map); | 26 | DECLARE_PER_CPU(cpumask_t, cpu_core_map); |
52 | DECLARE_PER_CPU(u16, cpu_llc_id); | 27 | DECLARE_PER_CPU(u16, cpu_llc_id); |
53 | #ifdef CONFIG_X86_32 | ||
54 | DECLARE_PER_CPU(int, cpu_number); | 28 | DECLARE_PER_CPU(int, cpu_number); |
55 | #endif | ||
56 | 29 | ||
57 | static inline struct cpumask *cpu_sibling_mask(int cpu) | 30 | static inline struct cpumask *cpu_sibling_mask(int cpu) |
58 | { | 31 | { |
@@ -167,8 +140,6 @@ void play_dead_common(void); | |||
167 | void native_send_call_func_ipi(const struct cpumask *mask); | 140 | void native_send_call_func_ipi(const struct cpumask *mask); |
168 | void native_send_call_func_single_ipi(int cpu); | 141 | void native_send_call_func_single_ipi(int cpu); |
169 | 142 | ||
170 | extern void prefill_possible_map(void); | ||
171 | |||
172 | void smp_store_cpu_info(int id); | 143 | void smp_store_cpu_info(int id); |
173 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) | 144 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) |
174 | 145 | ||
@@ -177,10 +148,6 @@ static inline int num_booting_cpus(void) | |||
177 | { | 148 | { |
178 | return cpumask_weight(cpu_callout_mask); | 149 | return cpumask_weight(cpu_callout_mask); |
179 | } | 150 | } |
180 | #else | ||
181 | static inline void prefill_possible_map(void) | ||
182 | { | ||
183 | } | ||
184 | #endif /* CONFIG_SMP */ | 151 | #endif /* CONFIG_SMP */ |
185 | 152 | ||
186 | extern unsigned disabled_cpus __cpuinitdata; | 153 | extern unsigned disabled_cpus __cpuinitdata; |
@@ -191,11 +158,11 @@ extern unsigned disabled_cpus __cpuinitdata; | |||
191 | * from the initial startup. We map APIC_BASE very early in page_setup(), | 158 | * from the initial startup. We map APIC_BASE very early in page_setup(), |
192 | * so this is correct in the x86 case. | 159 | * so this is correct in the x86 case. |
193 | */ | 160 | */ |
194 | #define raw_smp_processor_id() (x86_read_percpu(cpu_number)) | 161 | #define raw_smp_processor_id() (percpu_read(cpu_number)) |
195 | extern int safe_smp_processor_id(void); | 162 | extern int safe_smp_processor_id(void); |
196 | 163 | ||
197 | #elif defined(CONFIG_X86_64_SMP) | 164 | #elif defined(CONFIG_X86_64_SMP) |
198 | #define raw_smp_processor_id() read_pda(cpunumber) | 165 | #define raw_smp_processor_id() (percpu_read(cpu_number)) |
199 | 166 | ||
200 | #define stack_smp_processor_id() \ | 167 | #define stack_smp_processor_id() \ |
201 | ({ \ | 168 | ({ \ |
@@ -205,10 +172,6 @@ extern int safe_smp_processor_id(void); | |||
205 | }) | 172 | }) |
206 | #define safe_smp_processor_id() smp_processor_id() | 173 | #define safe_smp_processor_id() smp_processor_id() |
207 | 174 | ||
208 | #else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */ | ||
209 | #define cpu_physical_id(cpu) boot_cpu_physical_apicid | ||
210 | #define safe_smp_processor_id() 0 | ||
211 | #define stack_smp_processor_id() 0 | ||
212 | #endif | 175 | #endif |
213 | 176 | ||
214 | #ifdef CONFIG_X86_LOCAL_APIC | 177 | #ifdef CONFIG_X86_LOCAL_APIC |
@@ -251,11 +214,5 @@ static inline int hard_smp_processor_id(void) | |||
251 | 214 | ||
252 | #endif /* CONFIG_X86_LOCAL_APIC */ | 215 | #endif /* CONFIG_X86_LOCAL_APIC */ |
253 | 216 | ||
254 | #ifdef CONFIG_X86_HAS_BOOT_CPU_ID | ||
255 | extern unsigned char boot_cpu_id; | ||
256 | #else | ||
257 | #define boot_cpu_id 0 | ||
258 | #endif | ||
259 | |||
260 | #endif /* __ASSEMBLY__ */ | 217 | #endif /* __ASSEMBLY__ */ |
261 | #endif /* _ASM_X86_SMP_H */ | 218 | #endif /* _ASM_X86_SMP_H */ |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 8e626ea33a1a..d1dc27dba36d 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
@@ -94,7 +94,7 @@ do { \ | |||
94 | "call __switch_to\n\t" \ | 94 | "call __switch_to\n\t" \ |
95 | ".globl thread_return\n" \ | 95 | ".globl thread_return\n" \ |
96 | "thread_return:\n\t" \ | 96 | "thread_return:\n\t" \ |
97 | "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ | 97 | "movq "__percpu_arg([current_task])",%%rsi\n\t" \ |
98 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ | 98 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ |
99 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ | 99 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ |
100 | "movq %%rax,%%rdi\n\t" \ | 100 | "movq %%rax,%%rdi\n\t" \ |
@@ -106,7 +106,7 @@ do { \ | |||
106 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ | 106 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ |
107 | [tif_fork] "i" (TIF_FORK), \ | 107 | [tif_fork] "i" (TIF_FORK), \ |
108 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ | 108 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ |
109 | [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ | 109 | [current_task] "m" (per_cpu_var(current_task)) \ |
110 | : "memory", "cc" __EXTRA_CLOBBER) | 110 | : "memory", "cc" __EXTRA_CLOBBER) |
111 | #endif | 111 | #endif |
112 | 112 | ||
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index efdf93820aed..f38488989db7 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -196,25 +196,21 @@ static inline struct thread_info *current_thread_info(void) | |||
196 | 196 | ||
197 | #else /* X86_32 */ | 197 | #else /* X86_32 */ |
198 | 198 | ||
199 | #include <asm/pda.h> | 199 | #include <asm/percpu.h> |
200 | #define KERNEL_STACK_OFFSET (5*8) | ||
200 | 201 | ||
201 | /* | 202 | /* |
202 | * macros/functions for gaining access to the thread information structure | 203 | * macros/functions for gaining access to the thread information structure |
203 | * preempt_count needs to be 1 initially, until the scheduler is functional. | 204 | * preempt_count needs to be 1 initially, until the scheduler is functional. |
204 | */ | 205 | */ |
205 | #ifndef __ASSEMBLY__ | 206 | #ifndef __ASSEMBLY__ |
206 | static inline struct thread_info *current_thread_info(void) | 207 | DECLARE_PER_CPU(unsigned long, kernel_stack); |
207 | { | ||
208 | struct thread_info *ti; | ||
209 | ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); | ||
210 | return ti; | ||
211 | } | ||
212 | 208 | ||
213 | /* do not use in interrupt context */ | 209 | static inline struct thread_info *current_thread_info(void) |
214 | static inline struct thread_info *stack_thread_info(void) | ||
215 | { | 210 | { |
216 | struct thread_info *ti; | 211 | struct thread_info *ti; |
217 | asm("andq %%rsp,%0; " : "=r" (ti) : "0" (~(THREAD_SIZE - 1))); | 212 | ti = (void *)(percpu_read(kernel_stack) + |
213 | KERNEL_STACK_OFFSET - THREAD_SIZE); | ||
218 | return ti; | 214 | return ti; |
219 | } | 215 | } |
220 | 216 | ||
@@ -222,8 +218,8 @@ static inline struct thread_info *stack_thread_info(void) | |||
222 | 218 | ||
223 | /* how to get the thread information struct from ASM */ | 219 | /* how to get the thread information struct from ASM */ |
224 | #define GET_THREAD_INFO(reg) \ | 220 | #define GET_THREAD_INFO(reg) \ |
225 | movq %gs:pda_kernelstack,reg ; \ | 221 | movq PER_CPU_VAR(kernel_stack),reg ; \ |
226 | subq $(THREAD_SIZE-PDA_STACKOFFSET),reg | 222 | subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg |
227 | 223 | ||
228 | #endif | 224 | #endif |
229 | 225 | ||
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 0e7bbb549116..d3539f998f88 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
@@ -113,7 +113,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
113 | __flush_tlb(); | 113 | __flush_tlb(); |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline void native_flush_tlb_others(const cpumask_t *cpumask, | 116 | static inline void native_flush_tlb_others(const struct cpumask *cpumask, |
117 | struct mm_struct *mm, | 117 | struct mm_struct *mm, |
118 | unsigned long va) | 118 | unsigned long va) |
119 | { | 119 | { |
@@ -142,31 +142,28 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, | |||
142 | flush_tlb_mm(vma->vm_mm); | 142 | flush_tlb_mm(vma->vm_mm); |
143 | } | 143 | } |
144 | 144 | ||
145 | void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm, | 145 | void native_flush_tlb_others(const struct cpumask *cpumask, |
146 | unsigned long va); | 146 | struct mm_struct *mm, unsigned long va); |
147 | 147 | ||
148 | #define TLBSTATE_OK 1 | 148 | #define TLBSTATE_OK 1 |
149 | #define TLBSTATE_LAZY 2 | 149 | #define TLBSTATE_LAZY 2 |
150 | 150 | ||
151 | #ifdef CONFIG_X86_32 | ||
152 | struct tlb_state { | 151 | struct tlb_state { |
153 | struct mm_struct *active_mm; | 152 | struct mm_struct *active_mm; |
154 | int state; | 153 | int state; |
155 | char __cacheline_padding[L1_CACHE_BYTES-8]; | ||
156 | }; | 154 | }; |
157 | DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); | 155 | DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate); |
158 | 156 | ||
159 | void reset_lazy_tlbstate(void); | ||
160 | #else | ||
161 | static inline void reset_lazy_tlbstate(void) | 157 | static inline void reset_lazy_tlbstate(void) |
162 | { | 158 | { |
159 | percpu_write(cpu_tlbstate.state, 0); | ||
160 | percpu_write(cpu_tlbstate.active_mm, &init_mm); | ||
163 | } | 161 | } |
164 | #endif | ||
165 | 162 | ||
166 | #endif /* SMP */ | 163 | #endif /* SMP */ |
167 | 164 | ||
168 | #ifndef CONFIG_PARAVIRT | 165 | #ifndef CONFIG_PARAVIRT |
169 | #define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va) | 166 | #define flush_tlb_others(mask, mm, va) native_flush_tlb_others(mask, mm, va) |
170 | #endif | 167 | #endif |
171 | 168 | ||
172 | static inline void flush_tlb_kernel_range(unsigned long start, | 169 | static inline void flush_tlb_kernel_range(unsigned long start, |
@@ -175,4 +172,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, | |||
175 | flush_tlb_all(); | 172 | flush_tlb_all(); |
176 | } | 173 | } |
177 | 174 | ||
175 | extern void zap_low_mappings(void); | ||
176 | |||
178 | #endif /* _ASM_X86_TLBFLUSH_H */ | 177 | #endif /* _ASM_X86_TLBFLUSH_H */ |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 4e2f2e0aab27..ffea1fe03a99 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -83,7 +83,8 @@ extern cpumask_t *node_to_cpumask_map; | |||
83 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); | 83 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); |
84 | 84 | ||
85 | /* Returns the number of the current Node. */ | 85 | /* Returns the number of the current Node. */ |
86 | #define numa_node_id() read_pda(nodenumber) | 86 | DECLARE_PER_CPU(int, node_number); |
87 | #define numa_node_id() percpu_read(node_number) | ||
87 | 88 | ||
88 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 89 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
89 | extern int cpu_to_node(int cpu); | 90 | extern int cpu_to_node(int cpu); |
@@ -102,10 +103,7 @@ static inline int cpu_to_node(int cpu) | |||
102 | /* Same function but used if called before per_cpu areas are setup */ | 103 | /* Same function but used if called before per_cpu areas are setup */ |
103 | static inline int early_cpu_to_node(int cpu) | 104 | static inline int early_cpu_to_node(int cpu) |
104 | { | 105 | { |
105 | if (early_per_cpu_ptr(x86_cpu_to_node_map)) | 106 | return early_per_cpu(x86_cpu_to_node_map, cpu); |
106 | return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu]; | ||
107 | |||
108 | return per_cpu(x86_cpu_to_node_map, cpu); | ||
109 | } | 107 | } |
110 | 108 | ||
111 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ | 109 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ |
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index 780ba0ab94f9..90f06c25221d 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h | |||
@@ -13,6 +13,7 @@ extern unsigned char *trampoline_base; | |||
13 | 13 | ||
14 | extern unsigned long init_rsp; | 14 | extern unsigned long init_rsp; |
15 | extern unsigned long initial_code; | 15 | extern unsigned long initial_code; |
16 | extern unsigned long initial_gs; | ||
16 | 17 | ||
17 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) | 18 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) |
18 | #define TRAMPOLINE_BASE 0x6000 | 19 | #define TRAMPOLINE_BASE 0x6000 |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 50423c7b56b2..74e6393bfddb 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -325,7 +325,8 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | |||
325 | #define cpubit_isset(cpu, bau_local_cpumask) \ | 325 | #define cpubit_isset(cpu, bau_local_cpumask) \ |
326 | test_bit((cpu), (bau_local_cpumask).bits) | 326 | test_bit((cpu), (bau_local_cpumask).bits) |
327 | 327 | ||
328 | extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long); | 328 | extern int uv_flush_tlb_others(struct cpumask *, |
329 | struct mm_struct *, unsigned long); | ||
329 | extern void uv_bau_message_intr1(void); | 330 | extern void uv_bau_message_intr1(void); |
330 | extern void uv_bau_timeout_intr1(void); | 331 | extern void uv_bau_timeout_intr1(void); |
331 | 332 | ||