diff options
Diffstat (limited to 'arch/x86/kernel')
40 files changed, 545 insertions, 912 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index de5657c039e9..95f216bbfaf1 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -70,7 +70,7 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | |||
70 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o | 70 | obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o |
71 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o | 71 | obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o |
72 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o | 72 | obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o |
73 | obj-y += vsmp_64.o | 73 | obj-$(CONFIG_X86_VSMP) += vsmp_64.o |
74 | obj-$(CONFIG_KPROBES) += kprobes.o | 74 | obj-$(CONFIG_KPROBES) += kprobes.o |
75 | obj-$(CONFIG_MODULES) += module_$(BITS).o | 75 | obj-$(CONFIG_MODULES) += module_$(BITS).o |
76 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o | 76 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o |
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 82add8b804b7..8ea5164cbd04 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S | |||
@@ -13,7 +13,6 @@ | |||
13 | * Hooray, we are in Long 64-bit mode (but still running in low memory) | 13 | * Hooray, we are in Long 64-bit mode (but still running in low memory) |
14 | */ | 14 | */ |
15 | ENTRY(wakeup_long64) | 15 | ENTRY(wakeup_long64) |
16 | wakeup_long64: | ||
17 | movq saved_magic, %rax | 16 | movq saved_magic, %rax |
18 | movq $0x123456789abcdef0, %rdx | 17 | movq $0x123456789abcdef0, %rdx |
19 | cmpq %rdx, %rax | 18 | cmpq %rdx, %rax |
@@ -34,16 +33,12 @@ wakeup_long64: | |||
34 | 33 | ||
35 | movq saved_rip, %rax | 34 | movq saved_rip, %rax |
36 | jmp *%rax | 35 | jmp *%rax |
36 | ENDPROC(wakeup_long64) | ||
37 | 37 | ||
38 | bogus_64_magic: | 38 | bogus_64_magic: |
39 | jmp bogus_64_magic | 39 | jmp bogus_64_magic |
40 | 40 | ||
41 | .align 2 | 41 | ENTRY(do_suspend_lowlevel) |
42 | .p2align 4,,15 | ||
43 | .globl do_suspend_lowlevel | ||
44 | .type do_suspend_lowlevel,@function | ||
45 | do_suspend_lowlevel: | ||
46 | .LFB5: | ||
47 | subq $8, %rsp | 42 | subq $8, %rsp |
48 | xorl %eax, %eax | 43 | xorl %eax, %eax |
49 | call save_processor_state | 44 | call save_processor_state |
@@ -67,7 +62,7 @@ do_suspend_lowlevel: | |||
67 | pushfq | 62 | pushfq |
68 | popq pt_regs_flags(%rax) | 63 | popq pt_regs_flags(%rax) |
69 | 64 | ||
70 | movq $.L97, saved_rip(%rip) | 65 | movq $resume_point, saved_rip(%rip) |
71 | 66 | ||
72 | movq %rsp, saved_rsp | 67 | movq %rsp, saved_rsp |
73 | movq %rbp, saved_rbp | 68 | movq %rbp, saved_rbp |
@@ -78,14 +73,12 @@ do_suspend_lowlevel: | |||
78 | addq $8, %rsp | 73 | addq $8, %rsp |
79 | movl $3, %edi | 74 | movl $3, %edi |
80 | xorl %eax, %eax | 75 | xorl %eax, %eax |
81 | jmp acpi_enter_sleep_state | 76 | call acpi_enter_sleep_state |
82 | .L97: | 77 | /* in case something went wrong, restore the machine status and go on */ |
83 | .p2align 4,,7 | 78 | jmp resume_point |
84 | .L99: | ||
85 | .align 4 | ||
86 | movl $24, %eax | ||
87 | movw %ax, %ds | ||
88 | 79 | ||
80 | .align 4 | ||
81 | resume_point: | ||
89 | /* We don't restore %rax, it must be 0 anyway */ | 82 | /* We don't restore %rax, it must be 0 anyway */ |
90 | movq $saved_context, %rax | 83 | movq $saved_context, %rax |
91 | movq saved_context_cr4(%rax), %rbx | 84 | movq saved_context_cr4(%rax), %rbx |
@@ -117,12 +110,9 @@ do_suspend_lowlevel: | |||
117 | xorl %eax, %eax | 110 | xorl %eax, %eax |
118 | addq $8, %rsp | 111 | addq $8, %rsp |
119 | jmp restore_processor_state | 112 | jmp restore_processor_state |
120 | .LFE5: | 113 | ENDPROC(do_suspend_lowlevel) |
121 | .Lfe5: | 114 | |
122 | .size do_suspend_lowlevel, .Lfe5-do_suspend_lowlevel | ||
123 | |||
124 | .data | 115 | .data |
125 | ALIGN | ||
126 | ENTRY(saved_rbp) .quad 0 | 116 | ENTRY(saved_rbp) .quad 0 |
127 | ENTRY(saved_rsi) .quad 0 | 117 | ENTRY(saved_rsi) .quad 0 |
128 | ENTRY(saved_rdi) .quad 0 | 118 | ENTRY(saved_rdi) .quad 0 |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 160b3ab11e7a..f9cecdfd05c5 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/smp.h> | 34 | #include <linux/smp.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | 36 | ||
37 | #include <asm/arch_hooks.h> | ||
38 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
39 | #include <asm/atomic.h> | 38 | #include <asm/atomic.h> |
40 | #include <asm/mpspec.h> | 39 | #include <asm/mpspec.h> |
@@ -1265,14 +1264,7 @@ void __cpuinit end_local_APIC_setup(void) | |||
1265 | #ifdef CONFIG_X86_X2APIC | 1264 | #ifdef CONFIG_X86_X2APIC |
1266 | void check_x2apic(void) | 1265 | void check_x2apic(void) |
1267 | { | 1266 | { |
1268 | int msr, msr2; | 1267 | if (x2apic_enabled()) { |
1269 | |||
1270 | if (!cpu_has_x2apic) | ||
1271 | return; | ||
1272 | |||
1273 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | ||
1274 | |||
1275 | if (msr & X2APIC_ENABLE) { | ||
1276 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); | 1268 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); |
1277 | x2apic_preenabled = x2apic = 1; | 1269 | x2apic_preenabled = x2apic = 1; |
1278 | } | 1270 | } |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 3b002995e145..f933822dba18 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -222,7 +222,6 @@ struct apic apic_flat = { | |||
222 | .send_IPI_all = flat_send_IPI_all, | 222 | .send_IPI_all = flat_send_IPI_all, |
223 | .send_IPI_self = apic_send_IPI_self, | 223 | .send_IPI_self = apic_send_IPI_self, |
224 | 224 | ||
225 | .wakeup_cpu = NULL, | ||
226 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 225 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
227 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 226 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
228 | .wait_for_init_deassert = NULL, | 227 | .wait_for_init_deassert = NULL, |
@@ -373,7 +372,6 @@ struct apic apic_physflat = { | |||
373 | .send_IPI_all = physflat_send_IPI_all, | 372 | .send_IPI_all = physflat_send_IPI_all, |
374 | .send_IPI_self = apic_send_IPI_self, | 373 | .send_IPI_self = apic_send_IPI_self, |
375 | 374 | ||
376 | .wakeup_cpu = NULL, | ||
377 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 375 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
378 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 376 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
379 | .wait_for_init_deassert = NULL, | 377 | .wait_for_init_deassert = NULL, |
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 0b1093394fdf..d806ecaa948f 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -16,17 +16,17 @@ | |||
16 | #include <asm/apic.h> | 16 | #include <asm/apic.h> |
17 | #include <asm/ipi.h> | 17 | #include <asm/ipi.h> |
18 | 18 | ||
19 | static inline unsigned bigsmp_get_apic_id(unsigned long x) | 19 | static unsigned bigsmp_get_apic_id(unsigned long x) |
20 | { | 20 | { |
21 | return (x >> 24) & 0xFF; | 21 | return (x >> 24) & 0xFF; |
22 | } | 22 | } |
23 | 23 | ||
24 | static inline int bigsmp_apic_id_registered(void) | 24 | static int bigsmp_apic_id_registered(void) |
25 | { | 25 | { |
26 | return 1; | 26 | return 1; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline const cpumask_t *bigsmp_target_cpus(void) | 29 | static const cpumask_t *bigsmp_target_cpus(void) |
30 | { | 30 | { |
31 | #ifdef CONFIG_SMP | 31 | #ifdef CONFIG_SMP |
32 | return &cpu_online_map; | 32 | return &cpu_online_map; |
@@ -35,13 +35,12 @@ static inline const cpumask_t *bigsmp_target_cpus(void) | |||
35 | #endif | 35 | #endif |
36 | } | 36 | } |
37 | 37 | ||
38 | static inline unsigned long | 38 | static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) |
39 | bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) | ||
40 | { | 39 | { |
41 | return 0; | 40 | return 0; |
42 | } | 41 | } |
43 | 42 | ||
44 | static inline unsigned long bigsmp_check_apicid_present(int bit) | 43 | static unsigned long bigsmp_check_apicid_present(int bit) |
45 | { | 44 | { |
46 | return 1; | 45 | return 1; |
47 | } | 46 | } |
@@ -64,7 +63,7 @@ static inline unsigned long calculate_ldr(int cpu) | |||
64 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel | 63 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel |
65 | * document number 292116). So here it goes... | 64 | * document number 292116). So here it goes... |
66 | */ | 65 | */ |
67 | static inline void bigsmp_init_apic_ldr(void) | 66 | static void bigsmp_init_apic_ldr(void) |
68 | { | 67 | { |
69 | unsigned long val; | 68 | unsigned long val; |
70 | int cpu = smp_processor_id(); | 69 | int cpu = smp_processor_id(); |
@@ -74,19 +73,19 @@ static inline void bigsmp_init_apic_ldr(void) | |||
74 | apic_write(APIC_LDR, val); | 73 | apic_write(APIC_LDR, val); |
75 | } | 74 | } |
76 | 75 | ||
77 | static inline void bigsmp_setup_apic_routing(void) | 76 | static void bigsmp_setup_apic_routing(void) |
78 | { | 77 | { |
79 | printk(KERN_INFO | 78 | printk(KERN_INFO |
80 | "Enabling APIC mode: Physflat. Using %d I/O APICs\n", | 79 | "Enabling APIC mode: Physflat. Using %d I/O APICs\n", |
81 | nr_ioapics); | 80 | nr_ioapics); |
82 | } | 81 | } |
83 | 82 | ||
84 | static inline int bigsmp_apicid_to_node(int logical_apicid) | 83 | static int bigsmp_apicid_to_node(int logical_apicid) |
85 | { | 84 | { |
86 | return apicid_2_node[hard_smp_processor_id()]; | 85 | return apicid_2_node[hard_smp_processor_id()]; |
87 | } | 86 | } |
88 | 87 | ||
89 | static inline int bigsmp_cpu_present_to_apicid(int mps_cpu) | 88 | static int bigsmp_cpu_present_to_apicid(int mps_cpu) |
90 | { | 89 | { |
91 | if (mps_cpu < nr_cpu_ids) | 90 | if (mps_cpu < nr_cpu_ids) |
92 | return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); | 91 | return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu); |
@@ -94,7 +93,7 @@ static inline int bigsmp_cpu_present_to_apicid(int mps_cpu) | |||
94 | return BAD_APICID; | 93 | return BAD_APICID; |
95 | } | 94 | } |
96 | 95 | ||
97 | static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) | 96 | static physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid) |
98 | { | 97 | { |
99 | return physid_mask_of_physid(phys_apicid); | 98 | return physid_mask_of_physid(phys_apicid); |
100 | } | 99 | } |
@@ -107,29 +106,24 @@ static inline int bigsmp_cpu_to_logical_apicid(int cpu) | |||
107 | return cpu_physical_id(cpu); | 106 | return cpu_physical_id(cpu); |
108 | } | 107 | } |
109 | 108 | ||
110 | static inline physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map) | 109 | static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map) |
111 | { | 110 | { |
112 | /* For clustered we don't have a good way to do this yet - hack */ | 111 | /* For clustered we don't have a good way to do this yet - hack */ |
113 | return physids_promote(0xFFL); | 112 | return physids_promote(0xFFL); |
114 | } | 113 | } |
115 | 114 | ||
116 | static inline void bigsmp_setup_portio_remap(void) | 115 | static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid) |
117 | { | ||
118 | } | ||
119 | |||
120 | static inline int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid) | ||
121 | { | 116 | { |
122 | return 1; | 117 | return 1; |
123 | } | 118 | } |
124 | 119 | ||
125 | /* As we are using single CPU as destination, pick only one CPU here */ | 120 | /* As we are using single CPU as destination, pick only one CPU here */ |
126 | static inline unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask) | 121 | static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask) |
127 | { | 122 | { |
128 | return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); | 123 | return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); |
129 | } | 124 | } |
130 | 125 | ||
131 | static inline unsigned int | 126 | static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
132 | bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
133 | const struct cpumask *andmask) | 127 | const struct cpumask *andmask) |
134 | { | 128 | { |
135 | int cpu; | 129 | int cpu; |
@@ -148,7 +142,7 @@ bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
148 | return BAD_APICID; | 142 | return BAD_APICID; |
149 | } | 143 | } |
150 | 144 | ||
151 | static inline int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) | 145 | static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) |
152 | { | 146 | { |
153 | return cpuid_apic >> index_msb; | 147 | return cpuid_apic >> index_msb; |
154 | } | 148 | } |
@@ -158,12 +152,12 @@ static inline void bigsmp_send_IPI_mask(const struct cpumask *mask, int vector) | |||
158 | default_send_IPI_mask_sequence_phys(mask, vector); | 152 | default_send_IPI_mask_sequence_phys(mask, vector); |
159 | } | 153 | } |
160 | 154 | ||
161 | static inline void bigsmp_send_IPI_allbutself(int vector) | 155 | static void bigsmp_send_IPI_allbutself(int vector) |
162 | { | 156 | { |
163 | default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); | 157 | default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); |
164 | } | 158 | } |
165 | 159 | ||
166 | static inline void bigsmp_send_IPI_all(int vector) | 160 | static void bigsmp_send_IPI_all(int vector) |
167 | { | 161 | { |
168 | bigsmp_send_IPI_mask(cpu_online_mask, vector); | 162 | bigsmp_send_IPI_mask(cpu_online_mask, vector); |
169 | } | 163 | } |
@@ -256,7 +250,6 @@ struct apic apic_bigsmp = { | |||
256 | .send_IPI_all = bigsmp_send_IPI_all, | 250 | .send_IPI_all = bigsmp_send_IPI_all, |
257 | .send_IPI_self = default_send_IPI_self, | 251 | .send_IPI_self = default_send_IPI_self, |
258 | 252 | ||
259 | .wakeup_cpu = NULL, | ||
260 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 253 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
261 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 254 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
262 | 255 | ||
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 320f2d2e4e54..19588f2770ee 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -163,22 +163,17 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) | |||
163 | return 0; | 163 | return 0; |
164 | } | 164 | } |
165 | 165 | ||
166 | static int __init es7000_update_apic(void) | 166 | static int es7000_apic_is_cluster(void) |
167 | { | 167 | { |
168 | apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; | ||
169 | |||
170 | /* MPENTIUMIII */ | 168 | /* MPENTIUMIII */ |
171 | if (boot_cpu_data.x86 == 6 && | 169 | if (boot_cpu_data.x86 == 6 && |
172 | (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) { | 170 | (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) |
173 | es7000_update_apic_to_cluster(); | 171 | return 1; |
174 | apic->wait_for_init_deassert = NULL; | ||
175 | apic->wakeup_cpu = wakeup_secondary_cpu_via_mip; | ||
176 | } | ||
177 | 172 | ||
178 | return 0; | 173 | return 0; |
179 | } | 174 | } |
180 | 175 | ||
181 | static void __init setup_unisys(void) | 176 | static void setup_unisys(void) |
182 | { | 177 | { |
183 | /* | 178 | /* |
184 | * Determine the generation of the ES7000 currently running. | 179 | * Determine the generation of the ES7000 currently running. |
@@ -192,14 +187,12 @@ static void __init setup_unisys(void) | |||
192 | else | 187 | else |
193 | es7000_plat = ES7000_CLASSIC; | 188 | es7000_plat = ES7000_CLASSIC; |
194 | ioapic_renumber_irq = es7000_rename_gsi; | 189 | ioapic_renumber_irq = es7000_rename_gsi; |
195 | |||
196 | x86_quirks->update_apic = es7000_update_apic; | ||
197 | } | 190 | } |
198 | 191 | ||
199 | /* | 192 | /* |
200 | * Parse the OEM Table: | 193 | * Parse the OEM Table: |
201 | */ | 194 | */ |
202 | static int __init parse_unisys_oem(char *oemptr) | 195 | static int parse_unisys_oem(char *oemptr) |
203 | { | 196 | { |
204 | int i; | 197 | int i; |
205 | int success = 0; | 198 | int success = 0; |
@@ -261,7 +254,7 @@ static int __init parse_unisys_oem(char *oemptr) | |||
261 | } | 254 | } |
262 | 255 | ||
263 | #ifdef CONFIG_ACPI | 256 | #ifdef CONFIG_ACPI |
264 | static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) | 257 | static int find_unisys_acpi_oem_table(unsigned long *oem_addr) |
265 | { | 258 | { |
266 | struct acpi_table_header *header = NULL; | 259 | struct acpi_table_header *header = NULL; |
267 | struct es7000_oem_table *table; | 260 | struct es7000_oem_table *table; |
@@ -292,7 +285,7 @@ static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) | |||
292 | return 0; | 285 | return 0; |
293 | } | 286 | } |
294 | 287 | ||
295 | static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) | 288 | static void unmap_unisys_acpi_oem_table(unsigned long oem_addr) |
296 | { | 289 | { |
297 | if (!oem_addr) | 290 | if (!oem_addr) |
298 | return; | 291 | return; |
@@ -310,8 +303,10 @@ static int es7000_check_dsdt(void) | |||
310 | return 0; | 303 | return 0; |
311 | } | 304 | } |
312 | 305 | ||
306 | static int es7000_acpi_ret; | ||
307 | |||
313 | /* Hook from generic ACPI tables.c */ | 308 | /* Hook from generic ACPI tables.c */ |
314 | static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 309 | static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
315 | { | 310 | { |
316 | unsigned long oem_addr = 0; | 311 | unsigned long oem_addr = 0; |
317 | int check_dsdt; | 312 | int check_dsdt; |
@@ -332,10 +327,26 @@ static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
332 | */ | 327 | */ |
333 | unmap_unisys_acpi_oem_table(oem_addr); | 328 | unmap_unisys_acpi_oem_table(oem_addr); |
334 | } | 329 | } |
335 | return ret; | 330 | |
331 | es7000_acpi_ret = ret; | ||
332 | |||
333 | return ret && !es7000_apic_is_cluster(); | ||
336 | } | 334 | } |
335 | |||
336 | static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id) | ||
337 | { | ||
338 | int ret = es7000_acpi_ret; | ||
339 | |||
340 | return ret && es7000_apic_is_cluster(); | ||
341 | } | ||
342 | |||
337 | #else /* !CONFIG_ACPI: */ | 343 | #else /* !CONFIG_ACPI: */ |
338 | static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 344 | static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
345 | { | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int es7000_acpi_madt_oem_check_cluster(char *oem_id, char *oem_table_id) | ||
339 | { | 350 | { |
340 | return 0; | 351 | return 0; |
341 | } | 352 | } |
@@ -349,8 +360,7 @@ static void es7000_spin(int n) | |||
349 | rep_nop(); | 360 | rep_nop(); |
350 | } | 361 | } |
351 | 362 | ||
352 | static int __init | 363 | static int es7000_mip_write(struct mip_reg *mip_reg) |
353 | es7000_mip_write(struct mip_reg *mip_reg) | ||
354 | { | 364 | { |
355 | int status = 0; | 365 | int status = 0; |
356 | int spin; | 366 | int spin; |
@@ -383,7 +393,7 @@ es7000_mip_write(struct mip_reg *mip_reg) | |||
383 | return status; | 393 | return status; |
384 | } | 394 | } |
385 | 395 | ||
386 | static void __init es7000_enable_apic_mode(void) | 396 | static void es7000_enable_apic_mode(void) |
387 | { | 397 | { |
388 | struct mip_reg es7000_mip_reg; | 398 | struct mip_reg es7000_mip_reg; |
389 | int mip_status; | 399 | int mip_status; |
@@ -416,11 +426,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
416 | 426 | ||
417 | static void es7000_wait_for_init_deassert(atomic_t *deassert) | 427 | static void es7000_wait_for_init_deassert(atomic_t *deassert) |
418 | { | 428 | { |
419 | #ifndef CONFIG_ES7000_CLUSTERED_APIC | ||
420 | while (!atomic_read(deassert)) | 429 | while (!atomic_read(deassert)) |
421 | cpu_relax(); | 430 | cpu_relax(); |
422 | #endif | ||
423 | return; | ||
424 | } | 431 | } |
425 | 432 | ||
426 | static unsigned int es7000_get_apic_id(unsigned long x) | 433 | static unsigned int es7000_get_apic_id(unsigned long x) |
@@ -565,72 +572,24 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | |||
565 | return 1; | 572 | return 1; |
566 | } | 573 | } |
567 | 574 | ||
568 | static unsigned int | ||
569 | es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask) | ||
570 | { | ||
571 | int cpus_found = 0; | ||
572 | int num_bits_set; | ||
573 | int apicid; | ||
574 | int cpu; | ||
575 | |||
576 | num_bits_set = cpumask_weight(cpumask); | ||
577 | /* Return id to all */ | ||
578 | if (num_bits_set == nr_cpu_ids) | ||
579 | return 0xFF; | ||
580 | /* | ||
581 | * The cpus in the mask must all be on the apic cluster. If are not | ||
582 | * on the same apicid cluster return default value of target_cpus(): | ||
583 | */ | ||
584 | cpu = cpumask_first(cpumask); | ||
585 | apicid = es7000_cpu_to_logical_apicid(cpu); | ||
586 | |||
587 | while (cpus_found < num_bits_set) { | ||
588 | if (cpumask_test_cpu(cpu, cpumask)) { | ||
589 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
590 | |||
591 | if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | ||
592 | WARN(1, "Not a valid mask!"); | ||
593 | |||
594 | return 0xFF; | ||
595 | } | ||
596 | apicid = new_apicid; | ||
597 | cpus_found++; | ||
598 | } | ||
599 | cpu++; | ||
600 | } | ||
601 | return apicid; | ||
602 | } | ||
603 | |||
604 | static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) | 575 | static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask) |
605 | { | 576 | { |
606 | int cpus_found = 0; | 577 | unsigned int round = 0; |
607 | int num_bits_set; | 578 | int cpu, uninitialized_var(apicid); |
608 | int apicid; | ||
609 | int cpu; | ||
610 | 579 | ||
611 | num_bits_set = cpus_weight(*cpumask); | ||
612 | /* Return id to all */ | ||
613 | if (num_bits_set == nr_cpu_ids) | ||
614 | return es7000_cpu_to_logical_apicid(0); | ||
615 | /* | 580 | /* |
616 | * The cpus in the mask must all be on the apic cluster. If are not | 581 | * The cpus in the mask must all be on the apic cluster. |
617 | * on the same apicid cluster return default value of target_cpus(): | ||
618 | */ | 582 | */ |
619 | cpu = first_cpu(*cpumask); | 583 | for_each_cpu(cpu, cpumask) { |
620 | apicid = es7000_cpu_to_logical_apicid(cpu); | 584 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); |
621 | while (cpus_found < num_bits_set) { | ||
622 | if (cpu_isset(cpu, *cpumask)) { | ||
623 | int new_apicid = es7000_cpu_to_logical_apicid(cpu); | ||
624 | 585 | ||
625 | if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 586 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
626 | printk("%s: Not a valid mask!\n", __func__); | 587 | WARN(1, "Not a valid mask!"); |
627 | 588 | ||
628 | return es7000_cpu_to_logical_apicid(0); | 589 | return BAD_APICID; |
629 | } | ||
630 | apicid = new_apicid; | ||
631 | cpus_found++; | ||
632 | } | 590 | } |
633 | cpu++; | 591 | apicid = new_apicid; |
592 | round++; | ||
634 | } | 593 | } |
635 | return apicid; | 594 | return apicid; |
636 | } | 595 | } |
@@ -659,37 +618,103 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | |||
659 | return cpuid_apic >> index_msb; | 618 | return cpuid_apic >> index_msb; |
660 | } | 619 | } |
661 | 620 | ||
662 | void __init es7000_update_apic_to_cluster(void) | ||
663 | { | ||
664 | apic->target_cpus = target_cpus_cluster; | ||
665 | apic->irq_delivery_mode = dest_LowestPrio; | ||
666 | /* logical delivery broadcast to all procs: */ | ||
667 | apic->irq_dest_mode = 1; | ||
668 | |||
669 | apic->init_apic_ldr = es7000_init_apic_ldr_cluster; | ||
670 | |||
671 | apic->cpu_mask_to_apicid = es7000_cpu_mask_to_apicid_cluster; | ||
672 | } | ||
673 | |||
674 | static int probe_es7000(void) | 621 | static int probe_es7000(void) |
675 | { | 622 | { |
676 | /* probed later in mptable/ACPI hooks */ | 623 | /* probed later in mptable/ACPI hooks */ |
677 | return 0; | 624 | return 0; |
678 | } | 625 | } |
679 | 626 | ||
680 | static __init int | 627 | static int es7000_mps_ret; |
681 | es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | 628 | static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem, |
629 | char *productid) | ||
682 | { | 630 | { |
631 | int ret = 0; | ||
632 | |||
683 | if (mpc->oemptr) { | 633 | if (mpc->oemptr) { |
684 | struct mpc_oemtable *oem_table = | 634 | struct mpc_oemtable *oem_table = |
685 | (struct mpc_oemtable *)mpc->oemptr; | 635 | (struct mpc_oemtable *)mpc->oemptr; |
686 | 636 | ||
687 | if (!strncmp(oem, "UNISYS", 6)) | 637 | if (!strncmp(oem, "UNISYS", 6)) |
688 | return parse_unisys_oem((char *)oem_table); | 638 | ret = parse_unisys_oem((char *)oem_table); |
689 | } | 639 | } |
690 | return 0; | 640 | |
641 | es7000_mps_ret = ret; | ||
642 | |||
643 | return ret && !es7000_apic_is_cluster(); | ||
691 | } | 644 | } |
692 | 645 | ||
646 | static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem, | ||
647 | char *productid) | ||
648 | { | ||
649 | int ret = es7000_mps_ret; | ||
650 | |||
651 | return ret && es7000_apic_is_cluster(); | ||
652 | } | ||
653 | |||
654 | struct apic apic_es7000_cluster = { | ||
655 | |||
656 | .name = "es7000", | ||
657 | .probe = probe_es7000, | ||
658 | .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster, | ||
659 | .apic_id_registered = es7000_apic_id_registered, | ||
660 | |||
661 | .irq_delivery_mode = dest_LowestPrio, | ||
662 | /* logical delivery broadcast to all procs: */ | ||
663 | .irq_dest_mode = 1, | ||
664 | |||
665 | .target_cpus = target_cpus_cluster, | ||
666 | .disable_esr = 1, | ||
667 | .dest_logical = 0, | ||
668 | .check_apicid_used = es7000_check_apicid_used, | ||
669 | .check_apicid_present = es7000_check_apicid_present, | ||
670 | |||
671 | .vector_allocation_domain = es7000_vector_allocation_domain, | ||
672 | .init_apic_ldr = es7000_init_apic_ldr_cluster, | ||
673 | |||
674 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, | ||
675 | .setup_apic_routing = es7000_setup_apic_routing, | ||
676 | .multi_timer_check = NULL, | ||
677 | .apicid_to_node = es7000_apicid_to_node, | ||
678 | .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, | ||
679 | .cpu_present_to_apicid = es7000_cpu_present_to_apicid, | ||
680 | .apicid_to_cpu_present = es7000_apicid_to_cpu_present, | ||
681 | .setup_portio_remap = NULL, | ||
682 | .check_phys_apicid_present = es7000_check_phys_apicid_present, | ||
683 | .enable_apic_mode = es7000_enable_apic_mode, | ||
684 | .phys_pkg_id = es7000_phys_pkg_id, | ||
685 | .mps_oem_check = es7000_mps_oem_check_cluster, | ||
686 | |||
687 | .get_apic_id = es7000_get_apic_id, | ||
688 | .set_apic_id = NULL, | ||
689 | .apic_id_mask = 0xFF << 24, | ||
690 | |||
691 | .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, | ||
692 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, | ||
693 | |||
694 | .send_IPI_mask = es7000_send_IPI_mask, | ||
695 | .send_IPI_mask_allbutself = NULL, | ||
696 | .send_IPI_allbutself = es7000_send_IPI_allbutself, | ||
697 | .send_IPI_all = es7000_send_IPI_all, | ||
698 | .send_IPI_self = default_send_IPI_self, | ||
699 | |||
700 | .wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip, | ||
701 | |||
702 | .trampoline_phys_low = 0x467, | ||
703 | .trampoline_phys_high = 0x469, | ||
704 | |||
705 | .wait_for_init_deassert = NULL, | ||
706 | |||
707 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ | ||
708 | .smp_callin_clear_local_apic = NULL, | ||
709 | .inquire_remote_apic = default_inquire_remote_apic, | ||
710 | |||
711 | .read = native_apic_mem_read, | ||
712 | .write = native_apic_mem_write, | ||
713 | .icr_read = native_apic_icr_read, | ||
714 | .icr_write = native_apic_icr_write, | ||
715 | .wait_icr_idle = native_apic_wait_icr_idle, | ||
716 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, | ||
717 | }; | ||
693 | 718 | ||
694 | struct apic apic_es7000 = { | 719 | struct apic apic_es7000 = { |
695 | 720 | ||
@@ -737,8 +762,6 @@ struct apic apic_es7000 = { | |||
737 | .send_IPI_all = es7000_send_IPI_all, | 762 | .send_IPI_all = es7000_send_IPI_all, |
738 | .send_IPI_self = default_send_IPI_self, | 763 | .send_IPI_self = default_send_IPI_self, |
739 | 764 | ||
740 | .wakeup_cpu = NULL, | ||
741 | |||
742 | .trampoline_phys_low = 0x467, | 765 | .trampoline_phys_low = 0x467, |
743 | .trampoline_phys_high = 0x469, | 766 | .trampoline_phys_high = 0x469, |
744 | 767 | ||
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index d9d6d61eed82..ba2fc6465534 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -69,7 +69,7 @@ struct mpc_trans { | |||
69 | /* x86_quirks member */ | 69 | /* x86_quirks member */ |
70 | static int mpc_record; | 70 | static int mpc_record; |
71 | 71 | ||
72 | static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY]; | 72 | static struct mpc_trans *translation_table[MAX_MPC_ENTRY]; |
73 | 73 | ||
74 | int mp_bus_id_to_node[MAX_MP_BUSSES]; | 74 | int mp_bus_id_to_node[MAX_MP_BUSSES]; |
75 | int mp_bus_id_to_local[MAX_MP_BUSSES]; | 75 | int mp_bus_id_to_local[MAX_MP_BUSSES]; |
@@ -256,13 +256,6 @@ static int __init numaq_setup_ioapic_ids(void) | |||
256 | return 1; | 256 | return 1; |
257 | } | 257 | } |
258 | 258 | ||
259 | static int __init numaq_update_apic(void) | ||
260 | { | ||
261 | apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi; | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static struct x86_quirks numaq_x86_quirks __initdata = { | 259 | static struct x86_quirks numaq_x86_quirks __initdata = { |
267 | .arch_pre_time_init = numaq_pre_time_init, | 260 | .arch_pre_time_init = numaq_pre_time_init, |
268 | .arch_time_init = NULL, | 261 | .arch_time_init = NULL, |
@@ -278,7 +271,6 @@ static struct x86_quirks numaq_x86_quirks __initdata = { | |||
278 | .mpc_oem_pci_bus = mpc_oem_pci_bus, | 271 | .mpc_oem_pci_bus = mpc_oem_pci_bus, |
279 | .smp_read_mpc_oem = smp_read_mpc_oem, | 272 | .smp_read_mpc_oem = smp_read_mpc_oem, |
280 | .setup_ioapic_ids = numaq_setup_ioapic_ids, | 273 | .setup_ioapic_ids = numaq_setup_ioapic_ids, |
281 | .update_apic = numaq_update_apic, | ||
282 | }; | 274 | }; |
283 | 275 | ||
284 | static __init void early_check_numaq(void) | 276 | static __init void early_check_numaq(void) |
@@ -546,7 +538,7 @@ struct apic apic_numaq = { | |||
546 | .send_IPI_all = numaq_send_IPI_all, | 538 | .send_IPI_all = numaq_send_IPI_all, |
547 | .send_IPI_self = default_send_IPI_self, | 539 | .send_IPI_self = default_send_IPI_self, |
548 | 540 | ||
549 | .wakeup_cpu = NULL, | 541 | .wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi, |
550 | .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, | 542 | .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, |
551 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, | 543 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, |
552 | 544 | ||
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index c9ec90742e9f..141c99a1c264 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <asm/acpi.h> | 37 | #include <asm/acpi.h> |
38 | #include <asm/arch_hooks.h> | ||
39 | #include <asm/e820.h> | 38 | #include <asm/e820.h> |
40 | #include <asm/setup.h> | 39 | #include <asm/setup.h> |
41 | 40 | ||
@@ -139,7 +138,6 @@ struct apic apic_default = { | |||
139 | .send_IPI_all = default_send_IPI_all, | 138 | .send_IPI_all = default_send_IPI_all, |
140 | .send_IPI_self = default_send_IPI_self, | 139 | .send_IPI_self = default_send_IPI_self, |
141 | 140 | ||
142 | .wakeup_cpu = NULL, | ||
143 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 141 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
144 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 142 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
145 | 143 | ||
@@ -160,6 +158,7 @@ extern struct apic apic_numaq; | |||
160 | extern struct apic apic_summit; | 158 | extern struct apic apic_summit; |
161 | extern struct apic apic_bigsmp; | 159 | extern struct apic apic_bigsmp; |
162 | extern struct apic apic_es7000; | 160 | extern struct apic apic_es7000; |
161 | extern struct apic apic_es7000_cluster; | ||
163 | extern struct apic apic_default; | 162 | extern struct apic apic_default; |
164 | 163 | ||
165 | struct apic *apic = &apic_default; | 164 | struct apic *apic = &apic_default; |
@@ -177,6 +176,7 @@ static struct apic *apic_probe[] __initdata = { | |||
177 | #endif | 176 | #endif |
178 | #ifdef CONFIG_X86_ES7000 | 177 | #ifdef CONFIG_X86_ES7000 |
179 | &apic_es7000, | 178 | &apic_es7000, |
179 | &apic_es7000_cluster, | ||
180 | #endif | 180 | #endif |
181 | &apic_default, /* must be last */ | 181 | &apic_default, /* must be last */ |
182 | NULL, | 182 | NULL, |
@@ -198,9 +198,6 @@ static int __init parse_apic(char *arg) | |||
198 | } | 198 | } |
199 | } | 199 | } |
200 | 200 | ||
201 | if (x86_quirks->update_apic) | ||
202 | x86_quirks->update_apic(); | ||
203 | |||
204 | /* Parsed again by __setup for debug/verbose */ | 201 | /* Parsed again by __setup for debug/verbose */ |
205 | return 0; | 202 | return 0; |
206 | } | 203 | } |
@@ -219,8 +216,6 @@ void __init generic_bigsmp_probe(void) | |||
219 | if (!cmdline_apic && apic == &apic_default) { | 216 | if (!cmdline_apic && apic == &apic_default) { |
220 | if (apic_bigsmp.probe()) { | 217 | if (apic_bigsmp.probe()) { |
221 | apic = &apic_bigsmp; | 218 | apic = &apic_bigsmp; |
222 | if (x86_quirks->update_apic) | ||
223 | x86_quirks->update_apic(); | ||
224 | printk(KERN_INFO "Overriding APIC driver with %s\n", | 219 | printk(KERN_INFO "Overriding APIC driver with %s\n", |
225 | apic->name); | 220 | apic->name); |
226 | } | 221 | } |
@@ -241,9 +236,6 @@ void __init generic_apic_probe(void) | |||
241 | /* Not visible without early console */ | 236 | /* Not visible without early console */ |
242 | if (!apic_probe[i]) | 237 | if (!apic_probe[i]) |
243 | panic("Didn't find an APIC driver"); | 238 | panic("Didn't find an APIC driver"); |
244 | |||
245 | if (x86_quirks->update_apic) | ||
246 | x86_quirks->update_apic(); | ||
247 | } | 239 | } |
248 | printk(KERN_INFO "Using APIC driver %s\n", apic->name); | 240 | printk(KERN_INFO "Using APIC driver %s\n", apic->name); |
249 | } | 241 | } |
@@ -263,8 +255,6 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | |||
263 | 255 | ||
264 | if (!cmdline_apic) { | 256 | if (!cmdline_apic) { |
265 | apic = apic_probe[i]; | 257 | apic = apic_probe[i]; |
266 | if (x86_quirks->update_apic) | ||
267 | x86_quirks->update_apic(); | ||
268 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", | 258 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", |
269 | apic->name); | 259 | apic->name); |
270 | } | 260 | } |
@@ -285,8 +275,6 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
285 | 275 | ||
286 | if (!cmdline_apic) { | 276 | if (!cmdline_apic) { |
287 | apic = apic_probe[i]; | 277 | apic = apic_probe[i]; |
288 | if (x86_quirks->update_apic) | ||
289 | x86_quirks->update_apic(); | ||
290 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", | 278 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", |
291 | apic->name); | 279 | apic->name); |
292 | } | 280 | } |
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 70935dd904db..8d7748efe6a8 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -50,9 +50,16 @@ static struct apic *apic_probe[] __initdata = { | |||
50 | void __init default_setup_apic_routing(void) | 50 | void __init default_setup_apic_routing(void) |
51 | { | 51 | { |
52 | #ifdef CONFIG_X86_X2APIC | 52 | #ifdef CONFIG_X86_X2APIC |
53 | if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { | 53 | if (x2apic && (apic != &apic_x2apic_phys && |
54 | if (!intr_remapping_enabled) | 54 | #ifdef CONFIG_X86_UV |
55 | apic = &apic_flat; | 55 | apic != &apic_x2apic_uv_x && |
56 | #endif | ||
57 | apic != &apic_x2apic_cluster)) { | ||
58 | if (x2apic_phys) | ||
59 | apic = &apic_x2apic_phys; | ||
60 | else | ||
61 | apic = &apic_x2apic_cluster; | ||
62 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); | ||
56 | } | 63 | } |
57 | #endif | 64 | #endif |
58 | 65 | ||
@@ -61,9 +68,6 @@ void __init default_setup_apic_routing(void) | |||
61 | apic = &apic_physflat; | 68 | apic = &apic_physflat; |
62 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); | 69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); |
63 | } | 70 | } |
64 | |||
65 | if (x86_quirks->update_apic) | ||
66 | x86_quirks->update_apic(); | ||
67 | } | 71 | } |
68 | 72 | ||
69 | /* Same for both flat and physical. */ | 73 | /* Same for both flat and physical. */ |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index cfe7b09015d8..aac52fa873ff 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <linux/gfp.h> | 48 | #include <linux/gfp.h> |
49 | #include <linux/smp.h> | 49 | #include <linux/smp.h> |
50 | 50 | ||
51 | static inline unsigned summit_get_apic_id(unsigned long x) | 51 | static unsigned summit_get_apic_id(unsigned long x) |
52 | { | 52 | { |
53 | return (x >> 24) & 0xFF; | 53 | return (x >> 24) & 0xFF; |
54 | } | 54 | } |
@@ -58,7 +58,7 @@ static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) | |||
58 | default_send_IPI_mask_sequence_logical(mask, vector); | 58 | default_send_IPI_mask_sequence_logical(mask, vector); |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline void summit_send_IPI_allbutself(int vector) | 61 | static void summit_send_IPI_allbutself(int vector) |
62 | { | 62 | { |
63 | cpumask_t mask = cpu_online_map; | 63 | cpumask_t mask = cpu_online_map; |
64 | cpu_clear(smp_processor_id(), mask); | 64 | cpu_clear(smp_processor_id(), mask); |
@@ -67,7 +67,7 @@ static inline void summit_send_IPI_allbutself(int vector) | |||
67 | summit_send_IPI_mask(&mask, vector); | 67 | summit_send_IPI_mask(&mask, vector); |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline void summit_send_IPI_all(int vector) | 70 | static void summit_send_IPI_all(int vector) |
71 | { | 71 | { |
72 | summit_send_IPI_mask(&cpu_online_map, vector); | 72 | summit_send_IPI_mask(&cpu_online_map, vector); |
73 | } | 73 | } |
@@ -77,13 +77,13 @@ static inline void summit_send_IPI_all(int vector) | |||
77 | extern int use_cyclone; | 77 | extern int use_cyclone; |
78 | 78 | ||
79 | #ifdef CONFIG_X86_SUMMIT_NUMA | 79 | #ifdef CONFIG_X86_SUMMIT_NUMA |
80 | extern void setup_summit(void); | 80 | static void setup_summit(void); |
81 | #else | 81 | #else |
82 | #define setup_summit() {} | 82 | static inline void setup_summit(void) {} |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | static inline int | 85 | static int summit_mps_oem_check(struct mpc_table *mpc, char *oem, |
86 | summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | 86 | char *productid) |
87 | { | 87 | { |
88 | if (!strncmp(oem, "IBM ENSW", 8) && | 88 | if (!strncmp(oem, "IBM ENSW", 8) && |
89 | (!strncmp(productid, "VIGIL SMP", 9) | 89 | (!strncmp(productid, "VIGIL SMP", 9) |
@@ -98,7 +98,7 @@ summit_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | |||
98 | } | 98 | } |
99 | 99 | ||
100 | /* Hook from generic ACPI tables.c */ | 100 | /* Hook from generic ACPI tables.c */ |
101 | static inline int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 101 | static int summit_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
102 | { | 102 | { |
103 | if (!strncmp(oem_id, "IBM", 3) && | 103 | if (!strncmp(oem_id, "IBM", 3) && |
104 | (!strncmp(oem_table_id, "SERVIGIL", 8) | 104 | (!strncmp(oem_table_id, "SERVIGIL", 8) |
@@ -186,7 +186,7 @@ static inline int is_WPEG(struct rio_detail *rio){ | |||
186 | 186 | ||
187 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) | 187 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) |
188 | 188 | ||
189 | static inline const cpumask_t *summit_target_cpus(void) | 189 | static const cpumask_t *summit_target_cpus(void) |
190 | { | 190 | { |
191 | /* CPU_MASK_ALL (0xff) has undefined behaviour with | 191 | /* CPU_MASK_ALL (0xff) has undefined behaviour with |
192 | * dest_LowestPrio mode logical clustered apic interrupt routing | 192 | * dest_LowestPrio mode logical clustered apic interrupt routing |
@@ -195,19 +195,18 @@ static inline const cpumask_t *summit_target_cpus(void) | |||
195 | return &cpumask_of_cpu(0); | 195 | return &cpumask_of_cpu(0); |
196 | } | 196 | } |
197 | 197 | ||
198 | static inline unsigned long | 198 | static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) |
199 | summit_check_apicid_used(physid_mask_t bitmap, int apicid) | ||
200 | { | 199 | { |
201 | return 0; | 200 | return 0; |
202 | } | 201 | } |
203 | 202 | ||
204 | /* we don't use the phys_cpu_present_map to indicate apicid presence */ | 203 | /* we don't use the phys_cpu_present_map to indicate apicid presence */ |
205 | static inline unsigned long summit_check_apicid_present(int bit) | 204 | static unsigned long summit_check_apicid_present(int bit) |
206 | { | 205 | { |
207 | return 1; | 206 | return 1; |
208 | } | 207 | } |
209 | 208 | ||
210 | static inline void summit_init_apic_ldr(void) | 209 | static void summit_init_apic_ldr(void) |
211 | { | 210 | { |
212 | unsigned long val, id; | 211 | unsigned long val, id; |
213 | int count = 0; | 212 | int count = 0; |
@@ -234,18 +233,18 @@ static inline void summit_init_apic_ldr(void) | |||
234 | apic_write(APIC_LDR, val); | 233 | apic_write(APIC_LDR, val); |
235 | } | 234 | } |
236 | 235 | ||
237 | static inline int summit_apic_id_registered(void) | 236 | static int summit_apic_id_registered(void) |
238 | { | 237 | { |
239 | return 1; | 238 | return 1; |
240 | } | 239 | } |
241 | 240 | ||
242 | static inline void summit_setup_apic_routing(void) | 241 | static void summit_setup_apic_routing(void) |
243 | { | 242 | { |
244 | printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", | 243 | printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", |
245 | nr_ioapics); | 244 | nr_ioapics); |
246 | } | 245 | } |
247 | 246 | ||
248 | static inline int summit_apicid_to_node(int logical_apicid) | 247 | static int summit_apicid_to_node(int logical_apicid) |
249 | { | 248 | { |
250 | #ifdef CONFIG_SMP | 249 | #ifdef CONFIG_SMP |
251 | return apicid_2_node[hard_smp_processor_id()]; | 250 | return apicid_2_node[hard_smp_processor_id()]; |
@@ -266,7 +265,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu) | |||
266 | #endif | 265 | #endif |
267 | } | 266 | } |
268 | 267 | ||
269 | static inline int summit_cpu_present_to_apicid(int mps_cpu) | 268 | static int summit_cpu_present_to_apicid(int mps_cpu) |
270 | { | 269 | { |
271 | if (mps_cpu < nr_cpu_ids) | 270 | if (mps_cpu < nr_cpu_ids) |
272 | return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); | 271 | return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu); |
@@ -274,64 +273,44 @@ static inline int summit_cpu_present_to_apicid(int mps_cpu) | |||
274 | return BAD_APICID; | 273 | return BAD_APICID; |
275 | } | 274 | } |
276 | 275 | ||
277 | static inline physid_mask_t | 276 | static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map) |
278 | summit_ioapic_phys_id_map(physid_mask_t phys_id_map) | ||
279 | { | 277 | { |
280 | /* For clustered we don't have a good way to do this yet - hack */ | 278 | /* For clustered we don't have a good way to do this yet - hack */ |
281 | return physids_promote(0x0F); | 279 | return physids_promote(0x0F); |
282 | } | 280 | } |
283 | 281 | ||
284 | static inline physid_mask_t summit_apicid_to_cpu_present(int apicid) | 282 | static physid_mask_t summit_apicid_to_cpu_present(int apicid) |
285 | { | 283 | { |
286 | return physid_mask_of_physid(0); | 284 | return physid_mask_of_physid(0); |
287 | } | 285 | } |
288 | 286 | ||
289 | static inline void summit_setup_portio_remap(void) | 287 | static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) |
290 | { | ||
291 | } | ||
292 | |||
293 | static inline int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) | ||
294 | { | 288 | { |
295 | return 1; | 289 | return 1; |
296 | } | 290 | } |
297 | 291 | ||
298 | static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) | 292 | static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) |
299 | { | 293 | { |
300 | int cpus_found = 0; | 294 | unsigned int round = 0; |
301 | int num_bits_set; | 295 | int cpu, apicid = 0; |
302 | int apicid; | 296 | |
303 | int cpu; | ||
304 | |||
305 | num_bits_set = cpus_weight(*cpumask); | ||
306 | /* Return id to all */ | ||
307 | if (num_bits_set >= nr_cpu_ids) | ||
308 | return 0xFF; | ||
309 | /* | 297 | /* |
310 | * The cpus in the mask must all be on the apic cluster. If are not | 298 | * The cpus in the mask must all be on the apic cluster. |
311 | * on the same apicid cluster return default value of target_cpus(): | ||
312 | */ | 299 | */ |
313 | cpu = first_cpu(*cpumask); | 300 | for_each_cpu(cpu, cpumask) { |
314 | apicid = summit_cpu_to_logical_apicid(cpu); | 301 | int new_apicid = summit_cpu_to_logical_apicid(cpu); |
315 | 302 | ||
316 | while (cpus_found < num_bits_set) { | 303 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
317 | if (cpu_isset(cpu, *cpumask)) { | 304 | printk("%s: Not a valid mask!\n", __func__); |
318 | int new_apicid = summit_cpu_to_logical_apicid(cpu); | 305 | return BAD_APICID; |
319 | |||
320 | if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | ||
321 | printk ("%s: Not a valid mask!\n", __func__); | ||
322 | |||
323 | return 0xFF; | ||
324 | } | ||
325 | apicid = apicid | new_apicid; | ||
326 | cpus_found++; | ||
327 | } | 306 | } |
328 | cpu++; | 307 | apicid |= new_apicid; |
308 | round++; | ||
329 | } | 309 | } |
330 | return apicid; | 310 | return apicid; |
331 | } | 311 | } |
332 | 312 | ||
333 | static inline unsigned int | 313 | static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, |
334 | summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, | ||
335 | const struct cpumask *andmask) | 314 | const struct cpumask *andmask) |
336 | { | 315 | { |
337 | int apicid = summit_cpu_to_logical_apicid(0); | 316 | int apicid = summit_cpu_to_logical_apicid(0); |
@@ -356,7 +335,7 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, | |||
356 | * | 335 | * |
357 | * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. | 336 | * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. |
358 | */ | 337 | */ |
359 | static inline int summit_phys_pkg_id(int cpuid_apic, int index_msb) | 338 | static int summit_phys_pkg_id(int cpuid_apic, int index_msb) |
360 | { | 339 | { |
361 | return hard_smp_processor_id() >> index_msb; | 340 | return hard_smp_processor_id() >> index_msb; |
362 | } | 341 | } |
@@ -381,15 +360,15 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
381 | } | 360 | } |
382 | 361 | ||
383 | #ifdef CONFIG_X86_SUMMIT_NUMA | 362 | #ifdef CONFIG_X86_SUMMIT_NUMA |
384 | static struct rio_table_hdr *rio_table_hdr __initdata; | 363 | static struct rio_table_hdr *rio_table_hdr; |
385 | static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; | 364 | static struct scal_detail *scal_devs[MAX_NUMNODES]; |
386 | static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; | 365 | static struct rio_detail *rio_devs[MAX_NUMNODES*4]; |
387 | 366 | ||
388 | #ifndef CONFIG_X86_NUMAQ | 367 | #ifndef CONFIG_X86_NUMAQ |
389 | static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata; | 368 | static int mp_bus_id_to_node[MAX_MP_BUSSES]; |
390 | #endif | 369 | #endif |
391 | 370 | ||
392 | static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | 371 | static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) |
393 | { | 372 | { |
394 | int twister = 0, node = 0; | 373 | int twister = 0, node = 0; |
395 | int i, bus, num_buses; | 374 | int i, bus, num_buses; |
@@ -451,7 +430,7 @@ static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | |||
451 | return bus; | 430 | return bus; |
452 | } | 431 | } |
453 | 432 | ||
454 | static int __init build_detail_arrays(void) | 433 | static int build_detail_arrays(void) |
455 | { | 434 | { |
456 | unsigned long ptr; | 435 | unsigned long ptr; |
457 | int i, scal_detail_size, rio_detail_size; | 436 | int i, scal_detail_size, rio_detail_size; |
@@ -485,7 +464,7 @@ static int __init build_detail_arrays(void) | |||
485 | return 1; | 464 | return 1; |
486 | } | 465 | } |
487 | 466 | ||
488 | void __init setup_summit(void) | 467 | void setup_summit(void) |
489 | { | 468 | { |
490 | unsigned long ptr; | 469 | unsigned long ptr; |
491 | unsigned short offset; | 470 | unsigned short offset; |
@@ -583,7 +562,6 @@ struct apic apic_summit = { | |||
583 | .send_IPI_all = summit_send_IPI_all, | 562 | .send_IPI_all = summit_send_IPI_all, |
584 | .send_IPI_self = default_send_IPI_self, | 563 | .send_IPI_self = default_send_IPI_self, |
585 | 564 | ||
586 | .wakeup_cpu = NULL, | ||
587 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 565 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
588 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 566 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
589 | 567 | ||
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 4e39d9ad4d52..8fb87b6dd633 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -14,10 +14,7 @@ DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid); | |||
14 | 14 | ||
15 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 15 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
16 | { | 16 | { |
17 | if (cpu_has_x2apic) | 17 | return x2apic_enabled(); |
18 | return 1; | ||
19 | |||
20 | return 0; | ||
21 | } | 18 | } |
22 | 19 | ||
23 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ | 20 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ |
@@ -227,7 +224,6 @@ struct apic apic_x2apic_cluster = { | |||
227 | .send_IPI_all = x2apic_send_IPI_all, | 224 | .send_IPI_all = x2apic_send_IPI_all, |
228 | .send_IPI_self = x2apic_send_IPI_self, | 225 | .send_IPI_self = x2apic_send_IPI_self, |
229 | 226 | ||
230 | .wakeup_cpu = NULL, | ||
231 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 227 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
232 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 228 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
233 | .wait_for_init_deassert = NULL, | 229 | .wait_for_init_deassert = NULL, |
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index d2d52eb9f7ea..23625b9f98b2 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <asm/apic.h> | 10 | #include <asm/apic.h> |
11 | #include <asm/ipi.h> | 11 | #include <asm/ipi.h> |
12 | 12 | ||
13 | static int x2apic_phys; | 13 | int x2apic_phys; |
14 | 14 | ||
15 | static int set_x2apic_phys_mode(char *arg) | 15 | static int set_x2apic_phys_mode(char *arg) |
16 | { | 16 | { |
@@ -21,10 +21,10 @@ early_param("x2apic_phys", set_x2apic_phys_mode); | |||
21 | 21 | ||
22 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 22 | static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
23 | { | 23 | { |
24 | if (cpu_has_x2apic && x2apic_phys) | 24 | if (x2apic_phys) |
25 | return 1; | 25 | return x2apic_enabled(); |
26 | 26 | else | |
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | 29 | ||
30 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ | 30 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ |
@@ -213,7 +213,6 @@ struct apic apic_x2apic_phys = { | |||
213 | .send_IPI_all = x2apic_send_IPI_all, | 213 | .send_IPI_all = x2apic_send_IPI_all, |
214 | .send_IPI_self = x2apic_send_IPI_self, | 214 | .send_IPI_self = x2apic_send_IPI_self, |
215 | 215 | ||
216 | .wakeup_cpu = NULL, | ||
217 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 216 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
218 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 217 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
219 | .wait_for_init_deassert = NULL, | 218 | .wait_for_init_deassert = NULL, |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 20b4ad07c3a1..1bd6da1f8fad 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -7,28 +7,28 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/threads.h> | ||
13 | #include <linux/cpu.h> | ||
14 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
11 | #include <linux/hardirq.h> | ||
12 | #include <linux/proc_fs.h> | ||
13 | #include <linux/threads.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
15 | #include <linux/string.h> | 16 | #include <linux/string.h> |
16 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/module.h> | ||
20 | #include <linux/hardirq.h> | ||
21 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
22 | #include <linux/proc_fs.h> | 20 | #include <linux/cpu.h> |
23 | #include <asm/current.h> | 21 | #include <linux/init.h> |
24 | #include <asm/smp.h> | 22 | |
25 | #include <asm/apic.h> | ||
26 | #include <asm/ipi.h> | ||
27 | #include <asm/pgtable.h> | ||
28 | #include <asm/uv/uv.h> | ||
29 | #include <asm/uv/uv_mmrs.h> | 23 | #include <asm/uv/uv_mmrs.h> |
30 | #include <asm/uv/uv_hub.h> | 24 | #include <asm/uv/uv_hub.h> |
25 | #include <asm/current.h> | ||
26 | #include <asm/pgtable.h> | ||
31 | #include <asm/uv/bios.h> | 27 | #include <asm/uv/bios.h> |
28 | #include <asm/uv/uv.h> | ||
29 | #include <asm/apic.h> | ||
30 | #include <asm/ipi.h> | ||
31 | #include <asm/smp.h> | ||
32 | 32 | ||
33 | DEFINE_PER_CPU(int, x2apic_extra_bits); | 33 | DEFINE_PER_CPU(int, x2apic_extra_bits); |
34 | 34 | ||
@@ -91,24 +91,28 @@ static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
91 | cpumask_set_cpu(cpu, retmask); | 91 | cpumask_set_cpu(cpu, retmask); |
92 | } | 92 | } |
93 | 93 | ||
94 | int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) | 94 | static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) |
95 | { | 95 | { |
96 | #ifdef CONFIG_SMP | ||
96 | unsigned long val; | 97 | unsigned long val; |
97 | int pnode; | 98 | int pnode; |
98 | 99 | ||
99 | pnode = uv_apicid_to_pnode(phys_apicid); | 100 | pnode = uv_apicid_to_pnode(phys_apicid); |
100 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | 101 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | |
101 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | | 102 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | |
102 | (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | | 103 | ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | |
103 | APIC_DM_INIT; | 104 | APIC_DM_INIT; |
104 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); | 105 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); |
105 | mdelay(10); | 106 | mdelay(10); |
106 | 107 | ||
107 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | 108 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | |
108 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | | 109 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | |
109 | (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | | 110 | ((start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | |
110 | APIC_DM_STARTUP; | 111 | APIC_DM_STARTUP; |
111 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); | 112 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); |
113 | |||
114 | atomic_set(&init_deasserted, 1); | ||
115 | #endif | ||
112 | return 0; | 116 | return 0; |
113 | } | 117 | } |
114 | 118 | ||
@@ -285,7 +289,7 @@ struct apic apic_x2apic_uv_x = { | |||
285 | .send_IPI_all = uv_send_IPI_all, | 289 | .send_IPI_all = uv_send_IPI_all, |
286 | .send_IPI_self = uv_send_IPI_self, | 290 | .send_IPI_self = uv_send_IPI_self, |
287 | 291 | ||
288 | .wakeup_cpu = NULL, | 292 | .wakeup_secondary_cpu = uv_wakeup_secondary, |
289 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 293 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
290 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 294 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
291 | .wait_for_init_deassert = NULL, | 295 | .wait_for_init_deassert = NULL, |
@@ -365,7 +369,7 @@ static __init void map_high(char *id, unsigned long base, int shift, | |||
365 | paddr = base << shift; | 369 | paddr = base << shift; |
366 | bytes = (1UL << shift) * (max_pnode + 1); | 370 | bytes = (1UL << shift) * (max_pnode + 1); |
367 | printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, | 371 | printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, |
368 | paddr + bytes); | 372 | paddr + bytes); |
369 | if (map_type == map_uc) | 373 | if (map_type == map_uc) |
370 | init_extra_mapping_uc(paddr, bytes); | 374 | init_extra_mapping_uc(paddr, bytes); |
371 | else | 375 | else |
@@ -528,7 +532,7 @@ late_initcall(uv_init_heartbeat); | |||
528 | 532 | ||
529 | /* | 533 | /* |
530 | * Called on each cpu to initialize the per_cpu UV data area. | 534 | * Called on each cpu to initialize the per_cpu UV data area. |
531 | * ZZZ hotplug not supported yet | 535 | * FIXME: hotplug not supported yet |
532 | */ | 536 | */ |
533 | void __cpuinit uv_cpu_init(void) | 537 | void __cpuinit uv_cpu_init(void) |
534 | { | 538 | { |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 37ba5f85b718..10033fe718e0 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -1192,6 +1192,7 @@ static int suspend(int vetoable) | |||
1192 | device_suspend(PMSG_SUSPEND); | 1192 | device_suspend(PMSG_SUSPEND); |
1193 | local_irq_disable(); | 1193 | local_irq_disable(); |
1194 | device_power_down(PMSG_SUSPEND); | 1194 | device_power_down(PMSG_SUSPEND); |
1195 | sysdev_suspend(PMSG_SUSPEND); | ||
1195 | 1196 | ||
1196 | local_irq_enable(); | 1197 | local_irq_enable(); |
1197 | 1198 | ||
@@ -1208,6 +1209,7 @@ static int suspend(int vetoable) | |||
1208 | if (err != APM_SUCCESS) | 1209 | if (err != APM_SUCCESS) |
1209 | apm_error("suspend", err); | 1210 | apm_error("suspend", err); |
1210 | err = (err == APM_SUCCESS) ? 0 : -EIO; | 1211 | err = (err == APM_SUCCESS) ? 0 : -EIO; |
1212 | sysdev_resume(); | ||
1211 | device_power_up(PMSG_RESUME); | 1213 | device_power_up(PMSG_RESUME); |
1212 | local_irq_enable(); | 1214 | local_irq_enable(); |
1213 | device_resume(PMSG_RESUME); | 1215 | device_resume(PMSG_RESUME); |
@@ -1228,6 +1230,7 @@ static void standby(void) | |||
1228 | 1230 | ||
1229 | local_irq_disable(); | 1231 | local_irq_disable(); |
1230 | device_power_down(PMSG_SUSPEND); | 1232 | device_power_down(PMSG_SUSPEND); |
1233 | sysdev_suspend(PMSG_SUSPEND); | ||
1231 | local_irq_enable(); | 1234 | local_irq_enable(); |
1232 | 1235 | ||
1233 | err = set_system_power_state(APM_STATE_STANDBY); | 1236 | err = set_system_power_state(APM_STATE_STANDBY); |
@@ -1235,6 +1238,7 @@ static void standby(void) | |||
1235 | apm_error("standby", err); | 1238 | apm_error("standby", err); |
1236 | 1239 | ||
1237 | local_irq_disable(); | 1240 | local_irq_disable(); |
1241 | sysdev_resume(); | ||
1238 | device_power_up(PMSG_RESUME); | 1242 | device_power_up(PMSG_RESUME); |
1239 | local_irq_enable(); | 1243 | local_irq_enable(); |
1240 | } | 1244 | } |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 25cf624eccb7..fe79985ce0f2 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -490,7 +490,7 @@ static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) | |||
490 | 490 | ||
491 | } | 491 | } |
492 | 492 | ||
493 | static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) | 493 | static void mce_cpu_features(struct cpuinfo_x86 *c) |
494 | { | 494 | { |
495 | switch (c->x86_vendor) { | 495 | switch (c->x86_vendor) { |
496 | case X86_VENDOR_INTEL: | 496 | case X86_VENDOR_INTEL: |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 4772e91e8246..9817506dd469 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -121,7 +121,7 @@ static long threshold_restart_bank(void *_tr) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /* cpu init entry point, called from mce.c with preempt off */ | 123 | /* cpu init entry point, called from mce.c with preempt off */ |
124 | void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | 124 | void mce_amd_feature_init(struct cpuinfo_x86 *c) |
125 | { | 125 | { |
126 | unsigned int bank, block; | 126 | unsigned int bank, block; |
127 | unsigned int cpu = smp_processor_id(); | 127 | unsigned int cpu = smp_processor_id(); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c index ae00938ea50b..aa5e287c98e0 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c | |||
@@ -31,7 +31,7 @@ asmlinkage void smp_thermal_interrupt(void) | |||
31 | irq_exit(); | 31 | irq_exit(); |
32 | } | 32 | } |
33 | 33 | ||
34 | static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) | 34 | static void intel_init_thermal(struct cpuinfo_x86 *c) |
35 | { | 35 | { |
36 | u32 l, h; | 36 | u32 l, h; |
37 | int tm2 = 0; | 37 | int tm2 = 0; |
@@ -85,7 +85,7 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) | |||
85 | return; | 85 | return; |
86 | } | 86 | } |
87 | 87 | ||
88 | void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) | 88 | void mce_intel_feature_init(struct cpuinfo_x86 *c) |
89 | { | 89 | { |
90 | intel_init_thermal(c); | 90 | intel_init_thermal(c); |
91 | } | 91 | } |
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 01b1244ef1c0..d67e0e48bc2d 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
@@ -7,11 +7,10 @@ | |||
7 | /* | 7 | /* |
8 | * Get CPU information for use by the procfs. | 8 | * Get CPU information for use by the procfs. |
9 | */ | 9 | */ |
10 | #ifdef CONFIG_X86_32 | ||
11 | static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | 10 | static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, |
12 | unsigned int cpu) | 11 | unsigned int cpu) |
13 | { | 12 | { |
14 | #ifdef CONFIG_X86_HT | 13 | #ifdef CONFIG_SMP |
15 | if (c->x86_max_cores * smp_num_siblings > 1) { | 14 | if (c->x86_max_cores * smp_num_siblings > 1) { |
16 | seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); | 15 | seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); |
17 | seq_printf(m, "siblings\t: %d\n", | 16 | seq_printf(m, "siblings\t: %d\n", |
@@ -24,6 +23,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | |||
24 | #endif | 23 | #endif |
25 | } | 24 | } |
26 | 25 | ||
26 | #ifdef CONFIG_X86_32 | ||
27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | 27 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) |
28 | { | 28 | { |
29 | /* | 29 | /* |
@@ -50,22 +50,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | |||
50 | c->wp_works_ok ? "yes" : "no"); | 50 | c->wp_works_ok ? "yes" : "no"); |
51 | } | 51 | } |
52 | #else | 52 | #else |
53 | static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, | ||
54 | unsigned int cpu) | ||
55 | { | ||
56 | #ifdef CONFIG_SMP | ||
57 | if (c->x86_max_cores * smp_num_siblings > 1) { | ||
58 | seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); | ||
59 | seq_printf(m, "siblings\t: %d\n", | ||
60 | cpus_weight(per_cpu(cpu_core_map, cpu))); | ||
61 | seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); | ||
62 | seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); | ||
63 | seq_printf(m, "apicid\t\t: %d\n", c->apicid); | ||
64 | seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid); | ||
65 | } | ||
66 | #endif | ||
67 | } | ||
68 | |||
69 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) | 53 | static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) |
70 | { | 54 | { |
71 | seq_printf(m, | 55 | seq_printf(m, |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 999e827ef9c7..899e8938e79f 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -1359,7 +1359,7 @@ nmi_espfix_stack: | |||
1359 | CFI_ADJUST_CFA_OFFSET 4 | 1359 | CFI_ADJUST_CFA_OFFSET 4 |
1360 | pushl %esp | 1360 | pushl %esp |
1361 | CFI_ADJUST_CFA_OFFSET 4 | 1361 | CFI_ADJUST_CFA_OFFSET 4 |
1362 | addw $4, (%esp) | 1362 | addl $4, (%esp) |
1363 | /* copy the iret frame of 12 bytes */ | 1363 | /* copy the iret frame of 12 bytes */ |
1364 | .rept 3 | 1364 | .rept 3 |
1365 | pushl 16(%esp) | 1365 | pushl 16(%esp) |
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 11d5093eb281..df89102bef80 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
23 | #include <asm/desc.h> | 23 | #include <asm/desc.h> |
24 | #include <asm/apic.h> | 24 | #include <asm/apic.h> |
25 | #include <asm/arch_hooks.h> | ||
26 | #include <asm/i8259.h> | 25 | #include <asm/i8259.h> |
27 | 26 | ||
28 | /* | 27 | /* |
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index e41980a373ab..99c4d308f16b 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c | |||
@@ -85,19 +85,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) | |||
85 | 85 | ||
86 | t->io_bitmap_max = bytes; | 86 | t->io_bitmap_max = bytes; |
87 | 87 | ||
88 | #ifdef CONFIG_X86_32 | ||
89 | /* | ||
90 | * Sets the lazy trigger so that the next I/O operation will | ||
91 | * reload the correct bitmap. | ||
92 | * Reset the owner so that a process switch will not set | ||
93 | * tss->io_bitmap_base to IO_BITMAP_OFFSET. | ||
94 | */ | ||
95 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; | ||
96 | tss->io_bitmap_owner = NULL; | ||
97 | #else | ||
98 | /* Update the TSS: */ | 88 | /* Update the TSS: */ |
99 | memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated); | 89 | memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated); |
100 | #endif | ||
101 | 90 | ||
102 | put_cpu(); | 91 | put_cpu(); |
103 | 92 | ||
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index bf629cadec1a..50b8c3a3006c 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
19 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
20 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
21 | #include <asm/arch_hooks.h> | 21 | #include <asm/setup.h> |
22 | #include <asm/i8259.h> | 22 | #include <asm/i8259.h> |
23 | #include <asm/traps.h> | 23 | #include <asm/traps.h> |
24 | 24 | ||
@@ -127,8 +127,8 @@ void __init native_init_IRQ(void) | |||
127 | { | 127 | { |
128 | int i; | 128 | int i; |
129 | 129 | ||
130 | /* all the set up before the call gates are initialised */ | 130 | /* Execute any quirks before the call gates are initialised: */ |
131 | pre_intr_init_hook(); | 131 | x86_quirk_pre_intr_init(); |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Cover the whole vector space, no vector can escape | 134 | * Cover the whole vector space, no vector can escape |
@@ -188,10 +188,11 @@ void __init native_init_IRQ(void) | |||
188 | if (!acpi_ioapic) | 188 | if (!acpi_ioapic) |
189 | setup_irq(2, &irq2); | 189 | setup_irq(2, &irq2); |
190 | 190 | ||
191 | /* setup after call gates are initialised (usually add in | 191 | /* |
192 | * the architecture specific gates) | 192 | * Call quirks after call gates are initialised (usually add in |
193 | * the architecture specific gates): | ||
193 | */ | 194 | */ |
194 | intr_init_hook(); | 195 | x86_quirk_intr_init(); |
195 | 196 | ||
196 | /* | 197 | /* |
197 | * External FPU? Set up irq13 if so, for | 198 | * External FPU? Set up irq13 if so, for |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 652fce6d2cce..137f2e8132df 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/clocksource.h> | 19 | #include <linux/clocksource.h> |
20 | #include <linux/kvm_para.h> | 20 | #include <linux/kvm_para.h> |
21 | #include <asm/pvclock.h> | 21 | #include <asm/pvclock.h> |
22 | #include <asm/arch_hooks.h> | ||
23 | #include <asm/msr.h> | 22 | #include <asm/msr.h> |
24 | #include <asm/apic.h> | 23 | #include <asm/apic.h> |
25 | #include <linux/percpu.h> | 24 | #include <linux/percpu.h> |
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 37f420018a41..f5fc8c781a62 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c | |||
@@ -121,7 +121,7 @@ static void machine_kexec_page_table_set_one( | |||
121 | static void machine_kexec_prepare_page_tables(struct kimage *image) | 121 | static void machine_kexec_prepare_page_tables(struct kimage *image) |
122 | { | 122 | { |
123 | void *control_page; | 123 | void *control_page; |
124 | pmd_t *pmd = 0; | 124 | pmd_t *pmd = NULL; |
125 | 125 | ||
126 | control_page = page_address(image->control_code_page); | 126 | control_page = page_address(image->control_code_page); |
127 | #ifdef CONFIG_X86_PAE | 127 | #ifdef CONFIG_X86_PAE |
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index 2dc183758be3..845d80ce1ef1 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <linux/ioport.h> | 51 | #include <linux/ioport.h> |
52 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
53 | #include <linux/init.h> | 53 | #include <linux/init.h> |
54 | #include <asm/arch_hooks.h> | ||
55 | 54 | ||
56 | static unsigned char which_scsi; | 55 | static unsigned char which_scsi; |
57 | 56 | ||
@@ -474,6 +473,4 @@ void __kprobes mca_handle_nmi(void) | |||
474 | * adapter was responsible for the error. | 473 | * adapter was responsible for the error. |
475 | */ | 474 | */ |
476 | bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); | 475 | bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); |
477 | 476 | } | |
478 | mca_nmi_hook(); | ||
479 | } /* mca_handle_nmi */ | ||
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 7f4d2586972e..37cb1bda1baf 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -710,13 +710,22 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, | |||
710 | * of physical memory; so that simply reserving | 710 | * of physical memory; so that simply reserving |
711 | * PAGE_SIZE from mpf->physptr yields BUG() | 711 | * PAGE_SIZE from mpf->physptr yields BUG() |
712 | * in reserve_bootmem. | 712 | * in reserve_bootmem. |
713 | * also need to make sure physptr is below than | ||
714 | * max_low_pfn | ||
715 | * we don't need reserve the area above max_low_pfn | ||
713 | */ | 716 | */ |
714 | unsigned long end = max_low_pfn * PAGE_SIZE; | 717 | unsigned long end = max_low_pfn * PAGE_SIZE; |
715 | if (mpf->physptr + size > end) | 718 | |
716 | size = end - mpf->physptr; | 719 | if (mpf->physptr < end) { |
717 | #endif | 720 | if (mpf->physptr + size > end) |
721 | size = end - mpf->physptr; | ||
722 | reserve_bootmem_generic(mpf->physptr, size, | ||
723 | BOOTMEM_DEFAULT); | ||
724 | } | ||
725 | #else | ||
718 | reserve_bootmem_generic(mpf->physptr, size, | 726 | reserve_bootmem_generic(mpf->physptr, size, |
719 | BOOTMEM_DEFAULT); | 727 | BOOTMEM_DEFAULT); |
728 | #endif | ||
720 | } | 729 | } |
721 | 730 | ||
722 | return 1; | 731 | return 1; |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 6dc4dca255e4..63dd358d8ee1 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <asm/paravirt.h> | 28 | #include <asm/paravirt.h> |
29 | #include <asm/desc.h> | 29 | #include <asm/desc.h> |
30 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
31 | #include <asm/arch_hooks.h> | ||
32 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
33 | #include <asm/time.h> | 32 | #include <asm/time.h> |
34 | #include <asm/pgalloc.h> | 33 | #include <asm/pgalloc.h> |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 87b69d4fac16..6afa5232dbb7 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -1,8 +1,8 @@ | |||
1 | #include <linux/errno.h> | 1 | #include <linux/errno.h> |
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/mm.h> | 3 | #include <linux/mm.h> |
4 | #include <asm/idle.h> | ||
5 | #include <linux/smp.h> | 4 | #include <linux/smp.h> |
5 | #include <linux/prctl.h> | ||
6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
@@ -11,6 +11,9 @@ | |||
11 | #include <linux/ftrace.h> | 11 | #include <linux/ftrace.h> |
12 | #include <asm/system.h> | 12 | #include <asm/system.h> |
13 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
14 | #include <asm/idle.h> | ||
15 | #include <asm/uaccess.h> | ||
16 | #include <asm/i387.h> | ||
14 | 17 | ||
15 | unsigned long idle_halt; | 18 | unsigned long idle_halt; |
16 | EXPORT_SYMBOL(idle_halt); | 19 | EXPORT_SYMBOL(idle_halt); |
@@ -56,6 +59,192 @@ void arch_task_cache_init(void) | |||
56 | } | 59 | } |
57 | 60 | ||
58 | /* | 61 | /* |
62 | * Free current thread data structures etc.. | ||
63 | */ | ||
64 | void exit_thread(void) | ||
65 | { | ||
66 | struct task_struct *me = current; | ||
67 | struct thread_struct *t = &me->thread; | ||
68 | |||
69 | if (me->thread.io_bitmap_ptr) { | ||
70 | struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); | ||
71 | |||
72 | kfree(t->io_bitmap_ptr); | ||
73 | t->io_bitmap_ptr = NULL; | ||
74 | clear_thread_flag(TIF_IO_BITMAP); | ||
75 | /* | ||
76 | * Careful, clear this in the TSS too: | ||
77 | */ | ||
78 | memset(tss->io_bitmap, 0xff, t->io_bitmap_max); | ||
79 | t->io_bitmap_max = 0; | ||
80 | put_cpu(); | ||
81 | } | ||
82 | |||
83 | ds_exit_thread(current); | ||
84 | } | ||
85 | |||
86 | void flush_thread(void) | ||
87 | { | ||
88 | struct task_struct *tsk = current; | ||
89 | |||
90 | #ifdef CONFIG_X86_64 | ||
91 | if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) { | ||
92 | clear_tsk_thread_flag(tsk, TIF_ABI_PENDING); | ||
93 | if (test_tsk_thread_flag(tsk, TIF_IA32)) { | ||
94 | clear_tsk_thread_flag(tsk, TIF_IA32); | ||
95 | } else { | ||
96 | set_tsk_thread_flag(tsk, TIF_IA32); | ||
97 | current_thread_info()->status |= TS_COMPAT; | ||
98 | } | ||
99 | } | ||
100 | #endif | ||
101 | |||
102 | clear_tsk_thread_flag(tsk, TIF_DEBUG); | ||
103 | |||
104 | tsk->thread.debugreg0 = 0; | ||
105 | tsk->thread.debugreg1 = 0; | ||
106 | tsk->thread.debugreg2 = 0; | ||
107 | tsk->thread.debugreg3 = 0; | ||
108 | tsk->thread.debugreg6 = 0; | ||
109 | tsk->thread.debugreg7 = 0; | ||
110 | memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); | ||
111 | /* | ||
112 | * Forget coprocessor state.. | ||
113 | */ | ||
114 | tsk->fpu_counter = 0; | ||
115 | clear_fpu(tsk); | ||
116 | clear_used_math(); | ||
117 | } | ||
118 | |||
119 | static void hard_disable_TSC(void) | ||
120 | { | ||
121 | write_cr4(read_cr4() | X86_CR4_TSD); | ||
122 | } | ||
123 | |||
124 | void disable_TSC(void) | ||
125 | { | ||
126 | preempt_disable(); | ||
127 | if (!test_and_set_thread_flag(TIF_NOTSC)) | ||
128 | /* | ||
129 | * Must flip the CPU state synchronously with | ||
130 | * TIF_NOTSC in the current running context. | ||
131 | */ | ||
132 | hard_disable_TSC(); | ||
133 | preempt_enable(); | ||
134 | } | ||
135 | |||
136 | static void hard_enable_TSC(void) | ||
137 | { | ||
138 | write_cr4(read_cr4() & ~X86_CR4_TSD); | ||
139 | } | ||
140 | |||
141 | static void enable_TSC(void) | ||
142 | { | ||
143 | preempt_disable(); | ||
144 | if (test_and_clear_thread_flag(TIF_NOTSC)) | ||
145 | /* | ||
146 | * Must flip the CPU state synchronously with | ||
147 | * TIF_NOTSC in the current running context. | ||
148 | */ | ||
149 | hard_enable_TSC(); | ||
150 | preempt_enable(); | ||
151 | } | ||
152 | |||
153 | int get_tsc_mode(unsigned long adr) | ||
154 | { | ||
155 | unsigned int val; | ||
156 | |||
157 | if (test_thread_flag(TIF_NOTSC)) | ||
158 | val = PR_TSC_SIGSEGV; | ||
159 | else | ||
160 | val = PR_TSC_ENABLE; | ||
161 | |||
162 | return put_user(val, (unsigned int __user *)adr); | ||
163 | } | ||
164 | |||
165 | int set_tsc_mode(unsigned int val) | ||
166 | { | ||
167 | if (val == PR_TSC_SIGSEGV) | ||
168 | disable_TSC(); | ||
169 | else if (val == PR_TSC_ENABLE) | ||
170 | enable_TSC(); | ||
171 | else | ||
172 | return -EINVAL; | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | ||
178 | struct tss_struct *tss) | ||
179 | { | ||
180 | struct thread_struct *prev, *next; | ||
181 | |||
182 | prev = &prev_p->thread; | ||
183 | next = &next_p->thread; | ||
184 | |||
185 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || | ||
186 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | ||
187 | ds_switch_to(prev_p, next_p); | ||
188 | else if (next->debugctlmsr != prev->debugctlmsr) | ||
189 | update_debugctlmsr(next->debugctlmsr); | ||
190 | |||
191 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | ||
192 | set_debugreg(next->debugreg0, 0); | ||
193 | set_debugreg(next->debugreg1, 1); | ||
194 | set_debugreg(next->debugreg2, 2); | ||
195 | set_debugreg(next->debugreg3, 3); | ||
196 | /* no 4 and 5 */ | ||
197 | set_debugreg(next->debugreg6, 6); | ||
198 | set_debugreg(next->debugreg7, 7); | ||
199 | } | ||
200 | |||
201 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | ||
202 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | ||
203 | /* prev and next are different */ | ||
204 | if (test_tsk_thread_flag(next_p, TIF_NOTSC)) | ||
205 | hard_disable_TSC(); | ||
206 | else | ||
207 | hard_enable_TSC(); | ||
208 | } | ||
209 | |||
210 | if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | ||
211 | /* | ||
212 | * Copy the relevant range of the IO bitmap. | ||
213 | * Normally this is 128 bytes or less: | ||
214 | */ | ||
215 | memcpy(tss->io_bitmap, next->io_bitmap_ptr, | ||
216 | max(prev->io_bitmap_max, next->io_bitmap_max)); | ||
217 | } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { | ||
218 | /* | ||
219 | * Clear any possible leftover bits: | ||
220 | */ | ||
221 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | int sys_fork(struct pt_regs *regs) | ||
226 | { | ||
227 | return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * This is trivial, and on the face of it looks like it | ||
232 | * could equally well be done in user mode. | ||
233 | * | ||
234 | * Not so, for quite unobvious reasons - register pressure. | ||
235 | * In user mode vfork() cannot have a stack frame, and if | ||
236 | * done by calling the "clone()" system call directly, you | ||
237 | * do not have enough call-clobbered registers to hold all | ||
238 | * the information you need. | ||
239 | */ | ||
240 | int sys_vfork(struct pt_regs *regs) | ||
241 | { | ||
242 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, | ||
243 | NULL, NULL); | ||
244 | } | ||
245 | |||
246 | |||
247 | /* | ||
59 | * Idle related variables and functions | 248 | * Idle related variables and functions |
60 | */ | 249 | */ |
61 | unsigned long boot_option_idle_override = 0; | 250 | unsigned long boot_option_idle_override = 0; |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 646da41a620a..14014d766cad 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -230,55 +230,6 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |||
230 | } | 230 | } |
231 | EXPORT_SYMBOL(kernel_thread); | 231 | EXPORT_SYMBOL(kernel_thread); |
232 | 232 | ||
233 | /* | ||
234 | * Free current thread data structures etc.. | ||
235 | */ | ||
236 | void exit_thread(void) | ||
237 | { | ||
238 | /* The process may have allocated an io port bitmap... nuke it. */ | ||
239 | if (unlikely(test_thread_flag(TIF_IO_BITMAP))) { | ||
240 | struct task_struct *tsk = current; | ||
241 | struct thread_struct *t = &tsk->thread; | ||
242 | int cpu = get_cpu(); | ||
243 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | ||
244 | |||
245 | kfree(t->io_bitmap_ptr); | ||
246 | t->io_bitmap_ptr = NULL; | ||
247 | clear_thread_flag(TIF_IO_BITMAP); | ||
248 | /* | ||
249 | * Careful, clear this in the TSS too: | ||
250 | */ | ||
251 | memset(tss->io_bitmap, 0xff, tss->io_bitmap_max); | ||
252 | t->io_bitmap_max = 0; | ||
253 | tss->io_bitmap_owner = NULL; | ||
254 | tss->io_bitmap_max = 0; | ||
255 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | ||
256 | put_cpu(); | ||
257 | } | ||
258 | |||
259 | ds_exit_thread(current); | ||
260 | } | ||
261 | |||
262 | void flush_thread(void) | ||
263 | { | ||
264 | struct task_struct *tsk = current; | ||
265 | |||
266 | tsk->thread.debugreg0 = 0; | ||
267 | tsk->thread.debugreg1 = 0; | ||
268 | tsk->thread.debugreg2 = 0; | ||
269 | tsk->thread.debugreg3 = 0; | ||
270 | tsk->thread.debugreg6 = 0; | ||
271 | tsk->thread.debugreg7 = 0; | ||
272 | memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); | ||
273 | clear_tsk_thread_flag(tsk, TIF_DEBUG); | ||
274 | /* | ||
275 | * Forget coprocessor state.. | ||
276 | */ | ||
277 | tsk->fpu_counter = 0; | ||
278 | clear_fpu(tsk); | ||
279 | clear_used_math(); | ||
280 | } | ||
281 | |||
282 | void release_thread(struct task_struct *dead_task) | 233 | void release_thread(struct task_struct *dead_task) |
283 | { | 234 | { |
284 | BUG_ON(dead_task->mm); | 235 | BUG_ON(dead_task->mm); |
@@ -366,127 +317,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
366 | } | 317 | } |
367 | EXPORT_SYMBOL_GPL(start_thread); | 318 | EXPORT_SYMBOL_GPL(start_thread); |
368 | 319 | ||
369 | static void hard_disable_TSC(void) | ||
370 | { | ||
371 | write_cr4(read_cr4() | X86_CR4_TSD); | ||
372 | } | ||
373 | |||
374 | void disable_TSC(void) | ||
375 | { | ||
376 | preempt_disable(); | ||
377 | if (!test_and_set_thread_flag(TIF_NOTSC)) | ||
378 | /* | ||
379 | * Must flip the CPU state synchronously with | ||
380 | * TIF_NOTSC in the current running context. | ||
381 | */ | ||
382 | hard_disable_TSC(); | ||
383 | preempt_enable(); | ||
384 | } | ||
385 | |||
386 | static void hard_enable_TSC(void) | ||
387 | { | ||
388 | write_cr4(read_cr4() & ~X86_CR4_TSD); | ||
389 | } | ||
390 | |||
391 | static void enable_TSC(void) | ||
392 | { | ||
393 | preempt_disable(); | ||
394 | if (test_and_clear_thread_flag(TIF_NOTSC)) | ||
395 | /* | ||
396 | * Must flip the CPU state synchronously with | ||
397 | * TIF_NOTSC in the current running context. | ||
398 | */ | ||
399 | hard_enable_TSC(); | ||
400 | preempt_enable(); | ||
401 | } | ||
402 | |||
403 | int get_tsc_mode(unsigned long adr) | ||
404 | { | ||
405 | unsigned int val; | ||
406 | |||
407 | if (test_thread_flag(TIF_NOTSC)) | ||
408 | val = PR_TSC_SIGSEGV; | ||
409 | else | ||
410 | val = PR_TSC_ENABLE; | ||
411 | |||
412 | return put_user(val, (unsigned int __user *)adr); | ||
413 | } | ||
414 | |||
415 | int set_tsc_mode(unsigned int val) | ||
416 | { | ||
417 | if (val == PR_TSC_SIGSEGV) | ||
418 | disable_TSC(); | ||
419 | else if (val == PR_TSC_ENABLE) | ||
420 | enable_TSC(); | ||
421 | else | ||
422 | return -EINVAL; | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static noinline void | ||
428 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | ||
429 | struct tss_struct *tss) | ||
430 | { | ||
431 | struct thread_struct *prev, *next; | ||
432 | |||
433 | prev = &prev_p->thread; | ||
434 | next = &next_p->thread; | ||
435 | |||
436 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || | ||
437 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | ||
438 | ds_switch_to(prev_p, next_p); | ||
439 | else if (next->debugctlmsr != prev->debugctlmsr) | ||
440 | update_debugctlmsr(next->debugctlmsr); | ||
441 | |||
442 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | ||
443 | set_debugreg(next->debugreg0, 0); | ||
444 | set_debugreg(next->debugreg1, 1); | ||
445 | set_debugreg(next->debugreg2, 2); | ||
446 | set_debugreg(next->debugreg3, 3); | ||
447 | /* no 4 and 5 */ | ||
448 | set_debugreg(next->debugreg6, 6); | ||
449 | set_debugreg(next->debugreg7, 7); | ||
450 | } | ||
451 | |||
452 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | ||
453 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | ||
454 | /* prev and next are different */ | ||
455 | if (test_tsk_thread_flag(next_p, TIF_NOTSC)) | ||
456 | hard_disable_TSC(); | ||
457 | else | ||
458 | hard_enable_TSC(); | ||
459 | } | ||
460 | |||
461 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | ||
462 | /* | ||
463 | * Disable the bitmap via an invalid offset. We still cache | ||
464 | * the previous bitmap owner and the IO bitmap contents: | ||
465 | */ | ||
466 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | ||
467 | return; | ||
468 | } | ||
469 | |||
470 | if (likely(next == tss->io_bitmap_owner)) { | ||
471 | /* | ||
472 | * Previous owner of the bitmap (hence the bitmap content) | ||
473 | * matches the next task, we dont have to do anything but | ||
474 | * to set a valid offset in the TSS: | ||
475 | */ | ||
476 | tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; | ||
477 | return; | ||
478 | } | ||
479 | /* | ||
480 | * Lazy TSS's I/O bitmap copy. We set an invalid offset here | ||
481 | * and we let the task to get a GPF in case an I/O instruction | ||
482 | * is performed. The handler of the GPF will verify that the | ||
483 | * faulting task has a valid I/O bitmap and, it true, does the | ||
484 | * real copy and restart the instruction. This will save us | ||
485 | * redundant copies when the currently switched task does not | ||
486 | * perform any I/O during its timeslice. | ||
487 | */ | ||
488 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; | ||
489 | } | ||
490 | 320 | ||
491 | /* | 321 | /* |
492 | * switch_to(x,yn) should switch tasks from x to y. | 322 | * switch_to(x,yn) should switch tasks from x to y. |
@@ -600,11 +430,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
600 | return prev_p; | 430 | return prev_p; |
601 | } | 431 | } |
602 | 432 | ||
603 | int sys_fork(struct pt_regs *regs) | ||
604 | { | ||
605 | return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); | ||
606 | } | ||
607 | |||
608 | int sys_clone(struct pt_regs *regs) | 433 | int sys_clone(struct pt_regs *regs) |
609 | { | 434 | { |
610 | unsigned long clone_flags; | 435 | unsigned long clone_flags; |
@@ -621,21 +446,6 @@ int sys_clone(struct pt_regs *regs) | |||
621 | } | 446 | } |
622 | 447 | ||
623 | /* | 448 | /* |
624 | * This is trivial, and on the face of it looks like it | ||
625 | * could equally well be done in user mode. | ||
626 | * | ||
627 | * Not so, for quite unobvious reasons - register pressure. | ||
628 | * In user mode vfork() cannot have a stack frame, and if | ||
629 | * done by calling the "clone()" system call directly, you | ||
630 | * do not have enough call-clobbered registers to hold all | ||
631 | * the information you need. | ||
632 | */ | ||
633 | int sys_vfork(struct pt_regs *regs) | ||
634 | { | ||
635 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL); | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | * sys_execve() executes a new program. | 449 | * sys_execve() executes a new program. |
640 | */ | 450 | */ |
641 | int sys_execve(struct pt_regs *regs) | 451 | int sys_execve(struct pt_regs *regs) |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 836ef6575f01..abb7e6a7f0c6 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -237,61 +237,6 @@ void show_regs(struct pt_regs *regs) | |||
237 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); | 237 | show_trace(NULL, regs, (void *)(regs + 1), regs->bp); |
238 | } | 238 | } |
239 | 239 | ||
240 | /* | ||
241 | * Free current thread data structures etc.. | ||
242 | */ | ||
243 | void exit_thread(void) | ||
244 | { | ||
245 | struct task_struct *me = current; | ||
246 | struct thread_struct *t = &me->thread; | ||
247 | |||
248 | if (me->thread.io_bitmap_ptr) { | ||
249 | struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); | ||
250 | |||
251 | kfree(t->io_bitmap_ptr); | ||
252 | t->io_bitmap_ptr = NULL; | ||
253 | clear_thread_flag(TIF_IO_BITMAP); | ||
254 | /* | ||
255 | * Careful, clear this in the TSS too: | ||
256 | */ | ||
257 | memset(tss->io_bitmap, 0xff, t->io_bitmap_max); | ||
258 | t->io_bitmap_max = 0; | ||
259 | put_cpu(); | ||
260 | } | ||
261 | |||
262 | ds_exit_thread(current); | ||
263 | } | ||
264 | |||
265 | void flush_thread(void) | ||
266 | { | ||
267 | struct task_struct *tsk = current; | ||
268 | |||
269 | if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) { | ||
270 | clear_tsk_thread_flag(tsk, TIF_ABI_PENDING); | ||
271 | if (test_tsk_thread_flag(tsk, TIF_IA32)) { | ||
272 | clear_tsk_thread_flag(tsk, TIF_IA32); | ||
273 | } else { | ||
274 | set_tsk_thread_flag(tsk, TIF_IA32); | ||
275 | current_thread_info()->status |= TS_COMPAT; | ||
276 | } | ||
277 | } | ||
278 | clear_tsk_thread_flag(tsk, TIF_DEBUG); | ||
279 | |||
280 | tsk->thread.debugreg0 = 0; | ||
281 | tsk->thread.debugreg1 = 0; | ||
282 | tsk->thread.debugreg2 = 0; | ||
283 | tsk->thread.debugreg3 = 0; | ||
284 | tsk->thread.debugreg6 = 0; | ||
285 | tsk->thread.debugreg7 = 0; | ||
286 | memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); | ||
287 | /* | ||
288 | * Forget coprocessor state.. | ||
289 | */ | ||
290 | tsk->fpu_counter = 0; | ||
291 | clear_fpu(tsk); | ||
292 | clear_used_math(); | ||
293 | } | ||
294 | |||
295 | void release_thread(struct task_struct *dead_task) | 240 | void release_thread(struct task_struct *dead_task) |
296 | { | 241 | { |
297 | if (dead_task->mm) { | 242 | if (dead_task->mm) { |
@@ -425,118 +370,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
425 | } | 370 | } |
426 | EXPORT_SYMBOL_GPL(start_thread); | 371 | EXPORT_SYMBOL_GPL(start_thread); |
427 | 372 | ||
428 | static void hard_disable_TSC(void) | ||
429 | { | ||
430 | write_cr4(read_cr4() | X86_CR4_TSD); | ||
431 | } | ||
432 | |||
433 | void disable_TSC(void) | ||
434 | { | ||
435 | preempt_disable(); | ||
436 | if (!test_and_set_thread_flag(TIF_NOTSC)) | ||
437 | /* | ||
438 | * Must flip the CPU state synchronously with | ||
439 | * TIF_NOTSC in the current running context. | ||
440 | */ | ||
441 | hard_disable_TSC(); | ||
442 | preempt_enable(); | ||
443 | } | ||
444 | |||
445 | static void hard_enable_TSC(void) | ||
446 | { | ||
447 | write_cr4(read_cr4() & ~X86_CR4_TSD); | ||
448 | } | ||
449 | |||
450 | static void enable_TSC(void) | ||
451 | { | ||
452 | preempt_disable(); | ||
453 | if (test_and_clear_thread_flag(TIF_NOTSC)) | ||
454 | /* | ||
455 | * Must flip the CPU state synchronously with | ||
456 | * TIF_NOTSC in the current running context. | ||
457 | */ | ||
458 | hard_enable_TSC(); | ||
459 | preempt_enable(); | ||
460 | } | ||
461 | |||
462 | int get_tsc_mode(unsigned long adr) | ||
463 | { | ||
464 | unsigned int val; | ||
465 | |||
466 | if (test_thread_flag(TIF_NOTSC)) | ||
467 | val = PR_TSC_SIGSEGV; | ||
468 | else | ||
469 | val = PR_TSC_ENABLE; | ||
470 | |||
471 | return put_user(val, (unsigned int __user *)adr); | ||
472 | } | ||
473 | |||
474 | int set_tsc_mode(unsigned int val) | ||
475 | { | ||
476 | if (val == PR_TSC_SIGSEGV) | ||
477 | disable_TSC(); | ||
478 | else if (val == PR_TSC_ENABLE) | ||
479 | enable_TSC(); | ||
480 | else | ||
481 | return -EINVAL; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * This special macro can be used to load a debugging register | ||
488 | */ | ||
489 | #define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r) | ||
490 | |||
491 | static inline void __switch_to_xtra(struct task_struct *prev_p, | ||
492 | struct task_struct *next_p, | ||
493 | struct tss_struct *tss) | ||
494 | { | ||
495 | struct thread_struct *prev, *next; | ||
496 | |||
497 | prev = &prev_p->thread, | ||
498 | next = &next_p->thread; | ||
499 | |||
500 | if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) || | ||
501 | test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR)) | ||
502 | ds_switch_to(prev_p, next_p); | ||
503 | else if (next->debugctlmsr != prev->debugctlmsr) | ||
504 | update_debugctlmsr(next->debugctlmsr); | ||
505 | |||
506 | if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { | ||
507 | loaddebug(next, 0); | ||
508 | loaddebug(next, 1); | ||
509 | loaddebug(next, 2); | ||
510 | loaddebug(next, 3); | ||
511 | /* no 4 and 5 */ | ||
512 | loaddebug(next, 6); | ||
513 | loaddebug(next, 7); | ||
514 | } | ||
515 | |||
516 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | ||
517 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | ||
518 | /* prev and next are different */ | ||
519 | if (test_tsk_thread_flag(next_p, TIF_NOTSC)) | ||
520 | hard_disable_TSC(); | ||
521 | else | ||
522 | hard_enable_TSC(); | ||
523 | } | ||
524 | |||
525 | if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | ||
526 | /* | ||
527 | * Copy the relevant range of the IO bitmap. | ||
528 | * Normally this is 128 bytes or less: | ||
529 | */ | ||
530 | memcpy(tss->io_bitmap, next->io_bitmap_ptr, | ||
531 | max(prev->io_bitmap_max, next->io_bitmap_max)); | ||
532 | } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { | ||
533 | /* | ||
534 | * Clear any possible leftover bits: | ||
535 | */ | ||
536 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | /* | 373 | /* |
541 | * switch_to(x,y) should switch tasks from x to y. | 374 | * switch_to(x,y) should switch tasks from x to y. |
542 | * | 375 | * |
@@ -694,11 +527,6 @@ void set_personality_64bit(void) | |||
694 | current->personality &= ~READ_IMPLIES_EXEC; | 527 | current->personality &= ~READ_IMPLIES_EXEC; |
695 | } | 528 | } |
696 | 529 | ||
697 | asmlinkage long sys_fork(struct pt_regs *regs) | ||
698 | { | ||
699 | return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); | ||
700 | } | ||
701 | |||
702 | asmlinkage long | 530 | asmlinkage long |
703 | sys_clone(unsigned long clone_flags, unsigned long newsp, | 531 | sys_clone(unsigned long clone_flags, unsigned long newsp, |
704 | void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) | 532 | void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) |
@@ -708,22 +536,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
708 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); | 536 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); |
709 | } | 537 | } |
710 | 538 | ||
711 | /* | ||
712 | * This is trivial, and on the face of it looks like it | ||
713 | * could equally well be done in user mode. | ||
714 | * | ||
715 | * Not so, for quite unobvious reasons - register pressure. | ||
716 | * In user mode vfork() cannot have a stack frame, and if | ||
717 | * done by calling the "clone()" system call directly, you | ||
718 | * do not have enough call-clobbered registers to hold all | ||
719 | * the information you need. | ||
720 | */ | ||
721 | asmlinkage long sys_vfork(struct pt_regs *regs) | ||
722 | { | ||
723 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, | ||
724 | NULL, NULL); | ||
725 | } | ||
726 | |||
727 | unsigned long get_wchan(struct task_struct *p) | 539 | unsigned long get_wchan(struct task_struct *p) |
728 | { | 540 | { |
729 | unsigned long stack; | 541 | unsigned long stack; |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index fb2159a5c817..3d9672e59c16 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1383,7 +1383,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, | |||
1383 | #ifdef CONFIG_X86_32 | 1383 | #ifdef CONFIG_X86_32 |
1384 | # define IS_IA32 1 | 1384 | # define IS_IA32 1 |
1385 | #elif defined CONFIG_IA32_EMULATION | 1385 | #elif defined CONFIG_IA32_EMULATION |
1386 | # define IS_IA32 test_thread_flag(TIF_IA32) | 1386 | # define IS_IA32 is_compat_task() |
1387 | #else | 1387 | #else |
1388 | # define IS_IA32 0 | 1388 | # define IS_IA32 0 |
1389 | #endif | 1389 | #endif |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index ebef80055795..4c54bc0d8ff3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -74,8 +74,9 @@ | |||
74 | #include <asm/e820.h> | 74 | #include <asm/e820.h> |
75 | #include <asm/mpspec.h> | 75 | #include <asm/mpspec.h> |
76 | #include <asm/setup.h> | 76 | #include <asm/setup.h> |
77 | #include <asm/arch_hooks.h> | ||
78 | #include <asm/efi.h> | 77 | #include <asm/efi.h> |
78 | #include <asm/timer.h> | ||
79 | #include <asm/i8259.h> | ||
79 | #include <asm/sections.h> | 80 | #include <asm/sections.h> |
80 | #include <asm/dmi.h> | 81 | #include <asm/dmi.h> |
81 | #include <asm/io_apic.h> | 82 | #include <asm/io_apic.h> |
@@ -599,19 +600,7 @@ static int __init setup_elfcorehdr(char *arg) | |||
599 | early_param("elfcorehdr", setup_elfcorehdr); | 600 | early_param("elfcorehdr", setup_elfcorehdr); |
600 | #endif | 601 | #endif |
601 | 602 | ||
602 | static int __init default_update_apic(void) | 603 | static struct x86_quirks default_x86_quirks __initdata; |
603 | { | ||
604 | #ifdef CONFIG_SMP | ||
605 | if (!apic->wakeup_cpu) | ||
606 | apic->wakeup_cpu = wakeup_secondary_cpu_via_init; | ||
607 | #endif | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static struct x86_quirks default_x86_quirks __initdata = { | ||
613 | .update_apic = default_update_apic, | ||
614 | }; | ||
615 | 604 | ||
616 | struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; | 605 | struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; |
617 | 606 | ||
@@ -668,7 +657,6 @@ void __init setup_arch(char **cmdline_p) | |||
668 | #ifdef CONFIG_X86_32 | 657 | #ifdef CONFIG_X86_32 |
669 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 658 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
670 | visws_early_detect(); | 659 | visws_early_detect(); |
671 | pre_setup_arch_hook(); | ||
672 | #else | 660 | #else |
673 | printk(KERN_INFO "Command line: %s\n", boot_command_line); | 661 | printk(KERN_INFO "Command line: %s\n", boot_command_line); |
674 | #endif | 662 | #endif |
@@ -875,9 +863,7 @@ void __init setup_arch(char **cmdline_p) | |||
875 | 863 | ||
876 | reserve_initrd(); | 864 | reserve_initrd(); |
877 | 865 | ||
878 | #ifdef CONFIG_X86_64 | ||
879 | vsmp_init(); | 866 | vsmp_init(); |
880 | #endif | ||
881 | 867 | ||
882 | io_delay_init(); | 868 | io_delay_init(); |
883 | 869 | ||
@@ -988,7 +974,7 @@ void __init setup_arch(char **cmdline_p) | |||
988 | #ifdef CONFIG_X86_32 | 974 | #ifdef CONFIG_X86_32 |
989 | 975 | ||
990 | /** | 976 | /** |
991 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors | 977 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors |
992 | * | 978 | * |
993 | * Description: | 979 | * Description: |
994 | * Perform any necessary interrupt initialisation prior to setting up | 980 | * Perform any necessary interrupt initialisation prior to setting up |
@@ -996,7 +982,7 @@ void __init setup_arch(char **cmdline_p) | |||
996 | * interrupts should be initialised here if the machine emulates a PC | 982 | * interrupts should be initialised here if the machine emulates a PC |
997 | * in any way. | 983 | * in any way. |
998 | **/ | 984 | **/ |
999 | void __init pre_intr_init_hook(void) | 985 | void __init x86_quirk_pre_intr_init(void) |
1000 | { | 986 | { |
1001 | if (x86_quirks->arch_pre_intr_init) { | 987 | if (x86_quirks->arch_pre_intr_init) { |
1002 | if (x86_quirks->arch_pre_intr_init()) | 988 | if (x86_quirks->arch_pre_intr_init()) |
@@ -1006,7 +992,7 @@ void __init pre_intr_init_hook(void) | |||
1006 | } | 992 | } |
1007 | 993 | ||
1008 | /** | 994 | /** |
1009 | * intr_init_hook - post gate setup interrupt initialisation | 995 | * x86_quirk_intr_init - post gate setup interrupt initialisation |
1010 | * | 996 | * |
1011 | * Description: | 997 | * Description: |
1012 | * Fill in any interrupts that may have been left out by the general | 998 | * Fill in any interrupts that may have been left out by the general |
@@ -1014,7 +1000,7 @@ void __init pre_intr_init_hook(void) | |||
1014 | * than the devices on the I/O bus (like APIC interrupts in intel MP | 1000 | * than the devices on the I/O bus (like APIC interrupts in intel MP |
1015 | * systems) are started here. | 1001 | * systems) are started here. |
1016 | **/ | 1002 | **/ |
1017 | void __init intr_init_hook(void) | 1003 | void __init x86_quirk_intr_init(void) |
1018 | { | 1004 | { |
1019 | if (x86_quirks->arch_intr_init) { | 1005 | if (x86_quirks->arch_intr_init) { |
1020 | if (x86_quirks->arch_intr_init()) | 1006 | if (x86_quirks->arch_intr_init()) |
@@ -1023,25 +1009,13 @@ void __init intr_init_hook(void) | |||
1023 | } | 1009 | } |
1024 | 1010 | ||
1025 | /** | 1011 | /** |
1026 | * pre_setup_arch_hook - hook called prior to any setup_arch() execution | 1012 | * x86_quirk_trap_init - initialise system specific traps |
1027 | * | ||
1028 | * Description: | ||
1029 | * generally used to activate any machine specific identification | ||
1030 | * routines that may be needed before setup_arch() runs. On Voyager | ||
1031 | * this is used to get the board revision and type. | ||
1032 | **/ | ||
1033 | void __init pre_setup_arch_hook(void) | ||
1034 | { | ||
1035 | } | ||
1036 | |||
1037 | /** | ||
1038 | * trap_init_hook - initialise system specific traps | ||
1039 | * | 1013 | * |
1040 | * Description: | 1014 | * Description: |
1041 | * Called as the final act of trap_init(). Used in VISWS to initialise | 1015 | * Called as the final act of trap_init(). Used in VISWS to initialise |
1042 | * the various board specific APIC traps. | 1016 | * the various board specific APIC traps. |
1043 | **/ | 1017 | **/ |
1044 | void __init trap_init_hook(void) | 1018 | void __init x86_quirk_trap_init(void) |
1045 | { | 1019 | { |
1046 | if (x86_quirks->arch_trap_init) { | 1020 | if (x86_quirks->arch_trap_init) { |
1047 | if (x86_quirks->arch_trap_init()) | 1021 | if (x86_quirks->arch_trap_init()) |
@@ -1051,29 +1025,29 @@ void __init trap_init_hook(void) | |||
1051 | 1025 | ||
1052 | static struct irqaction irq0 = { | 1026 | static struct irqaction irq0 = { |
1053 | .handler = timer_interrupt, | 1027 | .handler = timer_interrupt, |
1054 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, | 1028 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, |
1055 | .mask = CPU_MASK_NONE, | 1029 | .mask = CPU_MASK_NONE, |
1056 | .name = "timer" | 1030 | .name = "timer" |
1057 | }; | 1031 | }; |
1058 | 1032 | ||
1059 | /** | 1033 | /** |
1060 | * pre_time_init_hook - do any specific initialisations before. | 1034 | * x86_quirk_pre_time_init - do any specific initialisations before. |
1061 | * | 1035 | * |
1062 | **/ | 1036 | **/ |
1063 | void __init pre_time_init_hook(void) | 1037 | void __init x86_quirk_pre_time_init(void) |
1064 | { | 1038 | { |
1065 | if (x86_quirks->arch_pre_time_init) | 1039 | if (x86_quirks->arch_pre_time_init) |
1066 | x86_quirks->arch_pre_time_init(); | 1040 | x86_quirks->arch_pre_time_init(); |
1067 | } | 1041 | } |
1068 | 1042 | ||
1069 | /** | 1043 | /** |
1070 | * time_init_hook - do any specific initialisations for the system timer. | 1044 | * x86_quirk_time_init - do any specific initialisations for the system timer. |
1071 | * | 1045 | * |
1072 | * Description: | 1046 | * Description: |
1073 | * Must plug the system timer interrupt source at HZ into the IRQ listed | 1047 | * Must plug the system timer interrupt source at HZ into the IRQ listed |
1074 | * in irq_vectors.h:TIMER_IRQ | 1048 | * in irq_vectors.h:TIMER_IRQ |
1075 | **/ | 1049 | **/ |
1076 | void __init time_init_hook(void) | 1050 | void __init x86_quirk_time_init(void) |
1077 | { | 1051 | { |
1078 | if (x86_quirks->arch_time_init) { | 1052 | if (x86_quirks->arch_time_init) { |
1079 | /* | 1053 | /* |
@@ -1088,25 +1062,4 @@ void __init time_init_hook(void) | |||
1088 | irq0.mask = cpumask_of_cpu(0); | 1062 | irq0.mask = cpumask_of_cpu(0); |
1089 | setup_irq(0, &irq0); | 1063 | setup_irq(0, &irq0); |
1090 | } | 1064 | } |
1091 | |||
1092 | #ifdef CONFIG_MCA | ||
1093 | /** | ||
1094 | * mca_nmi_hook - hook into MCA specific NMI chain | ||
1095 | * | ||
1096 | * Description: | ||
1097 | * The MCA (Microchannel Architecture) has an NMI chain for NMI sources | ||
1098 | * along the MCA bus. Use this to hook into that chain if you will need | ||
1099 | * it. | ||
1100 | **/ | ||
1101 | void mca_nmi_hook(void) | ||
1102 | { | ||
1103 | /* | ||
1104 | * If I recall correctly, there's a whole bunch of other things that | ||
1105 | * we can do to check for NMI problems, but that's all I know about | ||
1106 | * at the moment. | ||
1107 | */ | ||
1108 | pr_warning("NMI generated from unknown source!\n"); | ||
1109 | } | ||
1110 | #endif /* CONFIG_MCA */ | ||
1111 | |||
1112 | #endif /* CONFIG_X86_32 */ | 1065 | #endif /* CONFIG_X86_32 */ |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 7cdcd16885ed..d2cc6428c587 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -187,40 +187,35 @@ setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate, | |||
187 | /* | 187 | /* |
188 | * Set up a signal frame. | 188 | * Set up a signal frame. |
189 | */ | 189 | */ |
190 | #ifdef CONFIG_X86_32 | ||
191 | static const struct { | ||
192 | u16 poplmovl; | ||
193 | u32 val; | ||
194 | u16 int80; | ||
195 | } __attribute__((packed)) retcode = { | ||
196 | 0xb858, /* popl %eax; movl $..., %eax */ | ||
197 | __NR_sigreturn, | ||
198 | 0x80cd, /* int $0x80 */ | ||
199 | }; | ||
200 | |||
201 | static const struct { | ||
202 | u8 movl; | ||
203 | u32 val; | ||
204 | u16 int80; | ||
205 | u8 pad; | ||
206 | } __attribute__((packed)) rt_retcode = { | ||
207 | 0xb8, /* movl $..., %eax */ | ||
208 | __NR_rt_sigreturn, | ||
209 | 0x80cd, /* int $0x80 */ | ||
210 | 0 | ||
211 | }; | ||
212 | 190 | ||
213 | /* | 191 | /* |
214 | * Determine which stack to use.. | 192 | * Determine which stack to use.. |
215 | */ | 193 | */ |
194 | static unsigned long align_sigframe(unsigned long sp) | ||
195 | { | ||
196 | #ifdef CONFIG_X86_32 | ||
197 | /* | ||
198 | * Align the stack pointer according to the i386 ABI, | ||
199 | * i.e. so that on function entry ((sp + 4) & 15) == 0. | ||
200 | */ | ||
201 | sp = ((sp + 4) & -16ul) - 4; | ||
202 | #else /* !CONFIG_X86_32 */ | ||
203 | sp = round_down(sp, 16) - 8; | ||
204 | #endif | ||
205 | return sp; | ||
206 | } | ||
207 | |||
216 | static inline void __user * | 208 | static inline void __user * |
217 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | 209 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, |
218 | void **fpstate) | 210 | void __user **fpstate) |
219 | { | 211 | { |
220 | unsigned long sp; | ||
221 | |||
222 | /* Default to using normal stack */ | 212 | /* Default to using normal stack */ |
223 | sp = regs->sp; | 213 | unsigned long sp = regs->sp; |
214 | |||
215 | #ifdef CONFIG_X86_64 | ||
216 | /* redzone */ | ||
217 | sp -= 128; | ||
218 | #endif /* CONFIG_X86_64 */ | ||
224 | 219 | ||
225 | /* | 220 | /* |
226 | * If we are on the alternate signal stack and would overflow it, don't. | 221 | * If we are on the alternate signal stack and would overflow it, don't. |
@@ -234,30 +229,52 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, | |||
234 | if (sas_ss_flags(sp) == 0) | 229 | if (sas_ss_flags(sp) == 0) |
235 | sp = current->sas_ss_sp + current->sas_ss_size; | 230 | sp = current->sas_ss_sp + current->sas_ss_size; |
236 | } else { | 231 | } else { |
232 | #ifdef CONFIG_X86_32 | ||
237 | /* This is the legacy signal stack switching. */ | 233 | /* This is the legacy signal stack switching. */ |
238 | if ((regs->ss & 0xffff) != __USER_DS && | 234 | if ((regs->ss & 0xffff) != __USER_DS && |
239 | !(ka->sa.sa_flags & SA_RESTORER) && | 235 | !(ka->sa.sa_flags & SA_RESTORER) && |
240 | ka->sa.sa_restorer) | 236 | ka->sa.sa_restorer) |
241 | sp = (unsigned long) ka->sa.sa_restorer; | 237 | sp = (unsigned long) ka->sa.sa_restorer; |
238 | #endif /* CONFIG_X86_32 */ | ||
242 | } | 239 | } |
243 | 240 | ||
244 | if (used_math()) { | 241 | if (used_math()) { |
245 | sp = sp - sig_xstate_size; | 242 | sp -= sig_xstate_size; |
246 | *fpstate = (struct _fpstate *) sp; | 243 | #ifdef CONFIG_X86_64 |
244 | sp = round_down(sp, 64); | ||
245 | #endif /* CONFIG_X86_64 */ | ||
246 | *fpstate = (void __user *)sp; | ||
247 | |||
247 | if (save_i387_xstate(*fpstate) < 0) | 248 | if (save_i387_xstate(*fpstate) < 0) |
248 | return (void __user *)-1L; | 249 | return (void __user *)-1L; |
249 | } | 250 | } |
250 | 251 | ||
251 | sp -= frame_size; | 252 | return (void __user *)align_sigframe(sp - frame_size); |
252 | /* | ||
253 | * Align the stack pointer according to the i386 ABI, | ||
254 | * i.e. so that on function entry ((sp + 4) & 15) == 0. | ||
255 | */ | ||
256 | sp = ((sp + 4) & -16ul) - 4; | ||
257 | |||
258 | return (void __user *) sp; | ||
259 | } | 253 | } |
260 | 254 | ||
255 | #ifdef CONFIG_X86_32 | ||
256 | static const struct { | ||
257 | u16 poplmovl; | ||
258 | u32 val; | ||
259 | u16 int80; | ||
260 | } __attribute__((packed)) retcode = { | ||
261 | 0xb858, /* popl %eax; movl $..., %eax */ | ||
262 | __NR_sigreturn, | ||
263 | 0x80cd, /* int $0x80 */ | ||
264 | }; | ||
265 | |||
266 | static const struct { | ||
267 | u8 movl; | ||
268 | u32 val; | ||
269 | u16 int80; | ||
270 | u8 pad; | ||
271 | } __attribute__((packed)) rt_retcode = { | ||
272 | 0xb8, /* movl $..., %eax */ | ||
273 | __NR_rt_sigreturn, | ||
274 | 0x80cd, /* int $0x80 */ | ||
275 | 0 | ||
276 | }; | ||
277 | |||
261 | static int | 278 | static int |
262 | __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 279 | __setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, |
263 | struct pt_regs *regs) | 280 | struct pt_regs *regs) |
@@ -388,24 +405,6 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
388 | return 0; | 405 | return 0; |
389 | } | 406 | } |
390 | #else /* !CONFIG_X86_32 */ | 407 | #else /* !CONFIG_X86_32 */ |
391 | /* | ||
392 | * Determine which stack to use.. | ||
393 | */ | ||
394 | static void __user * | ||
395 | get_stack(struct k_sigaction *ka, unsigned long sp, unsigned long size) | ||
396 | { | ||
397 | /* Default to using normal stack - redzone*/ | ||
398 | sp -= 128; | ||
399 | |||
400 | /* This is the X/Open sanctioned signal stack switching. */ | ||
401 | if (ka->sa.sa_flags & SA_ONSTACK) { | ||
402 | if (sas_ss_flags(sp) == 0) | ||
403 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
404 | } | ||
405 | |||
406 | return (void __user *)round_down(sp - size, 64); | ||
407 | } | ||
408 | |||
409 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 408 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
410 | sigset_t *set, struct pt_regs *regs) | 409 | sigset_t *set, struct pt_regs *regs) |
411 | { | 410 | { |
@@ -414,15 +413,7 @@ static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
414 | int err = 0; | 413 | int err = 0; |
415 | struct task_struct *me = current; | 414 | struct task_struct *me = current; |
416 | 415 | ||
417 | if (used_math()) { | 416 | frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe), &fp); |
418 | fp = get_stack(ka, regs->sp, sig_xstate_size); | ||
419 | frame = (void __user *)round_down( | ||
420 | (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; | ||
421 | |||
422 | if (save_i387_xstate(fp) < 0) | ||
423 | return -EFAULT; | ||
424 | } else | ||
425 | frame = get_stack(ka, regs->sp, sizeof(struct rt_sigframe)) - 8; | ||
426 | 417 | ||
427 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 418 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
428 | return -EFAULT; | 419 | return -EFAULT; |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 9ce666387f37..249334f5080a 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -112,7 +112,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); | |||
112 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); | 112 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); |
113 | EXPORT_PER_CPU_SYMBOL(cpu_info); | 113 | EXPORT_PER_CPU_SYMBOL(cpu_info); |
114 | 114 | ||
115 | static atomic_t init_deasserted; | 115 | atomic_t init_deasserted; |
116 | 116 | ||
117 | 117 | ||
118 | /* Set if we find a B stepping CPU */ | 118 | /* Set if we find a B stepping CPU */ |
@@ -614,12 +614,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
614 | unsigned long send_status, accept_status = 0; | 614 | unsigned long send_status, accept_status = 0; |
615 | int maxlvt, num_starts, j; | 615 | int maxlvt, num_starts, j; |
616 | 616 | ||
617 | if (get_uv_system_type() == UV_NON_UNIQUE_APIC) { | ||
618 | send_status = uv_wakeup_secondary(phys_apicid, start_eip); | ||
619 | atomic_set(&init_deasserted, 1); | ||
620 | return send_status; | ||
621 | } | ||
622 | |||
623 | maxlvt = lapic_get_maxlvt(); | 617 | maxlvt = lapic_get_maxlvt(); |
624 | 618 | ||
625 | /* | 619 | /* |
@@ -748,7 +742,8 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
748 | /* | 742 | /* |
749 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 743 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
750 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. | 744 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. |
751 | * Returns zero if CPU booted OK, else error code from ->wakeup_cpu. | 745 | * Returns zero if CPU booted OK, else error code from |
746 | * ->wakeup_secondary_cpu. | ||
752 | */ | 747 | */ |
753 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | 748 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
754 | { | 749 | { |
@@ -835,9 +830,13 @@ do_rest: | |||
835 | } | 830 | } |
836 | 831 | ||
837 | /* | 832 | /* |
838 | * Starting actual IPI sequence... | 833 | * Kick the secondary CPU. Use the method in the APIC driver |
834 | * if it's defined - or use an INIT boot APIC message otherwise: | ||
839 | */ | 835 | */ |
840 | boot_error = apic->wakeup_cpu(apicid, start_ip); | 836 | if (apic->wakeup_secondary_cpu) |
837 | boot_error = apic->wakeup_secondary_cpu(apicid, start_ip); | ||
838 | else | ||
839 | boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); | ||
841 | 840 | ||
842 | if (!boot_error) { | 841 | if (!boot_error) { |
843 | /* | 842 | /* |
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c index 764c74e871f2..5c5d87f0b2e1 100644 --- a/arch/x86/kernel/time_32.c +++ b/arch/x86/kernel/time_32.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/time.h> | 33 | #include <linux/time.h> |
34 | #include <linux/mca.h> | 34 | #include <linux/mca.h> |
35 | 35 | ||
36 | #include <asm/arch_hooks.h> | 36 | #include <asm/setup.h> |
37 | #include <asm/hpet.h> | 37 | #include <asm/hpet.h> |
38 | #include <asm/time.h> | 38 | #include <asm/time.h> |
39 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
@@ -118,7 +118,7 @@ void __init hpet_time_init(void) | |||
118 | { | 118 | { |
119 | if (!hpet_enable()) | 119 | if (!hpet_enable()) |
120 | setup_pit_timer(); | 120 | setup_pit_timer(); |
121 | time_init_hook(); | 121 | x86_quirk_time_init(); |
122 | } | 122 | } |
123 | 123 | ||
124 | /* | 124 | /* |
@@ -131,7 +131,7 @@ void __init hpet_time_init(void) | |||
131 | */ | 131 | */ |
132 | void __init time_init(void) | 132 | void __init time_init(void) |
133 | { | 133 | { |
134 | pre_time_init_hook(); | 134 | x86_quirk_pre_time_init(); |
135 | tsc_init(); | 135 | tsc_init(); |
136 | late_time_init = choose_time_init(); | 136 | late_time_init = choose_time_init(); |
137 | } | 137 | } |
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index e6e695acd725..241ec3923f61 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c | |||
@@ -115,7 +115,7 @@ unsigned long __init calibrate_cpu(void) | |||
115 | 115 | ||
116 | static struct irqaction irq0 = { | 116 | static struct irqaction irq0 = { |
117 | .handler = timer_interrupt, | 117 | .handler = timer_interrupt, |
118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING, | 118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, |
119 | .mask = CPU_MASK_NONE, | 119 | .mask = CPU_MASK_NONE, |
120 | .name = "timer" | 120 | .name = "timer" |
121 | }; | 121 | }; |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index acb8c0585ab9..a1d288327ff0 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #include <asm/proto.h> | 61 | #include <asm/proto.h> |
62 | #else | 62 | #else |
63 | #include <asm/processor-flags.h> | 63 | #include <asm/processor-flags.h> |
64 | #include <asm/arch_hooks.h> | 64 | #include <asm/setup.h> |
65 | #include <asm/traps.h> | 65 | #include <asm/traps.h> |
66 | 66 | ||
67 | #include "cpu/mcheck/mce.h" | 67 | #include "cpu/mcheck/mce.h" |
@@ -118,47 +118,6 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err) | |||
118 | if (!user_mode_vm(regs)) | 118 | if (!user_mode_vm(regs)) |
119 | die(str, regs, err); | 119 | die(str, regs, err); |
120 | } | 120 | } |
121 | |||
122 | /* | ||
123 | * Perform the lazy TSS's I/O bitmap copy. If the TSS has an | ||
124 | * invalid offset set (the LAZY one) and the faulting thread has | ||
125 | * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS, | ||
126 | * we set the offset field correctly and return 1. | ||
127 | */ | ||
128 | static int lazy_iobitmap_copy(void) | ||
129 | { | ||
130 | struct thread_struct *thread; | ||
131 | struct tss_struct *tss; | ||
132 | int cpu; | ||
133 | |||
134 | cpu = get_cpu(); | ||
135 | tss = &per_cpu(init_tss, cpu); | ||
136 | thread = ¤t->thread; | ||
137 | |||
138 | if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && | ||
139 | thread->io_bitmap_ptr) { | ||
140 | memcpy(tss->io_bitmap, thread->io_bitmap_ptr, | ||
141 | thread->io_bitmap_max); | ||
142 | /* | ||
143 | * If the previously set map was extending to higher ports | ||
144 | * than the current one, pad extra space with 0xff (no access). | ||
145 | */ | ||
146 | if (thread->io_bitmap_max < tss->io_bitmap_max) { | ||
147 | memset((char *) tss->io_bitmap + | ||
148 | thread->io_bitmap_max, 0xff, | ||
149 | tss->io_bitmap_max - thread->io_bitmap_max); | ||
150 | } | ||
151 | tss->io_bitmap_max = thread->io_bitmap_max; | ||
152 | tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; | ||
153 | tss->io_bitmap_owner = thread; | ||
154 | put_cpu(); | ||
155 | |||
156 | return 1; | ||
157 | } | ||
158 | put_cpu(); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | #endif | 121 | #endif |
163 | 122 | ||
164 | static void __kprobes | 123 | static void __kprobes |
@@ -309,11 +268,6 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
309 | conditional_sti(regs); | 268 | conditional_sti(regs); |
310 | 269 | ||
311 | #ifdef CONFIG_X86_32 | 270 | #ifdef CONFIG_X86_32 |
312 | if (lazy_iobitmap_copy()) { | ||
313 | /* restart the faulting instruction */ | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | if (regs->flags & X86_VM_MASK) | 271 | if (regs->flags & X86_VM_MASK) |
318 | goto gp_in_vm86; | 272 | goto gp_in_vm86; |
319 | #endif | 273 | #endif |
@@ -942,7 +896,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
942 | info.si_signo = SIGILL; | 896 | info.si_signo = SIGILL; |
943 | info.si_errno = 0; | 897 | info.si_errno = 0; |
944 | info.si_code = ILL_BADSTK; | 898 | info.si_code = ILL_BADSTK; |
945 | info.si_addr = 0; | 899 | info.si_addr = NULL; |
946 | if (notify_die(DIE_TRAP, "iret exception", | 900 | if (notify_die(DIE_TRAP, "iret exception", |
947 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) | 901 | regs, error_code, 32, SIGILL) == NOTIFY_STOP) |
948 | return; | 902 | return; |
@@ -1026,6 +980,6 @@ void __init trap_init(void) | |||
1026 | cpu_init(); | 980 | cpu_init(); |
1027 | 981 | ||
1028 | #ifdef CONFIG_X86_32 | 982 | #ifdef CONFIG_X86_32 |
1029 | trap_init_hook(); | 983 | x86_quirk_trap_init(); |
1030 | #endif | 984 | #endif |
1031 | } | 985 | } |
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 34199d30ff46..191a876e9e87 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <asm/visws/cobalt.h> | 25 | #include <asm/visws/cobalt.h> |
26 | #include <asm/visws/piix4.h> | 26 | #include <asm/visws/piix4.h> |
27 | #include <asm/arch_hooks.h> | ||
28 | #include <asm/io_apic.h> | 27 | #include <asm/io_apic.h> |
29 | #include <asm/fixmap.h> | 28 | #include <asm/fixmap.h> |
30 | #include <asm/reboot.h> | 29 | #include <asm/reboot.h> |
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 9cd28c04952a..33a788d5879c 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include <asm/vmi.h> | 29 | #include <asm/vmi.h> |
30 | #include <asm/vmi_time.h> | 30 | #include <asm/vmi_time.h> |
31 | #include <asm/arch_hooks.h> | ||
32 | #include <asm/apicdef.h> | 31 | #include <asm/apicdef.h> |
33 | #include <asm/apic.h> | 32 | #include <asm/apic.h> |
34 | #include <asm/timer.h> | 33 | #include <asm/timer.h> |
@@ -202,7 +201,7 @@ static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) | |||
202 | static struct irqaction vmi_clock_action = { | 201 | static struct irqaction vmi_clock_action = { |
203 | .name = "vmi-timer", | 202 | .name = "vmi-timer", |
204 | .handler = vmi_timer_interrupt, | 203 | .handler = vmi_timer_interrupt, |
205 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, | 204 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, |
206 | .mask = CPU_MASK_ALL, | 205 | .mask = CPU_MASK_ALL, |
207 | }; | 206 | }; |
208 | 207 | ||
@@ -288,8 +287,7 @@ static struct clocksource clocksource_vmi; | |||
288 | static cycle_t read_real_cycles(void) | 287 | static cycle_t read_real_cycles(void) |
289 | { | 288 | { |
290 | cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); | 289 | cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); |
291 | return ret >= clocksource_vmi.cycle_last ? | 290 | return max(ret, clocksource_vmi.cycle_last); |
292 | ret : clocksource_vmi.cycle_last; | ||
293 | } | 291 | } |
294 | 292 | ||
295 | static struct clocksource clocksource_vmi = { | 293 | static struct clocksource clocksource_vmi = { |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index c609205df594..74de562812cc 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/paravirt.h> | 22 | #include <asm/paravirt.h> |
23 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
24 | 24 | ||
25 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT | 25 | #ifdef CONFIG_PARAVIRT |
26 | /* | 26 | /* |
27 | * Interrupt control on vSMPowered systems: | 27 | * Interrupt control on vSMPowered systems: |
28 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' | 28 | * ~AC is a shadow of IF. If IF is 'on' AC should be 'off' |
@@ -114,7 +114,6 @@ static void __init set_vsmp_pv_ops(void) | |||
114 | } | 114 | } |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | #ifdef CONFIG_PCI | ||
118 | static int is_vsmp = -1; | 117 | static int is_vsmp = -1; |
119 | 118 | ||
120 | static void __init detect_vsmp_box(void) | 119 | static void __init detect_vsmp_box(void) |
@@ -139,15 +138,6 @@ int is_vsmp_box(void) | |||
139 | return 0; | 138 | return 0; |
140 | } | 139 | } |
141 | } | 140 | } |
142 | #else | ||
143 | static void __init detect_vsmp_box(void) | ||
144 | { | ||
145 | } | ||
146 | int is_vsmp_box(void) | ||
147 | { | ||
148 | return 0; | ||
149 | } | ||
150 | #endif | ||
151 | 141 | ||
152 | void __init vsmp_init(void) | 142 | void __init vsmp_init(void) |
153 | { | 143 | { |