diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:02:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-06 03:02:57 -0400 |
commit | f541ae326fa120fa5c57433e4d9a133df212ce41 (patch) | |
tree | bdbd94ec72cfc601118051cb35e8617d55510177 /arch/x86/kernel/apic | |
parent | e255357764f92afcafafbd4879b222b8c752065a (diff) | |
parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) |
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream
Conflicts:
arch/powerpc/kernel/Makefile
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/unistd_32.h
arch/x86/include/asm/unistd_64.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/irq.c
arch/x86/kernel/syscall_table_32.S
arch/x86/mm/iomap_32.c
include/linux/sched.h
kernel/Makefile
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic_flat_64.c | 20 | ||||
-rw-r--r-- | arch/x86/kernel/apic/bigsmp_32.c | 53 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 238 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 296 | ||||
-rw-r--r-- | arch/x86/kernel/apic/nmi.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_32.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/apic/probe_64.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/apic/summit_32.c | 70 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_phys.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 53 |
13 files changed, 414 insertions, 425 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 4732768c5348..b0e5e712a7af 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <asm/idle.h> | 47 | #include <asm/idle.h> |
48 | #include <asm/mtrr.h> | 48 | #include <asm/mtrr.h> |
49 | #include <asm/smp.h> | 49 | #include <asm/smp.h> |
50 | #include <asm/mce.h> | ||
50 | 51 | ||
51 | unsigned int num_processors; | 52 | unsigned int num_processors; |
52 | 53 | ||
@@ -811,7 +812,7 @@ void clear_local_APIC(void) | |||
811 | u32 v; | 812 | u32 v; |
812 | 813 | ||
813 | /* APIC hasn't been mapped yet */ | 814 | /* APIC hasn't been mapped yet */ |
814 | if (!apic_phys) | 815 | if (!x2apic && !apic_phys) |
815 | return; | 816 | return; |
816 | 817 | ||
817 | maxlvt = lapic_get_maxlvt(); | 818 | maxlvt = lapic_get_maxlvt(); |
@@ -845,6 +846,14 @@ void clear_local_APIC(void) | |||
845 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); | 846 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); |
846 | } | 847 | } |
847 | #endif | 848 | #endif |
849 | #ifdef CONFIG_X86_MCE_INTEL | ||
850 | if (maxlvt >= 6) { | ||
851 | v = apic_read(APIC_LVTCMCI); | ||
852 | if (!(v & APIC_LVT_MASKED)) | ||
853 | apic_write(APIC_LVTCMCI, v | APIC_LVT_MASKED); | ||
854 | } | ||
855 | #endif | ||
856 | |||
848 | /* | 857 | /* |
849 | * Clean APIC state for other OSs: | 858 | * Clean APIC state for other OSs: |
850 | */ | 859 | */ |
@@ -1245,6 +1254,12 @@ void __cpuinit setup_local_APIC(void) | |||
1245 | apic_write(APIC_LVT1, value); | 1254 | apic_write(APIC_LVT1, value); |
1246 | 1255 | ||
1247 | preempt_enable(); | 1256 | preempt_enable(); |
1257 | |||
1258 | #ifdef CONFIG_X86_MCE_INTEL | ||
1259 | /* Recheck CMCI information after local APIC is up on CPU #0 */ | ||
1260 | if (smp_processor_id() == 0) | ||
1261 | cmci_recheck(); | ||
1262 | #endif | ||
1248 | } | 1263 | } |
1249 | 1264 | ||
1250 | void __cpuinit end_local_APIC_setup(void) | 1265 | void __cpuinit end_local_APIC_setup(void) |
@@ -1323,15 +1338,16 @@ void __init enable_IR_x2apic(void) | |||
1323 | return; | 1338 | return; |
1324 | } | 1339 | } |
1325 | 1340 | ||
1326 | local_irq_save(flags); | 1341 | ret = save_IO_APIC_setup(); |
1327 | mask_8259A(); | ||
1328 | |||
1329 | ret = save_mask_IO_APIC_setup(); | ||
1330 | if (ret) { | 1342 | if (ret) { |
1331 | pr_info("Saving IO-APIC state failed: %d\n", ret); | 1343 | pr_info("Saving IO-APIC state failed: %d\n", ret); |
1332 | goto end; | 1344 | goto end; |
1333 | } | 1345 | } |
1334 | 1346 | ||
1347 | local_irq_save(flags); | ||
1348 | mask_IO_APIC_setup(); | ||
1349 | mask_8259A(); | ||
1350 | |||
1335 | ret = enable_intr_remapping(1); | 1351 | ret = enable_intr_remapping(1); |
1336 | 1352 | ||
1337 | if (ret && x2apic_preenabled) { | 1353 | if (ret && x2apic_preenabled) { |
@@ -1356,10 +1372,10 @@ end_restore: | |||
1356 | else | 1372 | else |
1357 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); | 1373 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); |
1358 | 1374 | ||
1359 | end: | ||
1360 | unmask_8259A(); | 1375 | unmask_8259A(); |
1361 | local_irq_restore(flags); | 1376 | local_irq_restore(flags); |
1362 | 1377 | ||
1378 | end: | ||
1363 | if (!ret) { | 1379 | if (!ret) { |
1364 | if (!x2apic_preenabled) | 1380 | if (!x2apic_preenabled) |
1365 | pr_info("Enabled x2apic and interrupt-remapping\n"); | 1381 | pr_info("Enabled x2apic and interrupt-remapping\n"); |
@@ -1512,12 +1528,10 @@ void __init early_init_lapic_mapping(void) | |||
1512 | */ | 1528 | */ |
1513 | void __init init_apic_mappings(void) | 1529 | void __init init_apic_mappings(void) |
1514 | { | 1530 | { |
1515 | #ifdef CONFIG_X86_X2APIC | ||
1516 | if (x2apic) { | 1531 | if (x2apic) { |
1517 | boot_cpu_physical_apicid = read_apic_id(); | 1532 | boot_cpu_physical_apicid = read_apic_id(); |
1518 | return; | 1533 | return; |
1519 | } | 1534 | } |
1520 | #endif | ||
1521 | 1535 | ||
1522 | /* | 1536 | /* |
1523 | * If no local APIC can be found then set up a fake all | 1537 | * If no local APIC can be found then set up a fake all |
@@ -1961,12 +1975,9 @@ static int lapic_resume(struct sys_device *dev) | |||
1961 | 1975 | ||
1962 | local_irq_save(flags); | 1976 | local_irq_save(flags); |
1963 | 1977 | ||
1964 | #ifdef CONFIG_X86_X2APIC | ||
1965 | if (x2apic) | 1978 | if (x2apic) |
1966 | enable_x2apic(); | 1979 | enable_x2apic(); |
1967 | else | 1980 | else { |
1968 | #endif | ||
1969 | { | ||
1970 | /* | 1981 | /* |
1971 | * Make sure the APICBASE points to the right address | 1982 | * Make sure the APICBASE points to the right address |
1972 | * | 1983 | * |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 3b002995e145..0014714ea97b 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -159,20 +159,6 @@ static int flat_apic_id_registered(void) | |||
159 | return physid_isset(read_xapic_id(), phys_cpu_present_map); | 159 | return physid_isset(read_xapic_id(), phys_cpu_present_map); |
160 | } | 160 | } |
161 | 161 | ||
162 | static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
163 | { | ||
164 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | ||
165 | } | ||
166 | |||
167 | static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
168 | const struct cpumask *andmask) | ||
169 | { | ||
170 | unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | ||
171 | unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS; | ||
172 | |||
173 | return mask1 & mask2; | ||
174 | } | ||
175 | |||
176 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) | 162 | static int flat_phys_pkg_id(int initial_apic_id, int index_msb) |
177 | { | 163 | { |
178 | return hard_smp_processor_id() >> index_msb; | 164 | return hard_smp_processor_id() >> index_msb; |
@@ -213,8 +199,8 @@ struct apic apic_flat = { | |||
213 | .set_apic_id = set_apic_id, | 199 | .set_apic_id = set_apic_id, |
214 | .apic_id_mask = 0xFFu << 24, | 200 | .apic_id_mask = 0xFFu << 24, |
215 | 201 | ||
216 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, | 202 | .cpu_mask_to_apicid = default_cpu_mask_to_apicid, |
217 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, | 203 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
218 | 204 | ||
219 | .send_IPI_mask = flat_send_IPI_mask, | 205 | .send_IPI_mask = flat_send_IPI_mask, |
220 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, | 206 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, |
@@ -222,7 +208,6 @@ struct apic apic_flat = { | |||
222 | .send_IPI_all = flat_send_IPI_all, | 208 | .send_IPI_all = flat_send_IPI_all, |
223 | .send_IPI_self = apic_send_IPI_self, | 209 | .send_IPI_self = apic_send_IPI_self, |
224 | 210 | ||
225 | .wakeup_cpu = NULL, | ||
226 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 211 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
227 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 212 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
228 | .wait_for_init_deassert = NULL, | 213 | .wait_for_init_deassert = NULL, |
@@ -373,7 +358,6 @@ struct apic apic_physflat = { | |||
373 | .send_IPI_all = physflat_send_IPI_all, | 358 | .send_IPI_all = physflat_send_IPI_all, |
374 | .send_IPI_self = apic_send_IPI_self, | 359 | .send_IPI_self = apic_send_IPI_self, |
375 | 360 | ||
376 | .wakeup_cpu = NULL, | ||
377 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 361 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
378 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 362 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
379 | .wait_for_init_deassert = NULL, | 363 | .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..676cdac385c0 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -16,32 +16,31 @@ | |||
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 struct cpumask *bigsmp_target_cpus(void) |
30 | { | 30 | { |
31 | #ifdef CONFIG_SMP | 31 | #ifdef CONFIG_SMP |
32 | return &cpu_online_map; | 32 | return cpu_online_mask; |
33 | #else | 33 | #else |
34 | return &cpumask_of_cpu(0); | 34 | return cpumask_of(0); |
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 struct cpumask *cpumask) |
127 | { | 122 | { |
128 | return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask)); | 123 | return bigsmp_cpu_to_logical_apicid(cpumask_first(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 | } |
@@ -194,10 +188,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = { | |||
194 | { } /* NULL entry stops DMI scanning */ | 188 | { } /* NULL entry stops DMI scanning */ |
195 | }; | 189 | }; |
196 | 190 | ||
197 | static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask) | 191 | static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask) |
198 | { | 192 | { |
199 | cpus_clear(*retmask); | 193 | cpumask_clear(retmask); |
200 | cpu_set(cpu, *retmask); | 194 | cpumask_set_cpu(cpu, retmask); |
201 | } | 195 | } |
202 | 196 | ||
203 | static int probe_bigsmp(void) | 197 | static int probe_bigsmp(void) |
@@ -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..1c11b819f245 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; |
@@ -400,7 +410,7 @@ static void __init es7000_enable_apic_mode(void) | |||
400 | WARN(1, "Command failed, status = %x\n", mip_status); | 410 | WARN(1, "Command failed, status = %x\n", mip_status); |
401 | } | 411 | } |
402 | 412 | ||
403 | static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | 413 | static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask) |
404 | { | 414 | { |
405 | /* Careful. Some cpus do not strictly honor the set of cpus | 415 | /* Careful. Some cpus do not strictly honor the set of cpus |
406 | * specified in the interrupt destination when using lowest | 416 | * specified in the interrupt destination when using lowest |
@@ -410,17 +420,15 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
410 | * deliver interrupts to the wrong hyperthread when only one | 420 | * deliver interrupts to the wrong hyperthread when only one |
411 | * hyperthread was specified in the interrupt desitination. | 421 | * hyperthread was specified in the interrupt desitination. |
412 | */ | 422 | */ |
413 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 423 | cpumask_clear(retmask); |
424 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
414 | } | 425 | } |
415 | 426 | ||
416 | 427 | ||
417 | static void es7000_wait_for_init_deassert(atomic_t *deassert) | 428 | static void es7000_wait_for_init_deassert(atomic_t *deassert) |
418 | { | 429 | { |
419 | #ifndef CONFIG_ES7000_CLUSTERED_APIC | ||
420 | while (!atomic_read(deassert)) | 430 | while (!atomic_read(deassert)) |
421 | cpu_relax(); | 431 | cpu_relax(); |
422 | #endif | ||
423 | return; | ||
424 | } | 432 | } |
425 | 433 | ||
426 | static unsigned int es7000_get_apic_id(unsigned long x) | 434 | static unsigned int es7000_get_apic_id(unsigned long x) |
@@ -448,14 +456,14 @@ static int es7000_apic_id_registered(void) | |||
448 | return 1; | 456 | return 1; |
449 | } | 457 | } |
450 | 458 | ||
451 | static const cpumask_t *target_cpus_cluster(void) | 459 | static const struct cpumask *target_cpus_cluster(void) |
452 | { | 460 | { |
453 | return &CPU_MASK_ALL; | 461 | return cpu_all_mask; |
454 | } | 462 | } |
455 | 463 | ||
456 | static const cpumask_t *es7000_target_cpus(void) | 464 | static const struct cpumask *es7000_target_cpus(void) |
457 | { | 465 | { |
458 | return &cpumask_of_cpu(smp_processor_id()); | 466 | return cpumask_of(smp_processor_id()); |
459 | } | 467 | } |
460 | 468 | ||
461 | static unsigned long | 469 | static unsigned long |
@@ -510,7 +518,7 @@ static void es7000_setup_apic_routing(void) | |||
510 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | 518 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", |
511 | (apic_version[apic] == 0x14) ? | 519 | (apic_version[apic] == 0x14) ? |
512 | "Physical Cluster" : "Logical Cluster", | 520 | "Physical Cluster" : "Logical Cluster", |
513 | nr_ioapics, cpus_addr(*es7000_target_cpus())[0]); | 521 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); |
514 | } | 522 | } |
515 | 523 | ||
516 | static int es7000_apicid_to_node(int logical_apicid) | 524 | static int es7000_apicid_to_node(int logical_apicid) |
@@ -565,72 +573,24 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | |||
565 | return 1; | 573 | return 1; |
566 | } | 574 | } |
567 | 575 | ||
568 | static unsigned int | 576 | static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) |
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) | ||
605 | { | 577 | { |
606 | int cpus_found = 0; | 578 | unsigned int round = 0; |
607 | int num_bits_set; | 579 | int cpu, uninitialized_var(apicid); |
608 | int apicid; | ||
609 | int cpu; | ||
610 | 580 | ||
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 | /* | 581 | /* |
616 | * The cpus in the mask must all be on the apic cluster. If are not | 582 | * 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 | */ | 583 | */ |
619 | cpu = first_cpu(*cpumask); | 584 | for_each_cpu(cpu, cpumask) { |
620 | apicid = es7000_cpu_to_logical_apicid(cpu); | 585 | 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 | 586 | ||
625 | if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 587 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
626 | printk("%s: Not a valid mask!\n", __func__); | 588 | WARN(1, "Not a valid mask!"); |
627 | 589 | ||
628 | return es7000_cpu_to_logical_apicid(0); | 590 | return BAD_APICID; |
629 | } | ||
630 | apicid = new_apicid; | ||
631 | cpus_found++; | ||
632 | } | 591 | } |
633 | cpu++; | 592 | apicid = new_apicid; |
593 | round++; | ||
634 | } | 594 | } |
635 | return apicid; | 595 | return apicid; |
636 | } | 596 | } |
@@ -659,37 +619,103 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | |||
659 | return cpuid_apic >> index_msb; | 619 | return cpuid_apic >> index_msb; |
660 | } | 620 | } |
661 | 621 | ||
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) | 622 | static int probe_es7000(void) |
675 | { | 623 | { |
676 | /* probed later in mptable/ACPI hooks */ | 624 | /* probed later in mptable/ACPI hooks */ |
677 | return 0; | 625 | return 0; |
678 | } | 626 | } |
679 | 627 | ||
680 | static __init int | 628 | static int es7000_mps_ret; |
681 | es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | 629 | static int es7000_mps_oem_check(struct mpc_table *mpc, char *oem, |
630 | char *productid) | ||
682 | { | 631 | { |
632 | int ret = 0; | ||
633 | |||
683 | if (mpc->oemptr) { | 634 | if (mpc->oemptr) { |
684 | struct mpc_oemtable *oem_table = | 635 | struct mpc_oemtable *oem_table = |
685 | (struct mpc_oemtable *)mpc->oemptr; | 636 | (struct mpc_oemtable *)mpc->oemptr; |
686 | 637 | ||
687 | if (!strncmp(oem, "UNISYS", 6)) | 638 | if (!strncmp(oem, "UNISYS", 6)) |
688 | return parse_unisys_oem((char *)oem_table); | 639 | ret = parse_unisys_oem((char *)oem_table); |
689 | } | 640 | } |
690 | return 0; | 641 | |
642 | es7000_mps_ret = ret; | ||
643 | |||
644 | return ret && !es7000_apic_is_cluster(); | ||
691 | } | 645 | } |
692 | 646 | ||
647 | static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem, | ||
648 | char *productid) | ||
649 | { | ||
650 | int ret = es7000_mps_ret; | ||
651 | |||
652 | return ret && es7000_apic_is_cluster(); | ||
653 | } | ||
654 | |||
655 | struct apic apic_es7000_cluster = { | ||
656 | |||
657 | .name = "es7000", | ||
658 | .probe = probe_es7000, | ||
659 | .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster, | ||
660 | .apic_id_registered = es7000_apic_id_registered, | ||
661 | |||
662 | .irq_delivery_mode = dest_LowestPrio, | ||
663 | /* logical delivery broadcast to all procs: */ | ||
664 | .irq_dest_mode = 1, | ||
665 | |||
666 | .target_cpus = target_cpus_cluster, | ||
667 | .disable_esr = 1, | ||
668 | .dest_logical = 0, | ||
669 | .check_apicid_used = es7000_check_apicid_used, | ||
670 | .check_apicid_present = es7000_check_apicid_present, | ||
671 | |||
672 | .vector_allocation_domain = es7000_vector_allocation_domain, | ||
673 | .init_apic_ldr = es7000_init_apic_ldr_cluster, | ||
674 | |||
675 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, | ||
676 | .setup_apic_routing = es7000_setup_apic_routing, | ||
677 | .multi_timer_check = NULL, | ||
678 | .apicid_to_node = es7000_apicid_to_node, | ||
679 | .cpu_to_logical_apicid = es7000_cpu_to_logical_apicid, | ||
680 | .cpu_present_to_apicid = es7000_cpu_present_to_apicid, | ||
681 | .apicid_to_cpu_present = es7000_apicid_to_cpu_present, | ||
682 | .setup_portio_remap = NULL, | ||
683 | .check_phys_apicid_present = es7000_check_phys_apicid_present, | ||
684 | .enable_apic_mode = es7000_enable_apic_mode, | ||
685 | .phys_pkg_id = es7000_phys_pkg_id, | ||
686 | .mps_oem_check = es7000_mps_oem_check_cluster, | ||
687 | |||
688 | .get_apic_id = es7000_get_apic_id, | ||
689 | .set_apic_id = NULL, | ||
690 | .apic_id_mask = 0xFF << 24, | ||
691 | |||
692 | .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, | ||
693 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, | ||
694 | |||
695 | .send_IPI_mask = es7000_send_IPI_mask, | ||
696 | .send_IPI_mask_allbutself = NULL, | ||
697 | .send_IPI_allbutself = es7000_send_IPI_allbutself, | ||
698 | .send_IPI_all = es7000_send_IPI_all, | ||
699 | .send_IPI_self = default_send_IPI_self, | ||
700 | |||
701 | .wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip, | ||
702 | |||
703 | .trampoline_phys_low = 0x467, | ||
704 | .trampoline_phys_high = 0x469, | ||
705 | |||
706 | .wait_for_init_deassert = NULL, | ||
707 | |||
708 | /* Nothing to do for most platforms, since cleared by the INIT cycle: */ | ||
709 | .smp_callin_clear_local_apic = NULL, | ||
710 | .inquire_remote_apic = default_inquire_remote_apic, | ||
711 | |||
712 | .read = native_apic_mem_read, | ||
713 | .write = native_apic_mem_write, | ||
714 | .icr_read = native_apic_icr_read, | ||
715 | .icr_write = native_apic_icr_write, | ||
716 | .wait_icr_idle = native_apic_wait_icr_idle, | ||
717 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, | ||
718 | }; | ||
693 | 719 | ||
694 | struct apic apic_es7000 = { | 720 | struct apic apic_es7000 = { |
695 | 721 | ||
@@ -737,8 +763,6 @@ struct apic apic_es7000 = { | |||
737 | .send_IPI_all = es7000_send_IPI_all, | 763 | .send_IPI_all = es7000_send_IPI_all, |
738 | .send_IPI_self = default_send_IPI_self, | 764 | .send_IPI_self = default_send_IPI_self, |
739 | 765 | ||
740 | .wakeup_cpu = NULL, | ||
741 | |||
742 | .trampoline_phys_low = 0x467, | 766 | .trampoline_phys_low = 0x467, |
743 | .trampoline_phys_high = 0x469, | 767 | .trampoline_phys_high = 0x469, |
744 | 768 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 00e6071cefc4..1bb5c6cee3eb 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -389,6 +389,8 @@ struct io_apic { | |||
389 | unsigned int index; | 389 | unsigned int index; |
390 | unsigned int unused[3]; | 390 | unsigned int unused[3]; |
391 | unsigned int data; | 391 | unsigned int data; |
392 | unsigned int unused2[11]; | ||
393 | unsigned int eoi; | ||
392 | }; | 394 | }; |
393 | 395 | ||
394 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) | 396 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) |
@@ -397,6 +399,12 @@ static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) | |||
397 | + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); | 399 | + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); |
398 | } | 400 | } |
399 | 401 | ||
402 | static inline void io_apic_eoi(unsigned int apic, unsigned int vector) | ||
403 | { | ||
404 | struct io_apic __iomem *io_apic = io_apic_base(apic); | ||
405 | writel(vector, &io_apic->eoi); | ||
406 | } | ||
407 | |||
400 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) | 408 | static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) |
401 | { | 409 | { |
402 | struct io_apic __iomem *io_apic = io_apic_base(apic); | 410 | struct io_apic __iomem *io_apic = io_apic_base(apic); |
@@ -546,16 +554,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq | |||
546 | 554 | ||
547 | apic = entry->apic; | 555 | apic = entry->apic; |
548 | pin = entry->pin; | 556 | pin = entry->pin; |
549 | #ifdef CONFIG_INTR_REMAP | ||
550 | /* | 557 | /* |
551 | * With interrupt-remapping, destination information comes | 558 | * With interrupt-remapping, destination information comes |
552 | * from interrupt-remapping table entry. | 559 | * from interrupt-remapping table entry. |
553 | */ | 560 | */ |
554 | if (!irq_remapped(irq)) | 561 | if (!irq_remapped(irq)) |
555 | io_apic_write(apic, 0x11 + pin*2, dest); | 562 | io_apic_write(apic, 0x11 + pin*2, dest); |
556 | #else | ||
557 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
558 | #endif | ||
559 | reg = io_apic_read(apic, 0x10 + pin*2); | 563 | reg = io_apic_read(apic, 0x10 + pin*2); |
560 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | 564 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; |
561 | reg |= vector; | 565 | reg |= vector; |
@@ -588,10 +592,12 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask) | |||
588 | if (assign_irq_vector(irq, cfg, mask)) | 592 | if (assign_irq_vector(irq, cfg, mask)) |
589 | return BAD_APICID; | 593 | return BAD_APICID; |
590 | 594 | ||
591 | cpumask_and(desc->affinity, cfg->domain, mask); | 595 | /* check that before desc->addinity get updated */ |
592 | set_extra_move_desc(desc, mask); | 596 | set_extra_move_desc(desc, mask); |
593 | 597 | ||
594 | return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask); | 598 | cpumask_copy(desc->affinity, mask); |
599 | |||
600 | return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain); | ||
595 | } | 601 | } |
596 | 602 | ||
597 | static void | 603 | static void |
@@ -849,9 +855,9 @@ __setup("pirq=", ioapic_pirq_setup); | |||
849 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; | 855 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; |
850 | 856 | ||
851 | /* | 857 | /* |
852 | * Saves and masks all the unmasked IO-APIC RTE's | 858 | * Saves all the IO-APIC RTE's |
853 | */ | 859 | */ |
854 | int save_mask_IO_APIC_setup(void) | 860 | int save_IO_APIC_setup(void) |
855 | { | 861 | { |
856 | union IO_APIC_reg_01 reg_01; | 862 | union IO_APIC_reg_01 reg_01; |
857 | unsigned long flags; | 863 | unsigned long flags; |
@@ -876,16 +882,9 @@ int save_mask_IO_APIC_setup(void) | |||
876 | } | 882 | } |
877 | 883 | ||
878 | for (apic = 0; apic < nr_ioapics; apic++) | 884 | for (apic = 0; apic < nr_ioapics; apic++) |
879 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 885 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) |
880 | struct IO_APIC_route_entry entry; | 886 | early_ioapic_entries[apic][pin] = |
881 | |||
882 | entry = early_ioapic_entries[apic][pin] = | ||
883 | ioapic_read_entry(apic, pin); | 887 | ioapic_read_entry(apic, pin); |
884 | if (!entry.mask) { | ||
885 | entry.mask = 1; | ||
886 | ioapic_write_entry(apic, pin, entry); | ||
887 | } | ||
888 | } | ||
889 | 888 | ||
890 | return 0; | 889 | return 0; |
891 | 890 | ||
@@ -898,6 +897,25 @@ nomem: | |||
898 | return -ENOMEM; | 897 | return -ENOMEM; |
899 | } | 898 | } |
900 | 899 | ||
900 | void mask_IO_APIC_setup(void) | ||
901 | { | ||
902 | int apic, pin; | ||
903 | |||
904 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
905 | if (!early_ioapic_entries[apic]) | ||
906 | break; | ||
907 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | ||
908 | struct IO_APIC_route_entry entry; | ||
909 | |||
910 | entry = early_ioapic_entries[apic][pin]; | ||
911 | if (!entry.mask) { | ||
912 | entry.mask = 1; | ||
913 | ioapic_write_entry(apic, pin, entry); | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | } | ||
918 | |||
901 | void restore_IO_APIC_setup(void) | 919 | void restore_IO_APIC_setup(void) |
902 | { | 920 | { |
903 | int apic, pin; | 921 | int apic, pin; |
@@ -1411,9 +1429,7 @@ void __setup_vector_irq(int cpu) | |||
1411 | } | 1429 | } |
1412 | 1430 | ||
1413 | static struct irq_chip ioapic_chip; | 1431 | static struct irq_chip ioapic_chip; |
1414 | #ifdef CONFIG_INTR_REMAP | ||
1415 | static struct irq_chip ir_ioapic_chip; | 1432 | static struct irq_chip ir_ioapic_chip; |
1416 | #endif | ||
1417 | 1433 | ||
1418 | #define IOAPIC_AUTO -1 | 1434 | #define IOAPIC_AUTO -1 |
1419 | #define IOAPIC_EDGE 0 | 1435 | #define IOAPIC_EDGE 0 |
@@ -1452,7 +1468,6 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t | |||
1452 | else | 1468 | else |
1453 | desc->status &= ~IRQ_LEVEL; | 1469 | desc->status &= ~IRQ_LEVEL; |
1454 | 1470 | ||
1455 | #ifdef CONFIG_INTR_REMAP | ||
1456 | if (irq_remapped(irq)) { | 1471 | if (irq_remapped(irq)) { |
1457 | desc->status |= IRQ_MOVE_PCNTXT; | 1472 | desc->status |= IRQ_MOVE_PCNTXT; |
1458 | if (trigger) | 1473 | if (trigger) |
@@ -1464,7 +1479,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t | |||
1464 | handle_edge_irq, "edge"); | 1479 | handle_edge_irq, "edge"); |
1465 | return; | 1480 | return; |
1466 | } | 1481 | } |
1467 | #endif | 1482 | |
1468 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1483 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1469 | trigger == IOAPIC_LEVEL) | 1484 | trigger == IOAPIC_LEVEL) |
1470 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1485 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
@@ -1478,14 +1493,13 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t | |||
1478 | int setup_ioapic_entry(int apic_id, int irq, | 1493 | int setup_ioapic_entry(int apic_id, int irq, |
1479 | struct IO_APIC_route_entry *entry, | 1494 | struct IO_APIC_route_entry *entry, |
1480 | unsigned int destination, int trigger, | 1495 | unsigned int destination, int trigger, |
1481 | int polarity, int vector) | 1496 | int polarity, int vector, int pin) |
1482 | { | 1497 | { |
1483 | /* | 1498 | /* |
1484 | * add it to the IO-APIC irq-routing table: | 1499 | * add it to the IO-APIC irq-routing table: |
1485 | */ | 1500 | */ |
1486 | memset(entry,0,sizeof(*entry)); | 1501 | memset(entry,0,sizeof(*entry)); |
1487 | 1502 | ||
1488 | #ifdef CONFIG_INTR_REMAP | ||
1489 | if (intr_remapping_enabled) { | 1503 | if (intr_remapping_enabled) { |
1490 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); | 1504 | struct intel_iommu *iommu = map_ioapic_to_ir(apic_id); |
1491 | struct irte irte; | 1505 | struct irte irte; |
@@ -1504,7 +1518,14 @@ int setup_ioapic_entry(int apic_id, int irq, | |||
1504 | 1518 | ||
1505 | irte.present = 1; | 1519 | irte.present = 1; |
1506 | irte.dst_mode = apic->irq_dest_mode; | 1520 | irte.dst_mode = apic->irq_dest_mode; |
1507 | irte.trigger_mode = trigger; | 1521 | /* |
1522 | * Trigger mode in the IRTE will always be edge, and the | ||
1523 | * actual level or edge trigger will be setup in the IO-APIC | ||
1524 | * RTE. This will help simplify level triggered irq migration. | ||
1525 | * For more details, see the comments above explainig IO-APIC | ||
1526 | * irq migration in the presence of interrupt-remapping. | ||
1527 | */ | ||
1528 | irte.trigger_mode = 0; | ||
1508 | irte.dlvry_mode = apic->irq_delivery_mode; | 1529 | irte.dlvry_mode = apic->irq_delivery_mode; |
1509 | irte.vector = vector; | 1530 | irte.vector = vector; |
1510 | irte.dest_id = IRTE_DEST(destination); | 1531 | irte.dest_id = IRTE_DEST(destination); |
@@ -1515,18 +1536,21 @@ int setup_ioapic_entry(int apic_id, int irq, | |||
1515 | ir_entry->zero = 0; | 1536 | ir_entry->zero = 0; |
1516 | ir_entry->format = 1; | 1537 | ir_entry->format = 1; |
1517 | ir_entry->index = (index & 0x7fff); | 1538 | ir_entry->index = (index & 0x7fff); |
1518 | } else | 1539 | /* |
1519 | #endif | 1540 | * IO-APIC RTE will be configured with virtual vector. |
1520 | { | 1541 | * irq handler will do the explicit EOI to the io-apic. |
1542 | */ | ||
1543 | ir_entry->vector = pin; | ||
1544 | } else { | ||
1521 | entry->delivery_mode = apic->irq_delivery_mode; | 1545 | entry->delivery_mode = apic->irq_delivery_mode; |
1522 | entry->dest_mode = apic->irq_dest_mode; | 1546 | entry->dest_mode = apic->irq_dest_mode; |
1523 | entry->dest = destination; | 1547 | entry->dest = destination; |
1548 | entry->vector = vector; | ||
1524 | } | 1549 | } |
1525 | 1550 | ||
1526 | entry->mask = 0; /* enable IRQ */ | 1551 | entry->mask = 0; /* enable IRQ */ |
1527 | entry->trigger = trigger; | 1552 | entry->trigger = trigger; |
1528 | entry->polarity = polarity; | 1553 | entry->polarity = polarity; |
1529 | entry->vector = vector; | ||
1530 | 1554 | ||
1531 | /* Mask level triggered irqs. | 1555 | /* Mask level triggered irqs. |
1532 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. | 1556 | * Use IRQ_DELAYED_DISABLE for edge triggered irqs. |
@@ -1561,7 +1585,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq | |||
1561 | 1585 | ||
1562 | 1586 | ||
1563 | if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, | 1587 | if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, |
1564 | dest, trigger, polarity, cfg->vector)) { | 1588 | dest, trigger, polarity, cfg->vector, pin)) { |
1565 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", | 1589 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", |
1566 | mp_ioapics[apic_id].apicid, pin); | 1590 | mp_ioapics[apic_id].apicid, pin); |
1567 | __clear_irq_vector(irq, cfg); | 1591 | __clear_irq_vector(irq, cfg); |
@@ -1642,10 +1666,8 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | |||
1642 | { | 1666 | { |
1643 | struct IO_APIC_route_entry entry; | 1667 | struct IO_APIC_route_entry entry; |
1644 | 1668 | ||
1645 | #ifdef CONFIG_INTR_REMAP | ||
1646 | if (intr_remapping_enabled) | 1669 | if (intr_remapping_enabled) |
1647 | return; | 1670 | return; |
1648 | #endif | ||
1649 | 1671 | ||
1650 | memset(&entry, 0, sizeof(entry)); | 1672 | memset(&entry, 0, sizeof(entry)); |
1651 | 1673 | ||
@@ -2040,8 +2062,13 @@ void disable_IO_APIC(void) | |||
2040 | * If the i8259 is routed through an IOAPIC | 2062 | * If the i8259 is routed through an IOAPIC |
2041 | * Put that IOAPIC in virtual wire mode | 2063 | * Put that IOAPIC in virtual wire mode |
2042 | * so legacy interrupts can be delivered. | 2064 | * so legacy interrupts can be delivered. |
2065 | * | ||
2066 | * With interrupt-remapping, for now we will use virtual wire A mode, | ||
2067 | * as virtual wire B is little complex (need to configure both | ||
2068 | * IOAPIC RTE aswell as interrupt-remapping table entry). | ||
2069 | * As this gets called during crash dump, keep this simple for now. | ||
2043 | */ | 2070 | */ |
2044 | if (ioapic_i8259.pin != -1) { | 2071 | if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) { |
2045 | struct IO_APIC_route_entry entry; | 2072 | struct IO_APIC_route_entry entry; |
2046 | 2073 | ||
2047 | memset(&entry, 0, sizeof(entry)); | 2074 | memset(&entry, 0, sizeof(entry)); |
@@ -2061,7 +2088,10 @@ void disable_IO_APIC(void) | |||
2061 | ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); | 2088 | ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); |
2062 | } | 2089 | } |
2063 | 2090 | ||
2064 | disconnect_bsp_APIC(ioapic_i8259.pin != -1); | 2091 | /* |
2092 | * Use virtual wire A mode when interrupt remapping is enabled. | ||
2093 | */ | ||
2094 | disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1); | ||
2065 | } | 2095 | } |
2066 | 2096 | ||
2067 | #ifdef CONFIG_X86_32 | 2097 | #ifdef CONFIG_X86_32 |
@@ -2303,37 +2333,24 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
2303 | #ifdef CONFIG_SMP | 2333 | #ifdef CONFIG_SMP |
2304 | 2334 | ||
2305 | #ifdef CONFIG_INTR_REMAP | 2335 | #ifdef CONFIG_INTR_REMAP |
2306 | static void ir_irq_migration(struct work_struct *work); | ||
2307 | |||
2308 | static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration); | ||
2309 | 2336 | ||
2310 | /* | 2337 | /* |
2311 | * Migrate the IO-APIC irq in the presence of intr-remapping. | 2338 | * Migrate the IO-APIC irq in the presence of intr-remapping. |
2312 | * | 2339 | * |
2313 | * For edge triggered, irq migration is a simple atomic update(of vector | 2340 | * For both level and edge triggered, irq migration is a simple atomic |
2314 | * and cpu destination) of IRTE and flush the hardware cache. | 2341 | * update(of vector and cpu destination) of IRTE and flush the hardware cache. |
2315 | * | ||
2316 | * For level triggered, we need to modify the io-apic RTE aswell with the update | ||
2317 | * vector information, along with modifying IRTE with vector and destination. | ||
2318 | * So irq migration for level triggered is little bit more complex compared to | ||
2319 | * edge triggered migration. But the good news is, we use the same algorithm | ||
2320 | * for level triggered migration as we have today, only difference being, | ||
2321 | * we now initiate the irq migration from process context instead of the | ||
2322 | * interrupt context. | ||
2323 | * | 2342 | * |
2324 | * In future, when we do a directed EOI (combined with cpu EOI broadcast | 2343 | * For level triggered, we eliminate the io-apic RTE modification (with the |
2325 | * suppression) to the IO-APIC, level triggered irq migration will also be | 2344 | * updated vector information), by using a virtual vector (io-apic pin number). |
2326 | * as simple as edge triggered migration and we can do the irq migration | 2345 | * Real vector that is used for interrupting cpu will be coming from |
2327 | * with a simple atomic update to IO-APIC RTE. | 2346 | * the interrupt-remapping table entry. |
2328 | */ | 2347 | */ |
2329 | static void | 2348 | static void |
2330 | migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | 2349 | migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) |
2331 | { | 2350 | { |
2332 | struct irq_cfg *cfg; | 2351 | struct irq_cfg *cfg; |
2333 | struct irte irte; | 2352 | struct irte irte; |
2334 | int modify_ioapic_rte; | ||
2335 | unsigned int dest; | 2353 | unsigned int dest; |
2336 | unsigned long flags; | ||
2337 | unsigned int irq; | 2354 | unsigned int irq; |
2338 | 2355 | ||
2339 | if (!cpumask_intersects(mask, cpu_online_mask)) | 2356 | if (!cpumask_intersects(mask, cpu_online_mask)) |
@@ -2351,13 +2368,6 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | |||
2351 | 2368 | ||
2352 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); | 2369 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); |
2353 | 2370 | ||
2354 | modify_ioapic_rte = desc->status & IRQ_LEVEL; | ||
2355 | if (modify_ioapic_rte) { | ||
2356 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2357 | __target_IO_APIC_irq(irq, dest, cfg); | ||
2358 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2359 | } | ||
2360 | |||
2361 | irte.vector = cfg->vector; | 2371 | irte.vector = cfg->vector; |
2362 | irte.dest_id = IRTE_DEST(dest); | 2372 | irte.dest_id = IRTE_DEST(dest); |
2363 | 2373 | ||
@@ -2372,73 +2382,12 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | |||
2372 | cpumask_copy(desc->affinity, mask); | 2382 | cpumask_copy(desc->affinity, mask); |
2373 | } | 2383 | } |
2374 | 2384 | ||
2375 | static int migrate_irq_remapped_level_desc(struct irq_desc *desc) | ||
2376 | { | ||
2377 | int ret = -1; | ||
2378 | struct irq_cfg *cfg = desc->chip_data; | ||
2379 | |||
2380 | mask_IO_APIC_irq_desc(desc); | ||
2381 | |||
2382 | if (io_apic_level_ack_pending(cfg)) { | ||
2383 | /* | ||
2384 | * Interrupt in progress. Migrating irq now will change the | ||
2385 | * vector information in the IO-APIC RTE and that will confuse | ||
2386 | * the EOI broadcast performed by cpu. | ||
2387 | * So, delay the irq migration to the next instance. | ||
2388 | */ | ||
2389 | schedule_delayed_work(&ir_migration_work, 1); | ||
2390 | goto unmask; | ||
2391 | } | ||
2392 | |||
2393 | /* everthing is clear. we have right of way */ | ||
2394 | migrate_ioapic_irq_desc(desc, desc->pending_mask); | ||
2395 | |||
2396 | ret = 0; | ||
2397 | desc->status &= ~IRQ_MOVE_PENDING; | ||
2398 | cpumask_clear(desc->pending_mask); | ||
2399 | |||
2400 | unmask: | ||
2401 | unmask_IO_APIC_irq_desc(desc); | ||
2402 | |||
2403 | return ret; | ||
2404 | } | ||
2405 | |||
2406 | static void ir_irq_migration(struct work_struct *work) | ||
2407 | { | ||
2408 | unsigned int irq; | ||
2409 | struct irq_desc *desc; | ||
2410 | |||
2411 | for_each_irq_desc(irq, desc) { | ||
2412 | if (desc->status & IRQ_MOVE_PENDING) { | ||
2413 | unsigned long flags; | ||
2414 | |||
2415 | spin_lock_irqsave(&desc->lock, flags); | ||
2416 | if (!desc->chip->set_affinity || | ||
2417 | !(desc->status & IRQ_MOVE_PENDING)) { | ||
2418 | desc->status &= ~IRQ_MOVE_PENDING; | ||
2419 | spin_unlock_irqrestore(&desc->lock, flags); | ||
2420 | continue; | ||
2421 | } | ||
2422 | |||
2423 | desc->chip->set_affinity(irq, desc->pending_mask); | ||
2424 | spin_unlock_irqrestore(&desc->lock, flags); | ||
2425 | } | ||
2426 | } | ||
2427 | } | ||
2428 | |||
2429 | /* | 2385 | /* |
2430 | * Migrates the IRQ destination in the process context. | 2386 | * Migrates the IRQ destination in the process context. |
2431 | */ | 2387 | */ |
2432 | static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, | 2388 | static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, |
2433 | const struct cpumask *mask) | 2389 | const struct cpumask *mask) |
2434 | { | 2390 | { |
2435 | if (desc->status & IRQ_LEVEL) { | ||
2436 | desc->status |= IRQ_MOVE_PENDING; | ||
2437 | cpumask_copy(desc->pending_mask, mask); | ||
2438 | migrate_irq_remapped_level_desc(desc); | ||
2439 | return; | ||
2440 | } | ||
2441 | |||
2442 | migrate_ioapic_irq_desc(desc, mask); | 2391 | migrate_ioapic_irq_desc(desc, mask); |
2443 | } | 2392 | } |
2444 | static void set_ir_ioapic_affinity_irq(unsigned int irq, | 2393 | static void set_ir_ioapic_affinity_irq(unsigned int irq, |
@@ -2448,6 +2397,11 @@ static void set_ir_ioapic_affinity_irq(unsigned int irq, | |||
2448 | 2397 | ||
2449 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 2398 | set_ir_ioapic_affinity_irq_desc(desc, mask); |
2450 | } | 2399 | } |
2400 | #else | ||
2401 | static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc, | ||
2402 | const struct cpumask *mask) | ||
2403 | { | ||
2404 | } | ||
2451 | #endif | 2405 | #endif |
2452 | 2406 | ||
2453 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2407 | asmlinkage void smp_irq_move_cleanup_interrupt(void) |
@@ -2461,6 +2415,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
2461 | me = smp_processor_id(); | 2415 | me = smp_processor_id(); |
2462 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { | 2416 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) { |
2463 | unsigned int irq; | 2417 | unsigned int irq; |
2418 | unsigned int irr; | ||
2464 | struct irq_desc *desc; | 2419 | struct irq_desc *desc; |
2465 | struct irq_cfg *cfg; | 2420 | struct irq_cfg *cfg; |
2466 | irq = __get_cpu_var(vector_irq)[vector]; | 2421 | irq = __get_cpu_var(vector_irq)[vector]; |
@@ -2480,6 +2435,18 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
2480 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) | 2435 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) |
2481 | goto unlock; | 2436 | goto unlock; |
2482 | 2437 | ||
2438 | irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); | ||
2439 | /* | ||
2440 | * Check if the vector that needs to be cleanedup is | ||
2441 | * registered at the cpu's IRR. If so, then this is not | ||
2442 | * the best time to clean it up. Lets clean it up in the | ||
2443 | * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR | ||
2444 | * to myself. | ||
2445 | */ | ||
2446 | if (irr & (1 << (vector % 32))) { | ||
2447 | apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); | ||
2448 | goto unlock; | ||
2449 | } | ||
2483 | __get_cpu_var(vector_irq)[vector] = -1; | 2450 | __get_cpu_var(vector_irq)[vector] = -1; |
2484 | cfg->move_cleanup_count--; | 2451 | cfg->move_cleanup_count--; |
2485 | unlock: | 2452 | unlock: |
@@ -2529,9 +2496,44 @@ static inline void irq_complete_move(struct irq_desc **descp) {} | |||
2529 | #endif | 2496 | #endif |
2530 | 2497 | ||
2531 | #ifdef CONFIG_INTR_REMAP | 2498 | #ifdef CONFIG_INTR_REMAP |
2499 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | ||
2500 | { | ||
2501 | int apic, pin; | ||
2502 | struct irq_pin_list *entry; | ||
2503 | |||
2504 | entry = cfg->irq_2_pin; | ||
2505 | for (;;) { | ||
2506 | |||
2507 | if (!entry) | ||
2508 | break; | ||
2509 | |||
2510 | apic = entry->apic; | ||
2511 | pin = entry->pin; | ||
2512 | io_apic_eoi(apic, pin); | ||
2513 | entry = entry->next; | ||
2514 | } | ||
2515 | } | ||
2516 | |||
2517 | static void | ||
2518 | eoi_ioapic_irq(struct irq_desc *desc) | ||
2519 | { | ||
2520 | struct irq_cfg *cfg; | ||
2521 | unsigned long flags; | ||
2522 | unsigned int irq; | ||
2523 | |||
2524 | irq = desc->irq; | ||
2525 | cfg = desc->chip_data; | ||
2526 | |||
2527 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2528 | __eoi_ioapic_irq(irq, cfg); | ||
2529 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2530 | } | ||
2531 | |||
2532 | static void ack_x2apic_level(unsigned int irq) | 2532 | static void ack_x2apic_level(unsigned int irq) |
2533 | { | 2533 | { |
2534 | struct irq_desc *desc = irq_to_desc(irq); | ||
2534 | ack_x2APIC_irq(); | 2535 | ack_x2APIC_irq(); |
2536 | eoi_ioapic_irq(desc); | ||
2535 | } | 2537 | } |
2536 | 2538 | ||
2537 | static void ack_x2apic_edge(unsigned int irq) | 2539 | static void ack_x2apic_edge(unsigned int irq) |
@@ -2662,20 +2664,20 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
2662 | .retrigger = ioapic_retrigger_irq, | 2664 | .retrigger = ioapic_retrigger_irq, |
2663 | }; | 2665 | }; |
2664 | 2666 | ||
2665 | #ifdef CONFIG_INTR_REMAP | ||
2666 | static struct irq_chip ir_ioapic_chip __read_mostly = { | 2667 | static struct irq_chip ir_ioapic_chip __read_mostly = { |
2667 | .name = "IR-IO-APIC", | 2668 | .name = "IR-IO-APIC", |
2668 | .startup = startup_ioapic_irq, | 2669 | .startup = startup_ioapic_irq, |
2669 | .mask = mask_IO_APIC_irq, | 2670 | .mask = mask_IO_APIC_irq, |
2670 | .unmask = unmask_IO_APIC_irq, | 2671 | .unmask = unmask_IO_APIC_irq, |
2672 | #ifdef CONFIG_INTR_REMAP | ||
2671 | .ack = ack_x2apic_edge, | 2673 | .ack = ack_x2apic_edge, |
2672 | .eoi = ack_x2apic_level, | 2674 | .eoi = ack_x2apic_level, |
2673 | #ifdef CONFIG_SMP | 2675 | #ifdef CONFIG_SMP |
2674 | .set_affinity = set_ir_ioapic_affinity_irq, | 2676 | .set_affinity = set_ir_ioapic_affinity_irq, |
2675 | #endif | 2677 | #endif |
2678 | #endif | ||
2676 | .retrigger = ioapic_retrigger_irq, | 2679 | .retrigger = ioapic_retrigger_irq, |
2677 | }; | 2680 | }; |
2678 | #endif | ||
2679 | 2681 | ||
2680 | static inline void init_IO_APIC_traps(void) | 2682 | static inline void init_IO_APIC_traps(void) |
2681 | { | 2683 | { |
@@ -2901,10 +2903,8 @@ static inline void __init check_timer(void) | |||
2901 | * 8259A. | 2903 | * 8259A. |
2902 | */ | 2904 | */ |
2903 | if (pin1 == -1) { | 2905 | if (pin1 == -1) { |
2904 | #ifdef CONFIG_INTR_REMAP | ||
2905 | if (intr_remapping_enabled) | 2906 | if (intr_remapping_enabled) |
2906 | panic("BIOS bug: timer not connected to IO-APIC"); | 2907 | panic("BIOS bug: timer not connected to IO-APIC"); |
2907 | #endif | ||
2908 | pin1 = pin2; | 2908 | pin1 = pin2; |
2909 | apic1 = apic2; | 2909 | apic1 = apic2; |
2910 | no_pin1 = 1; | 2910 | no_pin1 = 1; |
@@ -2940,10 +2940,8 @@ static inline void __init check_timer(void) | |||
2940 | clear_IO_APIC_pin(0, pin1); | 2940 | clear_IO_APIC_pin(0, pin1); |
2941 | goto out; | 2941 | goto out; |
2942 | } | 2942 | } |
2943 | #ifdef CONFIG_INTR_REMAP | ||
2944 | if (intr_remapping_enabled) | 2943 | if (intr_remapping_enabled) |
2945 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); | 2944 | panic("timer doesn't work through Interrupt-remapped IO-APIC"); |
2946 | #endif | ||
2947 | local_irq_disable(); | 2945 | local_irq_disable(); |
2948 | clear_IO_APIC_pin(apic1, pin1); | 2946 | clear_IO_APIC_pin(apic1, pin1); |
2949 | if (!no_pin1) | 2947 | if (!no_pin1) |
@@ -3237,9 +3235,7 @@ void destroy_irq(unsigned int irq) | |||
3237 | if (desc) | 3235 | if (desc) |
3238 | desc->chip_data = cfg; | 3236 | desc->chip_data = cfg; |
3239 | 3237 | ||
3240 | #ifdef CONFIG_INTR_REMAP | ||
3241 | free_irte(irq); | 3238 | free_irte(irq); |
3242 | #endif | ||
3243 | spin_lock_irqsave(&vector_lock, flags); | 3239 | spin_lock_irqsave(&vector_lock, flags); |
3244 | __clear_irq_vector(irq, cfg); | 3240 | __clear_irq_vector(irq, cfg); |
3245 | spin_unlock_irqrestore(&vector_lock, flags); | 3241 | spin_unlock_irqrestore(&vector_lock, flags); |
@@ -3265,7 +3261,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3265 | 3261 | ||
3266 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3262 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); |
3267 | 3263 | ||
3268 | #ifdef CONFIG_INTR_REMAP | ||
3269 | if (irq_remapped(irq)) { | 3264 | if (irq_remapped(irq)) { |
3270 | struct irte irte; | 3265 | struct irte irte; |
3271 | int ir_index; | 3266 | int ir_index; |
@@ -3291,10 +3286,13 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms | |||
3291 | MSI_ADDR_IR_SHV | | 3286 | MSI_ADDR_IR_SHV | |
3292 | MSI_ADDR_IR_INDEX1(ir_index) | | 3287 | MSI_ADDR_IR_INDEX1(ir_index) | |
3293 | MSI_ADDR_IR_INDEX2(ir_index); | 3288 | MSI_ADDR_IR_INDEX2(ir_index); |
3294 | } else | 3289 | } else { |
3295 | #endif | 3290 | if (x2apic_enabled()) |
3296 | { | 3291 | msg->address_hi = MSI_ADDR_BASE_HI | |
3297 | msg->address_hi = MSI_ADDR_BASE_HI; | 3292 | MSI_ADDR_EXT_DEST_ID(dest); |
3293 | else | ||
3294 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
3295 | |||
3298 | msg->address_lo = | 3296 | msg->address_lo = |
3299 | MSI_ADDR_BASE_LO | | 3297 | MSI_ADDR_BASE_LO | |
3300 | ((apic->irq_dest_mode == 0) ? | 3298 | ((apic->irq_dest_mode == 0) ? |
@@ -3394,15 +3392,16 @@ static struct irq_chip msi_chip = { | |||
3394 | .retrigger = ioapic_retrigger_irq, | 3392 | .retrigger = ioapic_retrigger_irq, |
3395 | }; | 3393 | }; |
3396 | 3394 | ||
3397 | #ifdef CONFIG_INTR_REMAP | ||
3398 | static struct irq_chip msi_ir_chip = { | 3395 | static struct irq_chip msi_ir_chip = { |
3399 | .name = "IR-PCI-MSI", | 3396 | .name = "IR-PCI-MSI", |
3400 | .unmask = unmask_msi_irq, | 3397 | .unmask = unmask_msi_irq, |
3401 | .mask = mask_msi_irq, | 3398 | .mask = mask_msi_irq, |
3399 | #ifdef CONFIG_INTR_REMAP | ||
3402 | .ack = ack_x2apic_edge, | 3400 | .ack = ack_x2apic_edge, |
3403 | #ifdef CONFIG_SMP | 3401 | #ifdef CONFIG_SMP |
3404 | .set_affinity = ir_set_msi_irq_affinity, | 3402 | .set_affinity = ir_set_msi_irq_affinity, |
3405 | #endif | 3403 | #endif |
3404 | #endif | ||
3406 | .retrigger = ioapic_retrigger_irq, | 3405 | .retrigger = ioapic_retrigger_irq, |
3407 | }; | 3406 | }; |
3408 | 3407 | ||
@@ -3432,7 +3431,6 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec) | |||
3432 | } | 3431 | } |
3433 | return index; | 3432 | return index; |
3434 | } | 3433 | } |
3435 | #endif | ||
3436 | 3434 | ||
3437 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | 3435 | static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) |
3438 | { | 3436 | { |
@@ -3446,7 +3444,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | |||
3446 | set_irq_msi(irq, msidesc); | 3444 | set_irq_msi(irq, msidesc); |
3447 | write_msi_msg(irq, &msg); | 3445 | write_msi_msg(irq, &msg); |
3448 | 3446 | ||
3449 | #ifdef CONFIG_INTR_REMAP | ||
3450 | if (irq_remapped(irq)) { | 3447 | if (irq_remapped(irq)) { |
3451 | struct irq_desc *desc = irq_to_desc(irq); | 3448 | struct irq_desc *desc = irq_to_desc(irq); |
3452 | /* | 3449 | /* |
@@ -3455,7 +3452,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq) | |||
3455 | desc->status |= IRQ_MOVE_PCNTXT; | 3452 | desc->status |= IRQ_MOVE_PCNTXT; |
3456 | set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); | 3453 | set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge"); |
3457 | } else | 3454 | } else |
3458 | #endif | ||
3459 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); | 3455 | set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); |
3460 | 3456 | ||
3461 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); | 3457 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq); |
@@ -3469,11 +3465,12 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3469 | int ret, sub_handle; | 3465 | int ret, sub_handle; |
3470 | struct msi_desc *msidesc; | 3466 | struct msi_desc *msidesc; |
3471 | unsigned int irq_want; | 3467 | unsigned int irq_want; |
3472 | 3468 | struct intel_iommu *iommu = NULL; | |
3473 | #ifdef CONFIG_INTR_REMAP | ||
3474 | struct intel_iommu *iommu = 0; | ||
3475 | int index = 0; | 3469 | int index = 0; |
3476 | #endif | 3470 | |
3471 | /* x86 doesn't support multiple MSI yet */ | ||
3472 | if (type == PCI_CAP_ID_MSI && nvec > 1) | ||
3473 | return 1; | ||
3477 | 3474 | ||
3478 | irq_want = nr_irqs_gsi; | 3475 | irq_want = nr_irqs_gsi; |
3479 | sub_handle = 0; | 3476 | sub_handle = 0; |
@@ -3482,7 +3479,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3482 | if (irq == 0) | 3479 | if (irq == 0) |
3483 | return -1; | 3480 | return -1; |
3484 | irq_want = irq + 1; | 3481 | irq_want = irq + 1; |
3485 | #ifdef CONFIG_INTR_REMAP | ||
3486 | if (!intr_remapping_enabled) | 3482 | if (!intr_remapping_enabled) |
3487 | goto no_ir; | 3483 | goto no_ir; |
3488 | 3484 | ||
@@ -3510,7 +3506,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3510 | set_irte_irq(irq, iommu, index, sub_handle); | 3506 | set_irte_irq(irq, iommu, index, sub_handle); |
3511 | } | 3507 | } |
3512 | no_ir: | 3508 | no_ir: |
3513 | #endif | ||
3514 | ret = setup_msi_irq(dev, msidesc, irq); | 3509 | ret = setup_msi_irq(dev, msidesc, irq); |
3515 | if (ret < 0) | 3510 | if (ret < 0) |
3516 | goto error; | 3511 | goto error; |
@@ -3528,7 +3523,7 @@ void arch_teardown_msi_irq(unsigned int irq) | |||
3528 | destroy_irq(irq); | 3523 | destroy_irq(irq); |
3529 | } | 3524 | } |
3530 | 3525 | ||
3531 | #ifdef CONFIG_DMAR | 3526 | #if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP) |
3532 | #ifdef CONFIG_SMP | 3527 | #ifdef CONFIG_SMP |
3533 | static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | 3528 | static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask) |
3534 | { | 3529 | { |
@@ -3609,7 +3604,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask) | |||
3609 | 3604 | ||
3610 | #endif /* CONFIG_SMP */ | 3605 | #endif /* CONFIG_SMP */ |
3611 | 3606 | ||
3612 | struct irq_chip hpet_msi_type = { | 3607 | static struct irq_chip hpet_msi_type = { |
3613 | .name = "HPET_MSI", | 3608 | .name = "HPET_MSI", |
3614 | .unmask = hpet_msi_unmask, | 3609 | .unmask = hpet_msi_unmask, |
3615 | .mask = hpet_msi_mask, | 3610 | .mask = hpet_msi_mask, |
@@ -4045,11 +4040,9 @@ void __init setup_ioapic_dest(void) | |||
4045 | else | 4040 | else |
4046 | mask = apic->target_cpus(); | 4041 | mask = apic->target_cpus(); |
4047 | 4042 | ||
4048 | #ifdef CONFIG_INTR_REMAP | ||
4049 | if (intr_remapping_enabled) | 4043 | if (intr_remapping_enabled) |
4050 | set_ir_ioapic_affinity_irq_desc(desc, mask); | 4044 | set_ir_ioapic_affinity_irq_desc(desc, mask); |
4051 | else | 4045 | else |
4052 | #endif | ||
4053 | set_ioapic_affinity_irq_desc(desc, mask); | 4046 | set_ioapic_affinity_irq_desc(desc, mask); |
4054 | } | 4047 | } |
4055 | 4048 | ||
@@ -4142,9 +4135,12 @@ static int __init ioapic_insert_resources(void) | |||
4142 | struct resource *r = ioapic_resources; | 4135 | struct resource *r = ioapic_resources; |
4143 | 4136 | ||
4144 | if (!r) { | 4137 | if (!r) { |
4145 | printk(KERN_ERR | 4138 | if (nr_ioapics > 0) { |
4146 | "IO APIC resources could be not be allocated.\n"); | 4139 | printk(KERN_ERR |
4147 | return -1; | 4140 | "IO APIC resources couldn't be allocated.\n"); |
4141 | return -1; | ||
4142 | } | ||
4143 | return 0; | ||
4148 | } | 4144 | } |
4149 | 4145 | ||
4150 | for (i = 0; i < nr_ioapics; i++) { | 4146 | for (i = 0; i < nr_ioapics; i++) { |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index bdfad80c3cf1..d6bd62407152 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
@@ -39,7 +39,7 @@ | |||
39 | int unknown_nmi_panic; | 39 | int unknown_nmi_panic; |
40 | int nmi_watchdog_enabled; | 40 | int nmi_watchdog_enabled; |
41 | 41 | ||
42 | static cpumask_t backtrace_mask = CPU_MASK_NONE; | 42 | static cpumask_var_t backtrace_mask; |
43 | 43 | ||
44 | /* nmi_active: | 44 | /* nmi_active: |
45 | * >0: the lapic NMI watchdog is active, but can be disabled | 45 | * >0: the lapic NMI watchdog is active, but can be disabled |
@@ -138,6 +138,7 @@ int __init check_nmi_watchdog(void) | |||
138 | if (!prev_nmi_count) | 138 | if (!prev_nmi_count) |
139 | goto error; | 139 | goto error; |
140 | 140 | ||
141 | alloc_cpumask_var(&backtrace_mask, GFP_KERNEL); | ||
141 | printk(KERN_INFO "Testing NMI watchdog ... "); | 142 | printk(KERN_INFO "Testing NMI watchdog ... "); |
142 | 143 | ||
143 | #ifdef CONFIG_SMP | 144 | #ifdef CONFIG_SMP |
@@ -413,14 +414,14 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | |||
413 | touched = 1; | 414 | touched = 1; |
414 | } | 415 | } |
415 | 416 | ||
416 | if (cpu_isset(cpu, backtrace_mask)) { | 417 | if (cpumask_test_cpu(cpu, backtrace_mask)) { |
417 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ | 418 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ |
418 | 419 | ||
419 | spin_lock(&lock); | 420 | spin_lock(&lock); |
420 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | 421 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); |
421 | dump_stack(); | 422 | dump_stack(); |
422 | spin_unlock(&lock); | 423 | spin_unlock(&lock); |
423 | cpu_clear(cpu, backtrace_mask); | 424 | cpumask_clear_cpu(cpu, backtrace_mask); |
424 | } | 425 | } |
425 | 426 | ||
426 | /* Could check oops_in_progress here too, but it's safer not to */ | 427 | /* Could check oops_in_progress here too, but it's safer not to */ |
@@ -554,10 +555,10 @@ void __trigger_all_cpu_backtrace(void) | |||
554 | { | 555 | { |
555 | int i; | 556 | int i; |
556 | 557 | ||
557 | backtrace_mask = cpu_online_map; | 558 | cpumask_copy(backtrace_mask, cpu_online_mask); |
558 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | 559 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ |
559 | for (i = 0; i < 10 * 1000; i++) { | 560 | for (i = 0; i < 10 * 1000; i++) { |
560 | if (cpus_empty(backtrace_mask)) | 561 | if (cpumask_empty(backtrace_mask)) |
561 | break; | 562 | break; |
562 | mdelay(1); | 563 | mdelay(1); |
563 | } | 564 | } |
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index d9d6d61eed82..533e59c6fc82 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) |
@@ -342,9 +334,9 @@ static inline void numaq_smp_callin_clear_local_apic(void) | |||
342 | clear_local_APIC(); | 334 | clear_local_APIC(); |
343 | } | 335 | } |
344 | 336 | ||
345 | static inline const cpumask_t *numaq_target_cpus(void) | 337 | static inline const struct cpumask *numaq_target_cpus(void) |
346 | { | 338 | { |
347 | return &CPU_MASK_ALL; | 339 | return cpu_all_mask; |
348 | } | 340 | } |
349 | 341 | ||
350 | static inline unsigned long | 342 | static inline unsigned long |
@@ -435,7 +427,7 @@ static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid) | |||
435 | * We use physical apicids here, not logical, so just return the default | 427 | * We use physical apicids here, not logical, so just return the default |
436 | * physical broadcast to stop people from breaking us | 428 | * physical broadcast to stop people from breaking us |
437 | */ | 429 | */ |
438 | static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask) | 430 | static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) |
439 | { | 431 | { |
440 | return 0x0F; | 432 | return 0x0F; |
441 | } | 433 | } |
@@ -470,7 +462,7 @@ static int probe_numaq(void) | |||
470 | return found_numaq; | 462 | return found_numaq; |
471 | } | 463 | } |
472 | 464 | ||
473 | static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) | 465 | static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask) |
474 | { | 466 | { |
475 | /* Careful. Some cpus do not strictly honor the set of cpus | 467 | /* Careful. Some cpus do not strictly honor the set of cpus |
476 | * specified in the interrupt destination when using lowest | 468 | * specified in the interrupt destination when using lowest |
@@ -480,7 +472,8 @@ static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
480 | * deliver interrupts to the wrong hyperthread when only one | 472 | * deliver interrupts to the wrong hyperthread when only one |
481 | * hyperthread was specified in the interrupt desitination. | 473 | * hyperthread was specified in the interrupt desitination. |
482 | */ | 474 | */ |
483 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 475 | cpumask_clear(retmask); |
476 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
484 | } | 477 | } |
485 | 478 | ||
486 | static void numaq_setup_portio_remap(void) | 479 | static void numaq_setup_portio_remap(void) |
@@ -546,7 +539,7 @@ struct apic apic_numaq = { | |||
546 | .send_IPI_all = numaq_send_IPI_all, | 539 | .send_IPI_all = numaq_send_IPI_all, |
547 | .send_IPI_self = default_send_IPI_self, | 540 | .send_IPI_self = default_send_IPI_self, |
548 | 541 | ||
549 | .wakeup_cpu = NULL, | 542 | .wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi, |
550 | .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, | 543 | .trampoline_phys_low = NUMAQ_TRAMPOLINE_PHYS_LOW, |
551 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, | 544 | .trampoline_phys_high = NUMAQ_TRAMPOLINE_PHYS_HIGH, |
552 | 545 | ||
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 3a730fa574bb..01eda2ac65e4 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -83,7 +83,8 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) | |||
83 | * deliver interrupts to the wrong hyperthread when only one | 83 | * deliver interrupts to the wrong hyperthread when only one |
84 | * hyperthread was specified in the interrupt desitination. | 84 | * hyperthread was specified in the interrupt desitination. |
85 | */ | 85 | */ |
86 | *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } }; | 86 | cpumask_clear(retmask); |
87 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
87 | } | 88 | } |
88 | 89 | ||
89 | /* should be called last. */ | 90 | /* should be called last. */ |
@@ -138,7 +139,6 @@ struct apic apic_default = { | |||
138 | .send_IPI_all = default_send_IPI_all, | 139 | .send_IPI_all = default_send_IPI_all, |
139 | .send_IPI_self = default_send_IPI_self, | 140 | .send_IPI_self = default_send_IPI_self, |
140 | 141 | ||
141 | .wakeup_cpu = NULL, | ||
142 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 142 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
143 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 143 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
144 | 144 | ||
@@ -159,6 +159,7 @@ extern struct apic apic_numaq; | |||
159 | extern struct apic apic_summit; | 159 | extern struct apic apic_summit; |
160 | extern struct apic apic_bigsmp; | 160 | extern struct apic apic_bigsmp; |
161 | extern struct apic apic_es7000; | 161 | extern struct apic apic_es7000; |
162 | extern struct apic apic_es7000_cluster; | ||
162 | extern struct apic apic_default; | 163 | extern struct apic apic_default; |
163 | 164 | ||
164 | struct apic *apic = &apic_default; | 165 | struct apic *apic = &apic_default; |
@@ -176,6 +177,7 @@ static struct apic *apic_probe[] __initdata = { | |||
176 | #endif | 177 | #endif |
177 | #ifdef CONFIG_X86_ES7000 | 178 | #ifdef CONFIG_X86_ES7000 |
178 | &apic_es7000, | 179 | &apic_es7000, |
180 | &apic_es7000_cluster, | ||
179 | #endif | 181 | #endif |
180 | &apic_default, /* must be last */ | 182 | &apic_default, /* must be last */ |
181 | NULL, | 183 | NULL, |
@@ -197,9 +199,6 @@ static int __init parse_apic(char *arg) | |||
197 | } | 199 | } |
198 | } | 200 | } |
199 | 201 | ||
200 | if (x86_quirks->update_apic) | ||
201 | x86_quirks->update_apic(); | ||
202 | |||
203 | /* Parsed again by __setup for debug/verbose */ | 202 | /* Parsed again by __setup for debug/verbose */ |
204 | return 0; | 203 | return 0; |
205 | } | 204 | } |
@@ -218,8 +217,6 @@ void __init generic_bigsmp_probe(void) | |||
218 | if (!cmdline_apic && apic == &apic_default) { | 217 | if (!cmdline_apic && apic == &apic_default) { |
219 | if (apic_bigsmp.probe()) { | 218 | if (apic_bigsmp.probe()) { |
220 | apic = &apic_bigsmp; | 219 | apic = &apic_bigsmp; |
221 | if (x86_quirks->update_apic) | ||
222 | x86_quirks->update_apic(); | ||
223 | printk(KERN_INFO "Overriding APIC driver with %s\n", | 220 | printk(KERN_INFO "Overriding APIC driver with %s\n", |
224 | apic->name); | 221 | apic->name); |
225 | } | 222 | } |
@@ -240,9 +237,6 @@ void __init generic_apic_probe(void) | |||
240 | /* Not visible without early console */ | 237 | /* Not visible without early console */ |
241 | if (!apic_probe[i]) | 238 | if (!apic_probe[i]) |
242 | panic("Didn't find an APIC driver"); | 239 | panic("Didn't find an APIC driver"); |
243 | |||
244 | if (x86_quirks->update_apic) | ||
245 | x86_quirks->update_apic(); | ||
246 | } | 240 | } |
247 | printk(KERN_INFO "Using APIC driver %s\n", apic->name); | 241 | printk(KERN_INFO "Using APIC driver %s\n", apic->name); |
248 | } | 242 | } |
@@ -262,8 +256,6 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid) | |||
262 | 256 | ||
263 | if (!cmdline_apic) { | 257 | if (!cmdline_apic) { |
264 | apic = apic_probe[i]; | 258 | apic = apic_probe[i]; |
265 | if (x86_quirks->update_apic) | ||
266 | x86_quirks->update_apic(); | ||
267 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", | 259 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", |
268 | apic->name); | 260 | apic->name); |
269 | } | 261 | } |
@@ -284,8 +276,6 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
284 | 276 | ||
285 | if (!cmdline_apic) { | 277 | if (!cmdline_apic) { |
286 | apic = apic_probe[i]; | 278 | apic = apic_probe[i]; |
287 | if (x86_quirks->update_apic) | ||
288 | x86_quirks->update_apic(); | ||
289 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", | 279 | printk(KERN_INFO "Switched to APIC driver `%s'.\n", |
290 | apic->name); | 280 | apic->name); |
291 | } | 281 | } |
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index e7c163661c77..1783652bb0e5 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -69,8 +69,12 @@ void __init default_setup_apic_routing(void) | |||
69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); | 69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); |
70 | } | 70 | } |
71 | 71 | ||
72 | if (x86_quirks->update_apic) | 72 | /* |
73 | x86_quirks->update_apic(); | 73 | * Now that apic routing model is selected, configure the |
74 | * fault handling for intr remapping. | ||
75 | */ | ||
76 | if (intr_remapping_enabled) | ||
77 | enable_drhd_fault_handling(); | ||
74 | } | 78 | } |
75 | 79 | ||
76 | /* Same for both flat and physical. */ | 80 | /* 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 32838b57a945..9cfe1f415d81 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -53,23 +53,19 @@ static unsigned summit_get_apic_id(unsigned long x) | |||
53 | return (x >> 24) & 0xFF; | 53 | return (x >> 24) & 0xFF; |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector) | 56 | static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector) |
57 | { | 57 | { |
58 | default_send_IPI_mask_sequence_logical(mask, vector); | 58 | default_send_IPI_mask_sequence_logical(mask, vector); |
59 | } | 59 | } |
60 | 60 | ||
61 | static 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 | default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector); |
64 | cpu_clear(smp_processor_id(), mask); | ||
65 | |||
66 | if (!cpus_empty(mask)) | ||
67 | summit_send_IPI_mask(&mask, vector); | ||
68 | } | 64 | } |
69 | 65 | ||
70 | static void summit_send_IPI_all(int vector) | 66 | static void summit_send_IPI_all(int vector) |
71 | { | 67 | { |
72 | summit_send_IPI_mask(&cpu_online_map, vector); | 68 | summit_send_IPI_mask(cpu_online_mask, vector); |
73 | } | 69 | } |
74 | 70 | ||
75 | #include <asm/tsc.h> | 71 | #include <asm/tsc.h> |
@@ -77,9 +73,9 @@ static void summit_send_IPI_all(int vector) | |||
77 | extern int use_cyclone; | 73 | extern int use_cyclone; |
78 | 74 | ||
79 | #ifdef CONFIG_X86_SUMMIT_NUMA | 75 | #ifdef CONFIG_X86_SUMMIT_NUMA |
80 | extern void setup_summit(void); | 76 | static void setup_summit(void); |
81 | #else | 77 | #else |
82 | #define setup_summit() {} | 78 | static inline void setup_summit(void) {} |
83 | #endif | 79 | #endif |
84 | 80 | ||
85 | static int summit_mps_oem_check(struct mpc_table *mpc, char *oem, | 81 | static int summit_mps_oem_check(struct mpc_table *mpc, char *oem, |
@@ -186,13 +182,13 @@ static inline int is_WPEG(struct rio_detail *rio){ | |||
186 | 182 | ||
187 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) | 183 | #define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER) |
188 | 184 | ||
189 | static const cpumask_t *summit_target_cpus(void) | 185 | static const struct cpumask *summit_target_cpus(void) |
190 | { | 186 | { |
191 | /* CPU_MASK_ALL (0xff) has undefined behaviour with | 187 | /* CPU_MASK_ALL (0xff) has undefined behaviour with |
192 | * dest_LowestPrio mode logical clustered apic interrupt routing | 188 | * dest_LowestPrio mode logical clustered apic interrupt routing |
193 | * Just start on cpu 0. IRQ balancing will spread load | 189 | * Just start on cpu 0. IRQ balancing will spread load |
194 | */ | 190 | */ |
195 | return &cpumask_of_cpu(0); | 191 | return cpumask_of(0); |
196 | } | 192 | } |
197 | 193 | ||
198 | static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) | 194 | static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) |
@@ -289,35 +285,23 @@ static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid) | |||
289 | return 1; | 285 | return 1; |
290 | } | 286 | } |
291 | 287 | ||
292 | static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask) | 288 | static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) |
293 | { | 289 | { |
294 | int cpus_found = 0; | 290 | unsigned int round = 0; |
295 | int num_bits_set; | 291 | int cpu, apicid = 0; |
296 | int apicid; | ||
297 | int cpu; | ||
298 | 292 | ||
299 | num_bits_set = cpus_weight(*cpumask); | ||
300 | if (num_bits_set >= nr_cpu_ids) | ||
301 | return BAD_APICID; | ||
302 | /* | 293 | /* |
303 | * The cpus in the mask must all be on the apic cluster. | 294 | * The cpus in the mask must all be on the apic cluster. |
304 | */ | 295 | */ |
305 | cpu = first_cpu(*cpumask); | 296 | for_each_cpu(cpu, cpumask) { |
306 | apicid = summit_cpu_to_logical_apicid(cpu); | 297 | int new_apicid = summit_cpu_to_logical_apicid(cpu); |
307 | |||
308 | while (cpus_found < num_bits_set) { | ||
309 | if (cpu_isset(cpu, *cpumask)) { | ||
310 | int new_apicid = summit_cpu_to_logical_apicid(cpu); | ||
311 | 298 | ||
312 | if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 299 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
313 | printk("%s: Not a valid mask!\n", __func__); | 300 | printk("%s: Not a valid mask!\n", __func__); |
314 | 301 | return BAD_APICID; | |
315 | return BAD_APICID; | ||
316 | } | ||
317 | apicid = apicid | new_apicid; | ||
318 | cpus_found++; | ||
319 | } | 302 | } |
320 | cpu++; | 303 | apicid |= new_apicid; |
304 | round++; | ||
321 | } | 305 | } |
322 | return apicid; | 306 | return apicid; |
323 | } | 307 | } |
@@ -358,7 +342,7 @@ static int probe_summit(void) | |||
358 | return 0; | 342 | return 0; |
359 | } | 343 | } |
360 | 344 | ||
361 | static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) | 345 | static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask) |
362 | { | 346 | { |
363 | /* Careful. Some cpus do not strictly honor the set of cpus | 347 | /* Careful. Some cpus do not strictly honor the set of cpus |
364 | * specified in the interrupt destination when using lowest | 348 | * specified in the interrupt destination when using lowest |
@@ -368,19 +352,20 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask) | |||
368 | * deliver interrupts to the wrong hyperthread when only one | 352 | * deliver interrupts to the wrong hyperthread when only one |
369 | * hyperthread was specified in the interrupt desitination. | 353 | * hyperthread was specified in the interrupt desitination. |
370 | */ | 354 | */ |
371 | *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } }; | 355 | cpumask_clear(retmask); |
356 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
372 | } | 357 | } |
373 | 358 | ||
374 | #ifdef CONFIG_X86_SUMMIT_NUMA | 359 | #ifdef CONFIG_X86_SUMMIT_NUMA |
375 | static struct rio_table_hdr *rio_table_hdr __initdata; | 360 | static struct rio_table_hdr *rio_table_hdr; |
376 | static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; | 361 | static struct scal_detail *scal_devs[MAX_NUMNODES]; |
377 | static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; | 362 | static struct rio_detail *rio_devs[MAX_NUMNODES*4]; |
378 | 363 | ||
379 | #ifndef CONFIG_X86_NUMAQ | 364 | #ifndef CONFIG_X86_NUMAQ |
380 | static int mp_bus_id_to_node[MAX_MP_BUSSES] __initdata; | 365 | static int mp_bus_id_to_node[MAX_MP_BUSSES]; |
381 | #endif | 366 | #endif |
382 | 367 | ||
383 | static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | 368 | static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) |
384 | { | 369 | { |
385 | int twister = 0, node = 0; | 370 | int twister = 0, node = 0; |
386 | int i, bus, num_buses; | 371 | int i, bus, num_buses; |
@@ -442,7 +427,7 @@ static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | |||
442 | return bus; | 427 | return bus; |
443 | } | 428 | } |
444 | 429 | ||
445 | static int __init build_detail_arrays(void) | 430 | static int build_detail_arrays(void) |
446 | { | 431 | { |
447 | unsigned long ptr; | 432 | unsigned long ptr; |
448 | int i, scal_detail_size, rio_detail_size; | 433 | int i, scal_detail_size, rio_detail_size; |
@@ -476,7 +461,7 @@ static int __init build_detail_arrays(void) | |||
476 | return 1; | 461 | return 1; |
477 | } | 462 | } |
478 | 463 | ||
479 | void __init setup_summit(void) | 464 | void setup_summit(void) |
480 | { | 465 | { |
481 | unsigned long ptr; | 466 | unsigned long ptr; |
482 | unsigned short offset; | 467 | unsigned short offset; |
@@ -574,7 +559,6 @@ struct apic apic_summit = { | |||
574 | .send_IPI_all = summit_send_IPI_all, | 559 | .send_IPI_all = summit_send_IPI_all, |
575 | .send_IPI_self = default_send_IPI_self, | 560 | .send_IPI_self = default_send_IPI_self, |
576 | 561 | ||
577 | .wakeup_cpu = NULL, | ||
578 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 562 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
579 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 563 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
580 | 564 | ||
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 354b9c45601d..4a903e2f0d17 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -57,6 +57,8 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | |||
57 | unsigned long query_cpu; | 57 | unsigned long query_cpu; |
58 | unsigned long flags; | 58 | unsigned long flags; |
59 | 59 | ||
60 | x2apic_wrmsr_fence(); | ||
61 | |||
60 | local_irq_save(flags); | 62 | local_irq_save(flags); |
61 | for_each_cpu(query_cpu, mask) { | 63 | for_each_cpu(query_cpu, mask) { |
62 | __x2apic_send_IPI_dest( | 64 | __x2apic_send_IPI_dest( |
@@ -73,6 +75,8 @@ static void | |||
73 | unsigned long query_cpu; | 75 | unsigned long query_cpu; |
74 | unsigned long flags; | 76 | unsigned long flags; |
75 | 77 | ||
78 | x2apic_wrmsr_fence(); | ||
79 | |||
76 | local_irq_save(flags); | 80 | local_irq_save(flags); |
77 | for_each_cpu(query_cpu, mask) { | 81 | for_each_cpu(query_cpu, mask) { |
78 | if (query_cpu == this_cpu) | 82 | if (query_cpu == this_cpu) |
@@ -90,6 +94,8 @@ static void x2apic_send_IPI_allbutself(int vector) | |||
90 | unsigned long query_cpu; | 94 | unsigned long query_cpu; |
91 | unsigned long flags; | 95 | unsigned long flags; |
92 | 96 | ||
97 | x2apic_wrmsr_fence(); | ||
98 | |||
93 | local_irq_save(flags); | 99 | local_irq_save(flags); |
94 | for_each_online_cpu(query_cpu) { | 100 | for_each_online_cpu(query_cpu) { |
95 | if (query_cpu == this_cpu) | 101 | if (query_cpu == this_cpu) |
@@ -224,7 +230,6 @@ struct apic apic_x2apic_cluster = { | |||
224 | .send_IPI_all = x2apic_send_IPI_all, | 230 | .send_IPI_all = x2apic_send_IPI_all, |
225 | .send_IPI_self = x2apic_send_IPI_self, | 231 | .send_IPI_self = x2apic_send_IPI_self, |
226 | 232 | ||
227 | .wakeup_cpu = NULL, | ||
228 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 233 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
229 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 234 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
230 | .wait_for_init_deassert = NULL, | 235 | .wait_for_init_deassert = NULL, |
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 5bcb174409bc..a284359627e7 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
@@ -58,6 +58,8 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | |||
58 | unsigned long query_cpu; | 58 | unsigned long query_cpu; |
59 | unsigned long flags; | 59 | unsigned long flags; |
60 | 60 | ||
61 | x2apic_wrmsr_fence(); | ||
62 | |||
61 | local_irq_save(flags); | 63 | local_irq_save(flags); |
62 | for_each_cpu(query_cpu, mask) { | 64 | for_each_cpu(query_cpu, mask) { |
63 | __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), | 65 | __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), |
@@ -73,6 +75,8 @@ static void | |||
73 | unsigned long query_cpu; | 75 | unsigned long query_cpu; |
74 | unsigned long flags; | 76 | unsigned long flags; |
75 | 77 | ||
78 | x2apic_wrmsr_fence(); | ||
79 | |||
76 | local_irq_save(flags); | 80 | local_irq_save(flags); |
77 | for_each_cpu(query_cpu, mask) { | 81 | for_each_cpu(query_cpu, mask) { |
78 | if (query_cpu != this_cpu) | 82 | if (query_cpu != this_cpu) |
@@ -89,6 +93,8 @@ static void x2apic_send_IPI_allbutself(int vector) | |||
89 | unsigned long query_cpu; | 93 | unsigned long query_cpu; |
90 | unsigned long flags; | 94 | unsigned long flags; |
91 | 95 | ||
96 | x2apic_wrmsr_fence(); | ||
97 | |||
92 | local_irq_save(flags); | 98 | local_irq_save(flags); |
93 | for_each_online_cpu(query_cpu) { | 99 | for_each_online_cpu(query_cpu) { |
94 | if (query_cpu == this_cpu) | 100 | if (query_cpu == this_cpu) |
@@ -213,7 +219,6 @@ struct apic apic_x2apic_phys = { | |||
213 | .send_IPI_all = x2apic_send_IPI_all, | 219 | .send_IPI_all = x2apic_send_IPI_all, |
214 | .send_IPI_self = x2apic_send_IPI_self, | 220 | .send_IPI_self = x2apic_send_IPI_self, |
215 | 221 | ||
216 | .wakeup_cpu = NULL, | ||
217 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 222 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
218 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 223 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
219 | .wait_for_init_deassert = NULL, | 224 | .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..1248318436e8 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,40 +91,39 @@ 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 | ||
115 | static void uv_send_IPI_one(int cpu, int vector) | 119 | static void uv_send_IPI_one(int cpu, int vector) |
116 | { | 120 | { |
117 | unsigned long val, apicid; | 121 | unsigned long apicid; |
118 | int pnode; | 122 | int pnode; |
119 | 123 | ||
120 | apicid = per_cpu(x86_cpu_to_apicid, cpu); | 124 | apicid = per_cpu(x86_cpu_to_apicid, cpu); |
121 | pnode = uv_apicid_to_pnode(apicid); | 125 | pnode = uv_apicid_to_pnode(apicid); |
122 | 126 | uv_hub_send_ipi(pnode, apicid, vector); | |
123 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | ||
124 | (apicid << UVH_IPI_INT_APIC_ID_SHFT) | | ||
125 | (vector << UVH_IPI_INT_VECTOR_SHFT); | ||
126 | |||
127 | uv_write_global_mmr64(pnode, UVH_IPI_INT, val); | ||
128 | } | 127 | } |
129 | 128 | ||
130 | static void uv_send_IPI_mask(const struct cpumask *mask, int vector) | 129 | static void uv_send_IPI_mask(const struct cpumask *mask, int vector) |
@@ -285,7 +284,7 @@ struct apic apic_x2apic_uv_x = { | |||
285 | .send_IPI_all = uv_send_IPI_all, | 284 | .send_IPI_all = uv_send_IPI_all, |
286 | .send_IPI_self = uv_send_IPI_self, | 285 | .send_IPI_self = uv_send_IPI_self, |
287 | 286 | ||
288 | .wakeup_cpu = NULL, | 287 | .wakeup_secondary_cpu = uv_wakeup_secondary, |
289 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, | 288 | .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, |
290 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, | 289 | .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, |
291 | .wait_for_init_deassert = NULL, | 290 | .wait_for_init_deassert = NULL, |
@@ -365,7 +364,7 @@ static __init void map_high(char *id, unsigned long base, int shift, | |||
365 | paddr = base << shift; | 364 | paddr = base << shift; |
366 | bytes = (1UL << shift) * (max_pnode + 1); | 365 | bytes = (1UL << shift) * (max_pnode + 1); |
367 | printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, | 366 | printk(KERN_INFO "UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, |
368 | paddr + bytes); | 367 | paddr + bytes); |
369 | if (map_type == map_uc) | 368 | if (map_type == map_uc) |
370 | init_extra_mapping_uc(paddr, bytes); | 369 | init_extra_mapping_uc(paddr, bytes); |
371 | else | 370 | else |
@@ -528,7 +527,7 @@ late_initcall(uv_init_heartbeat); | |||
528 | 527 | ||
529 | /* | 528 | /* |
530 | * Called on each cpu to initialize the per_cpu UV data area. | 529 | * Called on each cpu to initialize the per_cpu UV data area. |
531 | * ZZZ hotplug not supported yet | 530 | * FIXME: hotplug not supported yet |
532 | */ | 531 | */ |
533 | void __cpuinit uv_cpu_init(void) | 532 | void __cpuinit uv_cpu_init(void) |
534 | { | 533 | { |