diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2009-01-30 17:50:57 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2009-01-30 17:50:57 -0500 |
commit | 9b7ed8faa034fc2d350e2eff5c68680eb5c43a07 (patch) | |
tree | 5c94c34ad30e312604c1ce4f08ab6631b64a94f5 /arch/x86/include/asm | |
parent | 6522869c34664dd5f05a0a327e93915b1281c90d (diff) | |
parent | c43e0e46adf79c321ed3fbf0351e1005fb8a2413 (diff) |
Merge branch 'core/percpu' into x86/paravirt
Diffstat (limited to 'arch/x86/include/asm')
42 files changed, 524 insertions, 637 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..a7f3c75f8ad7 --- /dev/null +++ b/arch/x86/include/asm/cpumask.h | |||
@@ -0,0 +1,32 @@ | |||
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 | extern void setup_cpu_local_masks(void); | ||
14 | |||
15 | #else /* CONFIG_X86_32 */ | ||
16 | |||
17 | extern cpumask_t cpu_callin_map; | ||
18 | extern cpumask_t cpu_callout_map; | ||
19 | extern cpumask_t cpu_initialized; | ||
20 | extern cpumask_t cpu_sibling_setup_map; | ||
21 | |||
22 | #define cpu_callin_mask ((struct cpumask *)&cpu_callin_map) | ||
23 | #define cpu_callout_mask ((struct cpumask *)&cpu_callout_map) | ||
24 | #define cpu_initialized_mask ((struct cpumask *)&cpu_initialized) | ||
25 | #define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map) | ||
26 | |||
27 | static inline void setup_cpu_local_masks(void) { } | ||
28 | |||
29 | #endif /* CONFIG_X86_32 */ | ||
30 | |||
31 | #endif /* __ASSEMBLY__ */ | ||
32 | #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/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 4035357f5b9d..132a134d12f2 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h | |||
@@ -2,8 +2,8 @@ | |||
2 | #define _ASM_X86_DMA_MAPPING_H | 2 | #define _ASM_X86_DMA_MAPPING_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for | 5 | * IOMMU interface. See Documentation/PCI/PCI-DMA-mapping.txt and |
6 | * documentation. | 6 | * Documentation/DMA-API.txt for documentation. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/scatterlist.h> | 9 | #include <linux/scatterlist.h> |
diff --git a/arch/x86/include/asm/genapic_32.h b/arch/x86/include/asm/genapic_32.h index 2c05b737ee22..4334502d3664 100644 --- a/arch/x86/include/asm/genapic_32.h +++ b/arch/x86/include/asm/genapic_32.h | |||
@@ -138,11 +138,4 @@ struct genapic { | |||
138 | extern struct genapic *genapic; | 138 | extern struct genapic *genapic; |
139 | extern void es7000_update_genapic_to_cluster(void); | 139 | extern void es7000_update_genapic_to_cluster(void); |
140 | 140 | ||
141 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; | ||
142 | #define get_uv_system_type() UV_NONE | ||
143 | #define is_uv_system() 0 | ||
144 | #define uv_wakeup_secondary(a, b) 1 | ||
145 | #define uv_system_init() do {} while (0) | ||
146 | |||
147 | |||
148 | #endif /* _ASM_X86_GENAPIC_32_H */ | 141 | #endif /* _ASM_X86_GENAPIC_32_H */ |
diff --git a/arch/x86/include/asm/genapic_64.h b/arch/x86/include/asm/genapic_64.h index adf32fb56aa6..7bb092c59055 100644 --- a/arch/x86/include/asm/genapic_64.h +++ b/arch/x86/include/asm/genapic_64.h | |||
@@ -51,15 +51,9 @@ extern struct genapic apic_x2apic_phys; | |||
51 | extern int acpi_madt_oem_check(char *, char *); | 51 | extern int acpi_madt_oem_check(char *, char *); |
52 | 52 | ||
53 | extern void apic_send_IPI_self(int vector); | 53 | extern void apic_send_IPI_self(int vector); |
54 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; | ||
55 | extern enum uv_system_type get_uv_system_type(void); | ||
56 | extern int is_uv_system(void); | ||
57 | 54 | ||
58 | extern struct genapic apic_x2apic_uv_x; | 55 | extern struct genapic apic_x2apic_uv_x; |
59 | DECLARE_PER_CPU(int, x2apic_extra_bits); | 56 | DECLARE_PER_CPU(int, x2apic_extra_bits); |
60 | extern void uv_cpu_init(void); | ||
61 | extern void uv_system_init(void); | ||
62 | extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); | ||
63 | 57 | ||
64 | extern void setup_apic_routing(void); | 58 | extern void setup_apic_routing(void); |
65 | 59 | ||
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index 000787df66e6..176f058e7159 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h | |||
@@ -1,11 +1,52 @@ | |||
1 | #ifdef CONFIG_X86_32 | 1 | #ifndef _ASM_X86_HARDIRQ_H |
2 | # include "hardirq_32.h" | 2 | #define _ASM_X86_HARDIRQ_H |
3 | #else | 3 | |
4 | # include "hardirq_64.h" | 4 | #include <linux/threads.h> |
5 | #include <linux/irq.h> | ||
6 | |||
7 | typedef struct { | ||
8 | unsigned int __softirq_pending; | ||
9 | unsigned int __nmi_count; /* arch dependent */ | ||
10 | unsigned int irq0_irqs; | ||
11 | #ifdef CONFIG_X86_LOCAL_APIC | ||
12 | unsigned int apic_timer_irqs; /* arch dependent */ | ||
13 | unsigned int irq_spurious_count; | ||
14 | #endif | ||
15 | #ifdef CONFIG_SMP | ||
16 | unsigned int irq_resched_count; | ||
17 | unsigned int irq_call_count; | ||
18 | unsigned int irq_tlb_count; | ||
19 | #endif | ||
20 | #ifdef CONFIG_X86_MCE | ||
21 | unsigned int irq_thermal_count; | ||
22 | # ifdef CONFIG_X86_64 | ||
23 | unsigned int irq_threshold_count; | ||
24 | # endif | ||
5 | #endif | 25 | #endif |
26 | } ____cacheline_aligned irq_cpustat_t; | ||
27 | |||
28 | DECLARE_PER_CPU(irq_cpustat_t, irq_stat); | ||
29 | |||
30 | /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ | ||
31 | #define MAX_HARDIRQS_PER_CPU NR_VECTORS | ||
32 | |||
33 | #define __ARCH_IRQ_STAT | ||
34 | |||
35 | #define inc_irq_stat(member) percpu_add(irq_stat.member, 1) | ||
36 | |||
37 | #define local_softirq_pending() percpu_read(irq_stat.__softirq_pending) | ||
38 | |||
39 | #define __ARCH_SET_SOFTIRQ_PENDING | ||
40 | |||
41 | #define set_softirq_pending(x) percpu_write(irq_stat.__softirq_pending, (x)) | ||
42 | #define or_softirq_pending(x) percpu_or(irq_stat.__softirq_pending, (x)) | ||
43 | |||
44 | extern void ack_bad_irq(unsigned int irq); | ||
6 | 45 | ||
7 | extern u64 arch_irq_stat_cpu(unsigned int cpu); | 46 | extern u64 arch_irq_stat_cpu(unsigned int cpu); |
8 | #define arch_irq_stat_cpu arch_irq_stat_cpu | 47 | #define arch_irq_stat_cpu arch_irq_stat_cpu |
9 | 48 | ||
10 | extern u64 arch_irq_stat(void); | 49 | extern u64 arch_irq_stat(void); |
11 | #define arch_irq_stat arch_irq_stat | 50 | #define arch_irq_stat arch_irq_stat |
51 | |||
52 | #endif /* _ASM_X86_HARDIRQ_H */ | ||
diff --git a/arch/x86/include/asm/hardirq_32.h b/arch/x86/include/asm/hardirq_32.h deleted file mode 100644 index cf7954d1405f..000000000000 --- a/arch/x86/include/asm/hardirq_32.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #ifndef _ASM_X86_HARDIRQ_32_H | ||
2 | #define _ASM_X86_HARDIRQ_32_H | ||
3 | |||
4 | #include <linux/threads.h> | ||
5 | #include <linux/irq.h> | ||
6 | |||
7 | typedef struct { | ||
8 | unsigned int __softirq_pending; | ||
9 | unsigned long idle_timestamp; | ||
10 | unsigned int __nmi_count; /* arch dependent */ | ||
11 | unsigned int apic_timer_irqs; /* arch dependent */ | ||
12 | unsigned int irq0_irqs; | ||
13 | unsigned int irq_resched_count; | ||
14 | unsigned int irq_call_count; | ||
15 | unsigned int irq_tlb_count; | ||
16 | unsigned int irq_thermal_count; | ||
17 | unsigned int irq_spurious_count; | ||
18 | } ____cacheline_aligned irq_cpustat_t; | ||
19 | |||
20 | DECLARE_PER_CPU(irq_cpustat_t, irq_stat); | ||
21 | |||
22 | #define __ARCH_IRQ_STAT | ||
23 | #define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member) | ||
24 | |||
25 | #define inc_irq_stat(member) (__get_cpu_var(irq_stat).member++) | ||
26 | |||
27 | void ack_bad_irq(unsigned int irq); | ||
28 | #include <linux/irq_cpustat.h> | ||
29 | |||
30 | #endif /* _ASM_X86_HARDIRQ_32_H */ | ||
diff --git a/arch/x86/include/asm/hardirq_64.h b/arch/x86/include/asm/hardirq_64.h deleted file mode 100644 index b5a6b5d56704..000000000000 --- a/arch/x86/include/asm/hardirq_64.h +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | #ifndef _ASM_X86_HARDIRQ_64_H | ||
2 | #define _ASM_X86_HARDIRQ_64_H | ||
3 | |||
4 | #include <linux/threads.h> | ||
5 | #include <linux/irq.h> | ||
6 | #include <asm/pda.h> | ||
7 | #include <asm/apic.h> | ||
8 | |||
9 | /* We can have at most NR_VECTORS irqs routed to a cpu at a time */ | ||
10 | #define MAX_HARDIRQS_PER_CPU NR_VECTORS | ||
11 | |||
12 | #define __ARCH_IRQ_STAT 1 | ||
13 | |||
14 | #define inc_irq_stat(member) add_pda(member, 1) | ||
15 | |||
16 | #define local_softirq_pending() read_pda(__softirq_pending) | ||
17 | |||
18 | #define __ARCH_SET_SOFTIRQ_PENDING 1 | ||
19 | |||
20 | #define set_softirq_pending(x) write_pda(__softirq_pending, (x)) | ||
21 | #define or_softirq_pending(x) or_pda(__softirq_pending, (x)) | ||
22 | |||
23 | extern void ack_bad_irq(unsigned int irq); | ||
24 | |||
25 | #endif /* _ASM_X86_HARDIRQ_64_H */ | ||
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 05cfed4485fa..1dbbdf4be9b4 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h | |||
@@ -99,7 +99,6 @@ extern void __iomem *ioremap_wc(unsigned long offset, unsigned long size); | |||
99 | * A boot-time mapping is currently limited to at most 16 pages. | 99 | * A boot-time mapping is currently limited to at most 16 pages. |
100 | */ | 100 | */ |
101 | extern void early_ioremap_init(void); | 101 | extern void early_ioremap_init(void); |
102 | extern void early_ioremap_clear(void); | ||
103 | extern void early_ioremap_reset(void); | 102 | extern void early_ioremap_reset(void); |
104 | extern void __iomem *early_ioremap(unsigned long offset, unsigned long size); | 103 | extern void __iomem *early_ioremap(unsigned long offset, unsigned long size); |
105 | extern void __iomem *early_memremap(unsigned long offset, unsigned long size); | 104 | extern void __iomem *early_memremap(unsigned long offset, unsigned long size); |
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.h b/arch/x86/include/asm/irq_regs.h index 89c898ab298b..77843225b7ea 100644 --- a/arch/x86/include/asm/irq_regs.h +++ b/arch/x86/include/asm/irq_regs.h | |||
@@ -1,5 +1,31 @@ | |||
1 | #ifdef CONFIG_X86_32 | 1 | /* |
2 | # include "irq_regs_32.h" | 2 | * Per-cpu current frame pointer - the location of the last exception frame on |
3 | #else | 3 | * the stack, stored in the per-cpu area. |
4 | # include "irq_regs_64.h" | 4 | * |
5 | #endif | 5 | * Jeremy Fitzhardinge <jeremy@goop.org> |
6 | */ | ||
7 | #ifndef _ASM_X86_IRQ_REGS_H | ||
8 | #define _ASM_X86_IRQ_REGS_H | ||
9 | |||
10 | #include <asm/percpu.h> | ||
11 | |||
12 | #define ARCH_HAS_OWN_IRQ_REGS | ||
13 | |||
14 | DECLARE_PER_CPU(struct pt_regs *, irq_regs); | ||
15 | |||
16 | static inline struct pt_regs *get_irq_regs(void) | ||
17 | { | ||
18 | return percpu_read(irq_regs); | ||
19 | } | ||
20 | |||
21 | static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) | ||
22 | { | ||
23 | struct pt_regs *old_regs; | ||
24 | |||
25 | old_regs = get_irq_regs(); | ||
26 | percpu_write(irq_regs, new_regs); | ||
27 | |||
28 | return old_regs; | ||
29 | } | ||
30 | |||
31 | #endif /* _ASM_X86_IRQ_REGS_32_H */ | ||
diff --git a/arch/x86/include/asm/irq_regs_32.h b/arch/x86/include/asm/irq_regs_32.h deleted file mode 100644 index 86afd7473457..000000000000 --- a/arch/x86/include/asm/irq_regs_32.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* | ||
2 | * Per-cpu current frame pointer - the location of the last exception frame on | ||
3 | * the stack, stored in the per-cpu area. | ||
4 | * | ||
5 | * Jeremy Fitzhardinge <jeremy@goop.org> | ||
6 | */ | ||
7 | #ifndef _ASM_X86_IRQ_REGS_32_H | ||
8 | #define _ASM_X86_IRQ_REGS_32_H | ||
9 | |||
10 | #include <asm/percpu.h> | ||
11 | |||
12 | #define ARCH_HAS_OWN_IRQ_REGS | ||
13 | |||
14 | DECLARE_PER_CPU(struct pt_regs *, irq_regs); | ||
15 | |||
16 | static inline struct pt_regs *get_irq_regs(void) | ||
17 | { | ||
18 | return x86_read_percpu(irq_regs); | ||
19 | } | ||
20 | |||
21 | static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs) | ||
22 | { | ||
23 | struct pt_regs *old_regs; | ||
24 | |||
25 | old_regs = get_irq_regs(); | ||
26 | x86_write_percpu(irq_regs, new_regs); | ||
27 | |||
28 | return old_regs; | ||
29 | } | ||
30 | |||
31 | #endif /* _ASM_X86_IRQ_REGS_32_H */ | ||
diff --git a/arch/x86/include/asm/irq_regs_64.h b/arch/x86/include/asm/irq_regs_64.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/x86/include/asm/irq_regs_64.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/irq_regs.h> | ||
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index f7ff65032b9d..9a83a10a5d51 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h | |||
@@ -49,31 +49,33 @@ | |||
49 | * some of the following vectors are 'rare', they are merged | 49 | * some of the following vectors are 'rare', they are merged |
50 | * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. | 50 | * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. |
51 | * TLB, reschedule and local APIC vectors are performance-critical. | 51 | * TLB, reschedule and local APIC vectors are performance-critical. |
52 | * | ||
53 | * Vectors 0xf0-0xfa are free (reserved for future Linux use). | ||
54 | */ | 52 | */ |
55 | #ifdef CONFIG_X86_32 | 53 | #ifdef CONFIG_X86_32 |
56 | 54 | ||
57 | # define SPURIOUS_APIC_VECTOR 0xff | 55 | # define SPURIOUS_APIC_VECTOR 0xff |
58 | # define ERROR_APIC_VECTOR 0xfe | 56 | # define ERROR_APIC_VECTOR 0xfe |
59 | # define INVALIDATE_TLB_VECTOR 0xfd | 57 | # define RESCHEDULE_VECTOR 0xfd |
60 | # define RESCHEDULE_VECTOR 0xfc | 58 | # define CALL_FUNCTION_VECTOR 0xfc |
61 | # define CALL_FUNCTION_VECTOR 0xfb | 59 | # define CALL_FUNCTION_SINGLE_VECTOR 0xfb |
62 | # define CALL_FUNCTION_SINGLE_VECTOR 0xfa | 60 | # define THERMAL_APIC_VECTOR 0xfa |
63 | # define THERMAL_APIC_VECTOR 0xf0 | 61 | /* 0xf8 - 0xf9 : free */ |
62 | # define INVALIDATE_TLB_VECTOR_END 0xf7 | ||
63 | # define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ | ||
64 | |||
65 | # define NUM_INVALIDATE_TLB_VECTORS 8 | ||
64 | 66 | ||
65 | #else | 67 | #else |
66 | 68 | ||
67 | #define SPURIOUS_APIC_VECTOR 0xff | 69 | # define SPURIOUS_APIC_VECTOR 0xff |
68 | #define ERROR_APIC_VECTOR 0xfe | 70 | # define ERROR_APIC_VECTOR 0xfe |
69 | #define RESCHEDULE_VECTOR 0xfd | 71 | # define RESCHEDULE_VECTOR 0xfd |
70 | #define CALL_FUNCTION_VECTOR 0xfc | 72 | # define CALL_FUNCTION_VECTOR 0xfc |
71 | #define CALL_FUNCTION_SINGLE_VECTOR 0xfb | 73 | # define CALL_FUNCTION_SINGLE_VECTOR 0xfb |
72 | #define THERMAL_APIC_VECTOR 0xfa | 74 | # define THERMAL_APIC_VECTOR 0xfa |
73 | #define THRESHOLD_APIC_VECTOR 0xf9 | 75 | # define THRESHOLD_APIC_VECTOR 0xf9 |
74 | #define UV_BAU_MESSAGE 0xf8 | 76 | # define UV_BAU_MESSAGE 0xf8 |
75 | #define INVALIDATE_TLB_VECTOR_END 0xf7 | 77 | # define INVALIDATE_TLB_VECTOR_END 0xf7 |
76 | #define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ | 78 | # define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ |
77 | 79 | ||
78 | #define NUM_INVALIDATE_TLB_VECTORS 8 | 80 | #define NUM_INVALIDATE_TLB_VECTORS 8 |
79 | 81 | ||
@@ -105,6 +107,8 @@ | |||
105 | 107 | ||
106 | #if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER) | 108 | #if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER) |
107 | 109 | ||
110 | #include <asm/apicnum.h> /* need MAX_IO_APICS */ | ||
111 | |||
108 | #ifndef CONFIG_SPARSE_IRQ | 112 | #ifndef CONFIG_SPARSE_IRQ |
109 | # if NR_CPUS < MAX_IO_APICS | 113 | # if NR_CPUS < MAX_IO_APICS |
110 | # define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) | 114 | # define NR_IRQS (NR_VECTORS + (32 * NR_CPUS)) |
@@ -112,11 +116,12 @@ | |||
112 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) | 116 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) |
113 | # endif | 117 | # endif |
114 | #else | 118 | #else |
115 | # if (8 * NR_CPUS) > (32 * MAX_IO_APICS) | 119 | |
116 | # define NR_IRQS (NR_VECTORS + (8 * NR_CPUS)) | 120 | # define NR_IRQS \ |
117 | # else | 121 | ((8 * NR_CPUS) > (32 * MAX_IO_APICS) ? \ |
118 | # define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS)) | 122 | (NR_VECTORS + (8 * NR_CPUS)) : \ |
119 | # endif | 123 | (NR_VECTORS + (32 * MAX_IO_APICS))) \ |
124 | |||
120 | #endif | 125 | #endif |
121 | 126 | ||
122 | #elif defined(CONFIG_X86_VOYAGER) | 127 | #elif defined(CONFIG_X86_VOYAGER) |
diff --git a/arch/x86/include/asm/mach-default/entry_arch.h b/arch/x86/include/asm/mach-default/entry_arch.h index 6b1add8e31dd..6fa399ad1de2 100644 --- a/arch/x86/include/asm/mach-default/entry_arch.h +++ b/arch/x86/include/asm/mach-default/entry_arch.h | |||
@@ -11,10 +11,26 @@ | |||
11 | */ | 11 | */ |
12 | #ifdef CONFIG_X86_SMP | 12 | #ifdef CONFIG_X86_SMP |
13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) | 13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) |
14 | BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) | ||
15 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) | 14 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) |
16 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) | 15 | BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) |
17 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) | 16 | BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) |
17 | |||
18 | BUILD_INTERRUPT3(invalidate_interrupt0,INVALIDATE_TLB_VECTOR_START+0, | ||
19 | smp_invalidate_interrupt) | ||
20 | BUILD_INTERRUPT3(invalidate_interrupt1,INVALIDATE_TLB_VECTOR_START+1, | ||
21 | smp_invalidate_interrupt) | ||
22 | BUILD_INTERRUPT3(invalidate_interrupt2,INVALIDATE_TLB_VECTOR_START+2, | ||
23 | smp_invalidate_interrupt) | ||
24 | BUILD_INTERRUPT3(invalidate_interrupt3,INVALIDATE_TLB_VECTOR_START+3, | ||
25 | smp_invalidate_interrupt) | ||
26 | BUILD_INTERRUPT3(invalidate_interrupt4,INVALIDATE_TLB_VECTOR_START+4, | ||
27 | smp_invalidate_interrupt) | ||
28 | BUILD_INTERRUPT3(invalidate_interrupt5,INVALIDATE_TLB_VECTOR_START+5, | ||
29 | smp_invalidate_interrupt) | ||
30 | BUILD_INTERRUPT3(invalidate_interrupt6,INVALIDATE_TLB_VECTOR_START+6, | ||
31 | smp_invalidate_interrupt) | ||
32 | BUILD_INTERRUPT3(invalidate_interrupt7,INVALIDATE_TLB_VECTOR_START+7, | ||
33 | smp_invalidate_interrupt) | ||
18 | #endif | 34 | #endif |
19 | 35 | ||
20 | /* | 36 | /* |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 8aeeb3fd73db..52948df9cd1d 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
@@ -21,11 +21,54 @@ static inline void paravirt_activate_mm(struct mm_struct *prev, | |||
21 | int init_new_context(struct task_struct *tsk, struct mm_struct *mm); | 21 | int init_new_context(struct task_struct *tsk, struct mm_struct *mm); |
22 | void destroy_context(struct mm_struct *mm); | 22 | void destroy_context(struct mm_struct *mm); |
23 | 23 | ||
24 | #ifdef CONFIG_X86_32 | 24 | |
25 | # include "mmu_context_32.h" | 25 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) |
26 | #else | 26 | { |
27 | # include "mmu_context_64.h" | 27 | #ifdef CONFIG_SMP |
28 | if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) | ||
29 | percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); | ||
30 | #endif | ||
31 | } | ||
32 | |||
33 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
34 | struct task_struct *tsk) | ||
35 | { | ||
36 | unsigned cpu = smp_processor_id(); | ||
37 | |||
38 | if (likely(prev != next)) { | ||
39 | /* stop flush ipis for the previous mm */ | ||
40 | cpu_clear(cpu, prev->cpu_vm_mask); | ||
41 | #ifdef CONFIG_SMP | ||
42 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); | ||
43 | percpu_write(cpu_tlbstate.active_mm, next); | ||
28 | #endif | 44 | #endif |
45 | cpu_set(cpu, next->cpu_vm_mask); | ||
46 | |||
47 | /* Re-load page tables */ | ||
48 | load_cr3(next->pgd); | ||
49 | |||
50 | /* | ||
51 | * load the LDT, if the LDT is different: | ||
52 | */ | ||
53 | if (unlikely(prev->context.ldt != next->context.ldt)) | ||
54 | load_LDT_nolock(&next->context); | ||
55 | } | ||
56 | #ifdef CONFIG_SMP | ||
57 | else { | ||
58 | percpu_write(cpu_tlbstate.state, TLBSTATE_OK); | ||
59 | BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next); | ||
60 | |||
61 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { | ||
62 | /* We were in lazy tlb mode and leave_mm disabled | ||
63 | * tlb flush IPI delivery. We must reload CR3 | ||
64 | * to make sure to use no freed page tables. | ||
65 | */ | ||
66 | load_cr3(next->pgd); | ||
67 | load_LDT_nolock(&next->context); | ||
68 | } | ||
69 | } | ||
70 | #endif | ||
71 | } | ||
29 | 72 | ||
30 | #define activate_mm(prev, next) \ | 73 | #define activate_mm(prev, next) \ |
31 | do { \ | 74 | do { \ |
@@ -33,5 +76,17 @@ do { \ | |||
33 | switch_mm((prev), (next), NULL); \ | 76 | switch_mm((prev), (next), NULL); \ |
34 | } while (0); | 77 | } while (0); |
35 | 78 | ||
79 | #ifdef CONFIG_X86_32 | ||
80 | #define deactivate_mm(tsk, mm) \ | ||
81 | do { \ | ||
82 | loadsegment(gs, 0); \ | ||
83 | } while (0) | ||
84 | #else | ||
85 | #define deactivate_mm(tsk, mm) \ | ||
86 | do { \ | ||
87 | load_gs_index(0); \ | ||
88 | loadsegment(fs, 0); \ | ||
89 | } while (0) | ||
90 | #endif | ||
36 | 91 | ||
37 | #endif /* _ASM_X86_MMU_CONTEXT_H */ | 92 | #endif /* _ASM_X86_MMU_CONTEXT_H */ |
diff --git a/arch/x86/include/asm/mmu_context_32.h b/arch/x86/include/asm/mmu_context_32.h deleted file mode 100644 index 7e98ce1d2c0e..000000000000 --- a/arch/x86/include/asm/mmu_context_32.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | #ifndef _ASM_X86_MMU_CONTEXT_32_H | ||
2 | #define _ASM_X86_MMU_CONTEXT_32_H | ||
3 | |||
4 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | ||
5 | { | ||
6 | #ifdef CONFIG_SMP | ||
7 | if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) | ||
8 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_LAZY); | ||
9 | #endif | ||
10 | } | ||
11 | |||
12 | static inline void switch_mm(struct mm_struct *prev, | ||
13 | struct mm_struct *next, | ||
14 | struct task_struct *tsk) | ||
15 | { | ||
16 | int cpu = smp_processor_id(); | ||
17 | |||
18 | if (likely(prev != next)) { | ||
19 | /* stop flush ipis for the previous mm */ | ||
20 | cpu_clear(cpu, prev->cpu_vm_mask); | ||
21 | #ifdef CONFIG_SMP | ||
22 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); | ||
23 | x86_write_percpu(cpu_tlbstate.active_mm, next); | ||
24 | #endif | ||
25 | cpu_set(cpu, next->cpu_vm_mask); | ||
26 | |||
27 | /* Re-load page tables */ | ||
28 | load_cr3(next->pgd); | ||
29 | |||
30 | /* | ||
31 | * load the LDT, if the LDT is different: | ||
32 | */ | ||
33 | if (unlikely(prev->context.ldt != next->context.ldt)) | ||
34 | load_LDT_nolock(&next->context); | ||
35 | } | ||
36 | #ifdef CONFIG_SMP | ||
37 | else { | ||
38 | x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK); | ||
39 | BUG_ON(x86_read_percpu(cpu_tlbstate.active_mm) != next); | ||
40 | |||
41 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { | ||
42 | /* We were in lazy tlb mode and leave_mm disabled | ||
43 | * tlb flush IPI delivery. We must reload %cr3. | ||
44 | */ | ||
45 | load_cr3(next->pgd); | ||
46 | load_LDT_nolock(&next->context); | ||
47 | } | ||
48 | } | ||
49 | #endif | ||
50 | } | ||
51 | |||
52 | #define deactivate_mm(tsk, mm) \ | ||
53 | asm("movl %0,%%gs": :"r" (0)); | ||
54 | |||
55 | #endif /* _ASM_X86_MMU_CONTEXT_32_H */ | ||
diff --git a/arch/x86/include/asm/mmu_context_64.h b/arch/x86/include/asm/mmu_context_64.h deleted file mode 100644 index 677d36e9540a..000000000000 --- a/arch/x86/include/asm/mmu_context_64.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | #ifndef _ASM_X86_MMU_CONTEXT_64_H | ||
2 | #define _ASM_X86_MMU_CONTEXT_64_H | ||
3 | |||
4 | #include <asm/pda.h> | ||
5 | |||
6 | static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | ||
7 | { | ||
8 | #ifdef CONFIG_SMP | ||
9 | if (read_pda(mmu_state) == TLBSTATE_OK) | ||
10 | write_pda(mmu_state, TLBSTATE_LAZY); | ||
11 | #endif | ||
12 | } | ||
13 | |||
14 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
15 | struct task_struct *tsk) | ||
16 | { | ||
17 | unsigned cpu = smp_processor_id(); | ||
18 | if (likely(prev != next)) { | ||
19 | /* stop flush ipis for the previous mm */ | ||
20 | cpu_clear(cpu, prev->cpu_vm_mask); | ||
21 | #ifdef CONFIG_SMP | ||
22 | write_pda(mmu_state, TLBSTATE_OK); | ||
23 | write_pda(active_mm, next); | ||
24 | #endif | ||
25 | cpu_set(cpu, next->cpu_vm_mask); | ||
26 | load_cr3(next->pgd); | ||
27 | |||
28 | if (unlikely(next->context.ldt != prev->context.ldt)) | ||
29 | load_LDT_nolock(&next->context); | ||
30 | } | ||
31 | #ifdef CONFIG_SMP | ||
32 | else { | ||
33 | write_pda(mmu_state, TLBSTATE_OK); | ||
34 | if (read_pda(active_mm) != next) | ||
35 | BUG(); | ||
36 | if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { | ||
37 | /* We were in lazy tlb mode and leave_mm disabled | ||
38 | * tlb flush IPI delivery. We must reload CR3 | ||
39 | * to make sure to use no freed page tables. | ||
40 | */ | ||
41 | load_cr3(next->pgd); | ||
42 | load_LDT_nolock(&next->context); | ||
43 | } | ||
44 | } | ||
45 | #endif | ||
46 | } | ||
47 | |||
48 | #define deactivate_mm(tsk, mm) \ | ||
49 | do { \ | ||
50 | load_gs_index(0); \ | ||
51 | asm volatile("movl %0,%%fs"::"r"(0)); \ | ||
52 | } while (0) | ||
53 | |||
54 | #endif /* _ASM_X86_MMU_CONTEXT_64_H */ | ||
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/msr-index.h b/arch/x86/include/asm/msr-index.h index cb58643947b9..358acc59ae04 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
@@ -202,6 +202,35 @@ | |||
202 | #define MSR_IA32_THERM_STATUS 0x0000019c | 202 | #define MSR_IA32_THERM_STATUS 0x0000019c |
203 | #define MSR_IA32_MISC_ENABLE 0x000001a0 | 203 | #define MSR_IA32_MISC_ENABLE 0x000001a0 |
204 | 204 | ||
205 | /* MISC_ENABLE bits: architectural */ | ||
206 | #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) | ||
207 | #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) | ||
208 | #define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) | ||
209 | #define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) | ||
210 | #define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) | ||
211 | #define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) | ||
212 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) | ||
213 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) | ||
214 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) | ||
215 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) | ||
216 | |||
217 | /* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ | ||
218 | #define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) | ||
219 | #define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) | ||
220 | #define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) | ||
221 | #define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) | ||
222 | #define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) | ||
223 | #define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) | ||
224 | #define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) | ||
225 | #define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) | ||
226 | #define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) | ||
227 | #define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) | ||
228 | #define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) | ||
229 | #define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) | ||
230 | #define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) | ||
231 | #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) | ||
232 | #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) | ||
233 | |||
205 | /* Intel Model 6 */ | 234 | /* Intel Model 6 */ |
206 | #define MSR_P6_EVNTSEL0 0x00000186 | 235 | #define MSR_P6_EVNTSEL0 0x00000186 |
207 | #define MSR_P6_EVNTSEL1 0x00000187 | 236 | #define MSR_P6_EVNTSEL1 0x00000187 |
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 e25c410f3d8c..175778887090 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 */ |
@@ -983,10 +984,11 @@ static inline void __flush_tlb_single(unsigned long addr) | |||
983 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); | 984 | PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); |
984 | } | 985 | } |
985 | 986 | ||
986 | static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, | 987 | static inline void flush_tlb_others(const struct cpumask *cpumask, |
988 | struct mm_struct *mm, | ||
987 | unsigned long va) | 989 | unsigned long va) |
988 | { | 990 | { |
989 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va); | 991 | PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va); |
990 | } | 992 | } |
991 | 993 | ||
992 | static inline int paravirt_pgd_alloc(struct mm_struct *mm) | 994 | 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 deleted file mode 100644 index 2fbfff88df37..000000000000 --- a/arch/x86/include/asm/pda.h +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | #ifndef _ASM_X86_PDA_H | ||
2 | #define _ASM_X86_PDA_H | ||
3 | |||
4 | #ifndef __ASSEMBLY__ | ||
5 | #include <linux/stddef.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/cache.h> | ||
8 | #include <asm/page.h> | ||
9 | |||
10 | /* Per processor datastructure. %gs points to it while the kernel runs */ | ||
11 | struct x8664_pda { | ||
12 | struct task_struct *pcurrent; /* 0 Current process */ | ||
13 | unsigned long data_offset; /* 8 Per cpu data offset from linker | ||
14 | address */ | ||
15 | unsigned long kernelstack; /* 16 top of kernel stack for current */ | ||
16 | unsigned long oldrsp; /* 24 user rsp for system call */ | ||
17 | int irqcount; /* 32 Irq nesting counter. Starts -1 */ | ||
18 | unsigned int cpunumber; /* 36 Logical CPU number */ | ||
19 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
20 | unsigned long stack_canary; /* 40 stack canary value */ | ||
21 | /* gcc-ABI: this canary MUST be at | ||
22 | offset 40!!! */ | ||
23 | #endif | ||
24 | char *irqstackptr; | ||
25 | short nodenumber; /* number of current node (32k max) */ | ||
26 | 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 irq0_irqs; | ||
34 | unsigned irq_resched_count; | ||
35 | unsigned irq_call_count; | ||
36 | unsigned irq_tlb_count; | ||
37 | unsigned irq_thermal_count; | ||
38 | unsigned irq_threshold_count; | ||
39 | unsigned irq_spurious_count; | ||
40 | } ____cacheline_aligned_in_smp; | ||
41 | |||
42 | extern struct x8664_pda **_cpu_pda; | ||
43 | extern void pda_init(int); | ||
44 | |||
45 | #define cpu_pda(i) (_cpu_pda[i]) | ||
46 | |||
47 | /* | ||
48 | * There is no fast way to get the base address of the PDA, all the accesses | ||
49 | * have to mention %fs/%gs. So it needs to be done this Torvaldian way. | ||
50 | */ | ||
51 | extern void __bad_pda_field(void) __attribute__((noreturn)); | ||
52 | |||
53 | /* | ||
54 | * proxy_pda doesn't actually exist, but tell gcc it is accessed for | ||
55 | * all PDA accesses so it gets read/write dependencies right. | ||
56 | */ | ||
57 | extern struct x8664_pda _proxy_pda; | ||
58 | |||
59 | #define pda_offset(field) offsetof(struct x8664_pda, field) | ||
60 | |||
61 | #define pda_to_op(op, field, val) \ | ||
62 | do { \ | ||
63 | typedef typeof(_proxy_pda.field) T__; \ | ||
64 | if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ | ||
65 | switch (sizeof(_proxy_pda.field)) { \ | ||
66 | case 2: \ | ||
67 | asm(op "w %1,%%gs:%c2" : \ | ||
68 | "+m" (_proxy_pda.field) : \ | ||
69 | "ri" ((T__)val), \ | ||
70 | "i"(pda_offset(field))); \ | ||
71 | break; \ | ||
72 | case 4: \ | ||
73 | asm(op "l %1,%%gs:%c2" : \ | ||
74 | "+m" (_proxy_pda.field) : \ | ||
75 | "ri" ((T__)val), \ | ||
76 | "i" (pda_offset(field))); \ | ||
77 | break; \ | ||
78 | case 8: \ | ||
79 | asm(op "q %1,%%gs:%c2": \ | ||
80 | "+m" (_proxy_pda.field) : \ | ||
81 | "ri" ((T__)val), \ | ||
82 | "i"(pda_offset(field))); \ | ||
83 | break; \ | ||
84 | default: \ | ||
85 | __bad_pda_field(); \ | ||
86 | } \ | ||
87 | } while (0) | ||
88 | |||
89 | #define pda_from_op(op, field) \ | ||
90 | ({ \ | ||
91 | typeof(_proxy_pda.field) ret__; \ | ||
92 | switch (sizeof(_proxy_pda.field)) { \ | ||
93 | case 2: \ | ||
94 | asm(op "w %%gs:%c1,%0" : \ | ||
95 | "=r" (ret__) : \ | ||
96 | "i" (pda_offset(field)), \ | ||
97 | "m" (_proxy_pda.field)); \ | ||
98 | break; \ | ||
99 | case 4: \ | ||
100 | asm(op "l %%gs:%c1,%0": \ | ||
101 | "=r" (ret__): \ | ||
102 | "i" (pda_offset(field)), \ | ||
103 | "m" (_proxy_pda.field)); \ | ||
104 | break; \ | ||
105 | case 8: \ | ||
106 | asm(op "q %%gs:%c1,%0": \ | ||
107 | "=r" (ret__) : \ | ||
108 | "i" (pda_offset(field)), \ | ||
109 | "m" (_proxy_pda.field)); \ | ||
110 | break; \ | ||
111 | default: \ | ||
112 | __bad_pda_field(); \ | ||
113 | } \ | ||
114 | ret__; \ | ||
115 | }) | ||
116 | |||
117 | #define read_pda(field) pda_from_op("mov", field) | ||
118 | #define write_pda(field, val) pda_to_op("mov", field, val) | ||
119 | #define add_pda(field, val) pda_to_op("add", field, val) | ||
120 | #define sub_pda(field, val) pda_to_op("sub", field, val) | ||
121 | #define or_pda(field, val) pda_to_op("or", field, val) | ||
122 | |||
123 | /* This is not atomic against other CPUs -- CPU preemption needs to be off */ | ||
124 | #define test_and_clear_bit_pda(bit, field) \ | ||
125 | ({ \ | ||
126 | int old__; \ | ||
127 | asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ | ||
128 | : "=r" (old__), "+m" (_proxy_pda.field) \ | ||
129 | : "dIr" (bit), "i" (pda_offset(field)) : "memory");\ | ||
130 | old__; \ | ||
131 | }) | ||
132 | |||
133 | #endif | ||
134 | |||
135 | #define PDA_STACKOFFSET (5*8) | ||
136 | |||
137 | #endif /* _ASM_X86_PDA_H */ | ||
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index ece72053ba63..0b64af4f13ac 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 | 40 | ||
96 | /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */ | 41 | #ifdef CONFIG_SMP |
97 | #define __percpu_seg "%%fs:" | 42 | #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x |
98 | 43 | #define __my_cpu_offset percpu_read(this_cpu_off) | |
99 | #else /* !SMP */ | 44 | #else |
100 | 45 | #define __percpu_arg(x) "%" #x | |
101 | #define __percpu_seg "" | 46 | #endif |
102 | |||
103 | #endif /* SMP */ | ||
104 | |||
105 | #include <asm-generic/percpu.h> | ||
106 | |||
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 | : "re" ((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,30 @@ 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 | |||
170 | #endif /* !__ASSEMBLY__ */ | 136 | #endif /* !__ASSEMBLY__ */ |
171 | #endif /* !CONFIG_X86_64 */ | ||
172 | 137 | ||
173 | #ifdef CONFIG_SMP | 138 | #ifdef CONFIG_SMP |
174 | 139 | ||
@@ -195,9 +160,9 @@ do { \ | |||
195 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) | 160 | #define early_per_cpu_ptr(_name) (_name##_early_ptr) |
196 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) | 161 | #define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx]) |
197 | #define early_per_cpu(_name, _cpu) \ | 162 | #define early_per_cpu(_name, _cpu) \ |
198 | (early_per_cpu_ptr(_name) ? \ | 163 | *(early_per_cpu_ptr(_name) ? \ |
199 | early_per_cpu_ptr(_name)[_cpu] : \ | 164 | &early_per_cpu_ptr(_name)[_cpu] : \ |
200 | per_cpu(_name, _cpu)) | 165 | &per_cpu(_name, _cpu)) |
201 | 166 | ||
202 | #else /* !CONFIG_SMP */ | 167 | #else /* !CONFIG_SMP */ |
203 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ | 168 | #define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \ |
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index cb7c151a8bff..dd14c54ac718 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h | |||
@@ -42,6 +42,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | |||
42 | 42 | ||
43 | static inline void pte_free(struct mm_struct *mm, struct page *pte) | 43 | static inline void pte_free(struct mm_struct *mm, struct page *pte) |
44 | { | 44 | { |
45 | pgtable_page_dtor(pte); | ||
45 | __free_page(pte); | 46 | __free_page(pte); |
46 | } | 47 | } |
47 | 48 | ||
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index ba09289accaa..1df9637dfda3 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/processor.h> | 11 | #include <asm/processor.h> |
12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
13 | #include <linux/threads.h> | 13 | #include <linux/threads.h> |
14 | #include <asm/pda.h> | ||
15 | 14 | ||
16 | extern pud_t level3_kernel_pgt[512]; | 15 | extern pud_t level3_kernel_pgt[512]; |
17 | extern pud_t level3_ident_pgt[512]; | 16 | extern pud_t level3_ident_pgt[512]; |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 091cd8855f2e..befa20b4a68c 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -378,6 +378,22 @@ 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 | union irq_stack_union { | ||
383 | char irq_stack[IRQ_STACK_SIZE]; | ||
384 | /* | ||
385 | * GCC hardcodes the stack canary as %gs:40. Since the | ||
386 | * irq_stack is the object at %gs:0, we reserve the bottom | ||
387 | * 48 bytes of the irq stack for the canary. | ||
388 | */ | ||
389 | struct { | ||
390 | char gs_base[40]; | ||
391 | unsigned long stack_canary; | ||
392 | }; | ||
393 | }; | ||
394 | |||
395 | DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); | ||
396 | DECLARE_PER_CPU(char *, irq_stack_ptr); | ||
381 | #endif | 397 | #endif |
382 | 398 | ||
383 | extern void print_cpu_info(struct cpuinfo_x86 *); | 399 | extern void print_cpu_info(struct cpuinfo_x86 *); |
@@ -754,7 +770,6 @@ extern struct desc_ptr early_gdt_descr; | |||
754 | extern void cpu_set_gdt(int); | 770 | extern void cpu_set_gdt(int); |
755 | extern void switch_to_new_gdt(void); | 771 | extern void switch_to_new_gdt(void); |
756 | extern void cpu_init(void); | 772 | extern void cpu_init(void); |
757 | extern void init_gdt(int cpu); | ||
758 | 773 | ||
759 | static inline unsigned long get_debugctlmsr(void) | 774 | static inline unsigned long get_debugctlmsr(void) |
760 | { | 775 | { |
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..45ef8a1b9d7c 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
@@ -15,34 +15,8 @@ | |||
15 | # include <asm/io_apic.h> | 15 | # include <asm/io_apic.h> |
16 | # endif | 16 | # endif |
17 | #endif | 17 | #endif |
18 | #include <asm/pda.h> | ||
19 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
20 | 19 | #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 | 20 | ||
47 | extern int smp_num_siblings; | 21 | extern int smp_num_siblings; |
48 | extern unsigned int num_processors; | 22 | extern unsigned int num_processors; |
@@ -50,9 +24,7 @@ extern unsigned int num_processors; | |||
50 | DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); | 24 | DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); |
51 | DECLARE_PER_CPU(cpumask_t, cpu_core_map); | 25 | DECLARE_PER_CPU(cpumask_t, cpu_core_map); |
52 | DECLARE_PER_CPU(u16, cpu_llc_id); | 26 | DECLARE_PER_CPU(u16, cpu_llc_id); |
53 | #ifdef CONFIG_X86_32 | ||
54 | DECLARE_PER_CPU(int, cpu_number); | 27 | DECLARE_PER_CPU(int, cpu_number); |
55 | #endif | ||
56 | 28 | ||
57 | static inline struct cpumask *cpu_sibling_mask(int cpu) | 29 | static inline struct cpumask *cpu_sibling_mask(int cpu) |
58 | { | 30 | { |
@@ -167,8 +139,6 @@ void play_dead_common(void); | |||
167 | void native_send_call_func_ipi(const struct cpumask *mask); | 139 | void native_send_call_func_ipi(const struct cpumask *mask); |
168 | void native_send_call_func_single_ipi(int cpu); | 140 | void native_send_call_func_single_ipi(int cpu); |
169 | 141 | ||
170 | extern void prefill_possible_map(void); | ||
171 | |||
172 | void smp_store_cpu_info(int id); | 142 | void smp_store_cpu_info(int id); |
173 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) | 143 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) |
174 | 144 | ||
@@ -177,10 +147,6 @@ static inline int num_booting_cpus(void) | |||
177 | { | 147 | { |
178 | return cpumask_weight(cpu_callout_mask); | 148 | return cpumask_weight(cpu_callout_mask); |
179 | } | 149 | } |
180 | #else | ||
181 | static inline void prefill_possible_map(void) | ||
182 | { | ||
183 | } | ||
184 | #endif /* CONFIG_SMP */ | 150 | #endif /* CONFIG_SMP */ |
185 | 151 | ||
186 | extern unsigned disabled_cpus __cpuinitdata; | 152 | extern unsigned disabled_cpus __cpuinitdata; |
@@ -191,11 +157,11 @@ extern unsigned disabled_cpus __cpuinitdata; | |||
191 | * from the initial startup. We map APIC_BASE very early in page_setup(), | 157 | * from the initial startup. We map APIC_BASE very early in page_setup(), |
192 | * so this is correct in the x86 case. | 158 | * so this is correct in the x86 case. |
193 | */ | 159 | */ |
194 | #define raw_smp_processor_id() (x86_read_percpu(cpu_number)) | 160 | #define raw_smp_processor_id() (percpu_read(cpu_number)) |
195 | extern int safe_smp_processor_id(void); | 161 | extern int safe_smp_processor_id(void); |
196 | 162 | ||
197 | #elif defined(CONFIG_X86_64_SMP) | 163 | #elif defined(CONFIG_X86_64_SMP) |
198 | #define raw_smp_processor_id() read_pda(cpunumber) | 164 | #define raw_smp_processor_id() (percpu_read(cpu_number)) |
199 | 165 | ||
200 | #define stack_smp_processor_id() \ | 166 | #define stack_smp_processor_id() \ |
201 | ({ \ | 167 | ({ \ |
@@ -205,10 +171,6 @@ extern int safe_smp_processor_id(void); | |||
205 | }) | 171 | }) |
206 | #define safe_smp_processor_id() smp_processor_id() | 172 | #define safe_smp_processor_id() smp_processor_id() |
207 | 173 | ||
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 | 174 | #endif |
213 | 175 | ||
214 | #ifdef CONFIG_X86_LOCAL_APIC | 176 | #ifdef CONFIG_X86_LOCAL_APIC |
@@ -251,11 +213,5 @@ static inline int hard_smp_processor_id(void) | |||
251 | 213 | ||
252 | #endif /* CONFIG_X86_LOCAL_APIC */ | 214 | #endif /* CONFIG_X86_LOCAL_APIC */ |
253 | 215 | ||
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__ */ | 216 | #endif /* __ASSEMBLY__ */ |
261 | #endif /* _ASM_X86_SMP_H */ | 217 | #endif /* _ASM_X86_SMP_H */ |
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h new file mode 100644 index 000000000000..36a700acaf2b --- /dev/null +++ b/arch/x86/include/asm/stackprotector.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef _ASM_STACKPROTECTOR_H | ||
2 | #define _ASM_STACKPROTECTOR_H 1 | ||
3 | |||
4 | #include <asm/tsc.h> | ||
5 | #include <asm/processor.h> | ||
6 | |||
7 | /* | ||
8 | * Initialize the stackprotector canary value. | ||
9 | * | ||
10 | * NOTE: this must only be called from functions that never return, | ||
11 | * and it must always be inlined. | ||
12 | */ | ||
13 | static __always_inline void boot_init_stack_canary(void) | ||
14 | { | ||
15 | u64 canary; | ||
16 | u64 tsc; | ||
17 | |||
18 | /* | ||
19 | * Build time only check to make sure the stack_canary is at | ||
20 | * offset 40 in the pda; this is a gcc ABI requirement | ||
21 | */ | ||
22 | BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40); | ||
23 | |||
24 | /* | ||
25 | * We both use the random pool and the current TSC as a source | ||
26 | * of randomness. The TSC only matters for very early init, | ||
27 | * there it already has some randomness on most systems. Later | ||
28 | * on during the bootup the random pool has true entropy too. | ||
29 | */ | ||
30 | get_random_bytes(&canary, sizeof(canary)); | ||
31 | tsc = __native_read_tsc(); | ||
32 | canary += tsc + (tsc << 32UL); | ||
33 | |||
34 | current->stack_canary = canary; | ||
35 | percpu_write(irq_stack_union.stack_canary, canary); | ||
36 | } | ||
37 | |||
38 | #endif | ||
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 9c6797c3e56c..c0b0bda754ee 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h | |||
@@ -40,7 +40,7 @@ asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, | |||
40 | struct old_sigaction __user *); | 40 | struct old_sigaction __user *); |
41 | asmlinkage int sys_sigaltstack(unsigned long); | 41 | asmlinkage int sys_sigaltstack(unsigned long); |
42 | asmlinkage unsigned long sys_sigreturn(unsigned long); | 42 | asmlinkage unsigned long sys_sigreturn(unsigned long); |
43 | asmlinkage int sys_rt_sigreturn(struct pt_regs); | 43 | asmlinkage int sys_rt_sigreturn(unsigned long); |
44 | 44 | ||
45 | /* kernel/ioport.c */ | 45 | /* kernel/ioport.c */ |
46 | asmlinkage long sys_iopl(unsigned long); | 46 | asmlinkage long sys_iopl(unsigned long); |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 8e626ea33a1a..2fcc70bc85f3 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
@@ -86,27 +86,44 @@ do { \ | |||
86 | , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ | 86 | , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ |
87 | "r12", "r13", "r14", "r15" | 87 | "r12", "r13", "r14", "r15" |
88 | 88 | ||
89 | #ifdef CONFIG_CC_STACKPROTECTOR | ||
90 | #define __switch_canary \ | ||
91 | "movq %P[task_canary](%%rsi),%%r8\n\t" \ | ||
92 | "movq %%r8,"__percpu_arg([gs_canary])"\n\t" | ||
93 | #define __switch_canary_oparam \ | ||
94 | , [gs_canary] "=m" (per_cpu_var(irq_stack_union.stack_canary)) | ||
95 | #define __switch_canary_iparam \ | ||
96 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) | ||
97 | #else /* CC_STACKPROTECTOR */ | ||
98 | #define __switch_canary | ||
99 | #define __switch_canary_oparam | ||
100 | #define __switch_canary_iparam | ||
101 | #endif /* CC_STACKPROTECTOR */ | ||
102 | |||
89 | /* Save restore flags to clear handle leaking NT */ | 103 | /* Save restore flags to clear handle leaking NT */ |
90 | #define switch_to(prev, next, last) \ | 104 | #define switch_to(prev, next, last) \ |
91 | asm volatile(SAVE_CONTEXT \ | 105 | asm volatile(SAVE_CONTEXT \ |
92 | "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ | 106 | "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ |
93 | "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ | 107 | "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ |
94 | "call __switch_to\n\t" \ | 108 | "call __switch_to\n\t" \ |
95 | ".globl thread_return\n" \ | 109 | ".globl thread_return\n" \ |
96 | "thread_return:\n\t" \ | 110 | "thread_return:\n\t" \ |
97 | "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \ | 111 | "movq "__percpu_arg([current_task])",%%rsi\n\t" \ |
112 | __switch_canary \ | ||
98 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ | 113 | "movq %P[thread_info](%%rsi),%%r8\n\t" \ |
99 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ | 114 | LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ |
100 | "movq %%rax,%%rdi\n\t" \ | 115 | "movq %%rax,%%rdi\n\t" \ |
101 | "jc ret_from_fork\n\t" \ | 116 | "jc ret_from_fork\n\t" \ |
102 | RESTORE_CONTEXT \ | 117 | RESTORE_CONTEXT \ |
103 | : "=a" (last) \ | 118 | : "=a" (last) \ |
119 | __switch_canary_oparam \ | ||
104 | : [next] "S" (next), [prev] "D" (prev), \ | 120 | : [next] "S" (next), [prev] "D" (prev), \ |
105 | [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ | 121 | [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \ |
106 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ | 122 | [ti_flags] "i" (offsetof(struct thread_info, flags)), \ |
107 | [tif_fork] "i" (TIF_FORK), \ | 123 | [tif_fork] "i" (TIF_FORK), \ |
108 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ | 124 | [thread_info] "i" (offsetof(struct task_struct, stack)), \ |
109 | [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \ | 125 | [current_task] "m" (per_cpu_var(current_task)) \ |
126 | __switch_canary_iparam \ | ||
110 | : "memory", "cc" __EXTRA_CLOBBER) | 127 | : "memory", "cc" __EXTRA_CLOBBER) |
111 | #endif | 128 | #endif |
112 | 129 | ||
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 98789647baa9..b46f8ca007b5 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -194,25 +194,21 @@ static inline struct thread_info *current_thread_info(void) | |||
194 | 194 | ||
195 | #else /* X86_32 */ | 195 | #else /* X86_32 */ |
196 | 196 | ||
197 | #include <asm/pda.h> | 197 | #include <asm/percpu.h> |
198 | #define KERNEL_STACK_OFFSET (5*8) | ||
198 | 199 | ||
199 | /* | 200 | /* |
200 | * macros/functions for gaining access to the thread information structure | 201 | * macros/functions for gaining access to the thread information structure |
201 | * preempt_count needs to be 1 initially, until the scheduler is functional. | 202 | * preempt_count needs to be 1 initially, until the scheduler is functional. |
202 | */ | 203 | */ |
203 | #ifndef __ASSEMBLY__ | 204 | #ifndef __ASSEMBLY__ |
204 | static inline struct thread_info *current_thread_info(void) | 205 | DECLARE_PER_CPU(unsigned long, kernel_stack); |
205 | { | ||
206 | struct thread_info *ti; | ||
207 | ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); | ||
208 | return ti; | ||
209 | } | ||
210 | 206 | ||
211 | /* do not use in interrupt context */ | 207 | static inline struct thread_info *current_thread_info(void) |
212 | static inline struct thread_info *stack_thread_info(void) | ||
213 | { | 208 | { |
214 | struct thread_info *ti; | 209 | struct thread_info *ti; |
215 | asm("andq %%rsp,%0; " : "=r" (ti) : "0" (~(THREAD_SIZE - 1))); | 210 | ti = (void *)(percpu_read(kernel_stack) + |
211 | KERNEL_STACK_OFFSET - THREAD_SIZE); | ||
216 | return ti; | 212 | return ti; |
217 | } | 213 | } |
218 | 214 | ||
@@ -220,8 +216,8 @@ static inline struct thread_info *stack_thread_info(void) | |||
220 | 216 | ||
221 | /* how to get the thread information struct from ASM */ | 217 | /* how to get the thread information struct from ASM */ |
222 | #define GET_THREAD_INFO(reg) \ | 218 | #define GET_THREAD_INFO(reg) \ |
223 | movq %gs:pda_kernelstack,reg ; \ | 219 | movq PER_CPU_VAR(kernel_stack),reg ; \ |
224 | subq $(THREAD_SIZE-PDA_STACKOFFSET),reg | 220 | subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg |
225 | 221 | ||
226 | #endif | 222 | #endif |
227 | 223 | ||
diff --git a/arch/x86/include/asm/timex.h b/arch/x86/include/asm/timex.h index 1287dc1347d6..b5c9d45c981f 100644 --- a/arch/x86/include/asm/timex.h +++ b/arch/x86/include/asm/timex.h | |||
@@ -1,18 +1,13 @@ | |||
1 | /* x86 architecture timex specifications */ | ||
2 | #ifndef _ASM_X86_TIMEX_H | 1 | #ifndef _ASM_X86_TIMEX_H |
3 | #define _ASM_X86_TIMEX_H | 2 | #define _ASM_X86_TIMEX_H |
4 | 3 | ||
5 | #include <asm/processor.h> | 4 | #include <asm/processor.h> |
6 | #include <asm/tsc.h> | 5 | #include <asm/tsc.h> |
7 | 6 | ||
8 | #ifdef CONFIG_X86_ELAN | 7 | /* The PIT ticks at this frequency (in HZ): */ |
9 | # define PIT_TICK_RATE 1189200 /* AMD Elan has different frequency! */ | 8 | #define PIT_TICK_RATE 1193182 |
10 | #elif defined(CONFIG_X86_RDC321X) | 9 | |
11 | # define PIT_TICK_RATE 1041667 /* Underlying HZ for R8610 */ | 10 | #define CLOCK_TICK_RATE PIT_TICK_RATE |
12 | #else | ||
13 | # define PIT_TICK_RATE 1193182 /* Underlying HZ */ | ||
14 | #endif | ||
15 | #define CLOCK_TICK_RATE PIT_TICK_RATE | ||
16 | 11 | ||
17 | #define ARCH_HAS_READ_CURRENT_TIMER | 12 | #define ARCH_HAS_READ_CURRENT_TIMER |
18 | 13 | ||
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..77cfb2cfb386 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -74,6 +74,8 @@ static inline const struct cpumask *cpumask_of_node(int node) | |||
74 | return &node_to_cpumask_map[node]; | 74 | return &node_to_cpumask_map[node]; |
75 | } | 75 | } |
76 | 76 | ||
77 | static inline void setup_node_to_cpumask_map(void) { } | ||
78 | |||
77 | #else /* CONFIG_X86_64 */ | 79 | #else /* CONFIG_X86_64 */ |
78 | 80 | ||
79 | /* Mappings between node number and cpus on that node. */ | 81 | /* Mappings between node number and cpus on that node. */ |
@@ -83,7 +85,8 @@ extern cpumask_t *node_to_cpumask_map; | |||
83 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); | 85 | DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); |
84 | 86 | ||
85 | /* Returns the number of the current Node. */ | 87 | /* Returns the number of the current Node. */ |
86 | #define numa_node_id() read_pda(nodenumber) | 88 | DECLARE_PER_CPU(int, node_number); |
89 | #define numa_node_id() percpu_read(node_number) | ||
87 | 90 | ||
88 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 91 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
89 | extern int cpu_to_node(int cpu); | 92 | extern int cpu_to_node(int cpu); |
@@ -102,10 +105,7 @@ static inline int cpu_to_node(int cpu) | |||
102 | /* Same function but used if called before per_cpu areas are setup */ | 105 | /* Same function but used if called before per_cpu areas are setup */ |
103 | static inline int early_cpu_to_node(int cpu) | 106 | static inline int early_cpu_to_node(int cpu) |
104 | { | 107 | { |
105 | if (early_per_cpu_ptr(x86_cpu_to_node_map)) | 108 | 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 | } | 109 | } |
110 | 110 | ||
111 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ | 111 | /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ |
@@ -122,6 +122,8 @@ static inline cpumask_t node_to_cpumask(int node) | |||
122 | 122 | ||
123 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ | 123 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ |
124 | 124 | ||
125 | extern void setup_node_to_cpumask_map(void); | ||
126 | |||
125 | /* | 127 | /* |
126 | * Replace default node_to_cpumask_ptr with optimized version | 128 | * Replace default node_to_cpumask_ptr with optimized version |
127 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" | 129 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" |
@@ -192,9 +194,20 @@ extern int __node_distance(int, int); | |||
192 | 194 | ||
193 | #else /* !CONFIG_NUMA */ | 195 | #else /* !CONFIG_NUMA */ |
194 | 196 | ||
195 | #define numa_node_id() 0 | 197 | static inline int numa_node_id(void) |
196 | #define cpu_to_node(cpu) 0 | 198 | { |
197 | #define early_cpu_to_node(cpu) 0 | 199 | return 0; |
200 | } | ||
201 | |||
202 | static inline int cpu_to_node(int cpu) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static inline int early_cpu_to_node(int cpu) | ||
208 | { | ||
209 | return 0; | ||
210 | } | ||
198 | 211 | ||
199 | static inline const cpumask_t *cpumask_of_node(int node) | 212 | static inline const cpumask_t *cpumask_of_node(int node) |
200 | { | 213 | { |
@@ -209,6 +222,8 @@ static inline int node_to_first_cpu(int node) | |||
209 | return first_cpu(cpu_online_map); | 222 | return first_cpu(cpu_online_map); |
210 | } | 223 | } |
211 | 224 | ||
225 | static inline void setup_node_to_cpumask_map(void) { } | ||
226 | |||
212 | /* | 227 | /* |
213 | * Replace default node_to_cpumask_ptr with optimized version | 228 | * Replace default node_to_cpumask_ptr with optimized version |
214 | * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)" | 229 | * Deprecated: use "const struct cpumask *mask = cpumask_of_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.h b/arch/x86/include/asm/uv/uv.h new file mode 100644 index 000000000000..8ac1d7e312f3 --- /dev/null +++ b/arch/x86/include/asm/uv/uv.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _ASM_X86_UV_UV_H | ||
2 | #define _ASM_X86_UV_UV_H | ||
3 | |||
4 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; | ||
5 | |||
6 | #ifdef CONFIG_X86_UV | ||
7 | |||
8 | extern enum uv_system_type get_uv_system_type(void); | ||
9 | extern int is_uv_system(void); | ||
10 | extern void uv_cpu_init(void); | ||
11 | extern void uv_system_init(void); | ||
12 | extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); | ||
13 | extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | ||
14 | struct mm_struct *mm, | ||
15 | unsigned long va, | ||
16 | unsigned int cpu); | ||
17 | |||
18 | #else /* X86_UV */ | ||
19 | |||
20 | static inline enum uv_system_type get_uv_system_type(void) { return UV_NONE; } | ||
21 | static inline int is_uv_system(void) { return 0; } | ||
22 | static inline void uv_cpu_init(void) { } | ||
23 | static inline void uv_system_init(void) { } | ||
24 | static inline int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) | ||
25 | { return 1; } | ||
26 | static inline const struct cpumask * | ||
27 | uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, | ||
28 | unsigned long va, unsigned int cpu) | ||
29 | { return cpumask; } | ||
30 | |||
31 | #endif /* X86_UV */ | ||
32 | |||
33 | #endif /* _ASM_X86_UV_UV_H */ | ||
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 50423c7b56b2..9b0e61bf7a88 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -325,7 +325,6 @@ 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); | ||
329 | extern void uv_bau_message_intr1(void); | 328 | extern void uv_bau_message_intr1(void); |
330 | extern void uv_bau_timeout_intr1(void); | 329 | extern void uv_bau_timeout_intr1(void); |
331 | 330 | ||