aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/genapic_flat.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2005-07-29 00:15:42 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-29 00:46:01 -0400
commitf8d311939f9d2b2a5e935df8dceb98b7cbe08d43 (patch)
tree02da12ff661ee3da44e29e4ca89df28dea8a4593 /arch/x86_64/kernel/genapic_flat.c
parent37a47e65fa58d413a31f27ee88f6cb98583b6157 (diff)
[PATCH] x86_64: Support more than 8 cores on AMD systems
Use physical mode instead of logical mode to address more CPUs. This is also used in the CPU hotplug case to avoid a race. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/genapic_flat.c')
-rw-r--r--arch/x86_64/kernel/genapic_flat.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index fdfa15f5d2ed..adc96282a9e2 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -2,7 +2,7 @@
2 * Copyright 2004 James Cleverdon, IBM. 2 * Copyright 2004 James Cleverdon, IBM.
3 * Subject to the GNU Public License, v.2 3 * Subject to the GNU Public License, v.2
4 * 4 *
5 * Flat APIC subarch code. Maximum 8 CPUs, logical delivery. 5 * Flat APIC subarch code.
6 * 6 *
7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by 7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by
8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and 8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
@@ -119,3 +119,63 @@ struct genapic apic_flat = {
119 .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, 119 .cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
120 .phys_pkg_id = phys_pkg_id, 120 .phys_pkg_id = phys_pkg_id,
121}; 121};
122
123/*
124 * Physflat mode is used when there are more than 8 CPUs on a AMD system.
125 * We cannot use logical delivery in this case because the mask
126 * overflows, so use physical mode.
127 */
128
129static cpumask_t physflat_target_cpus(void)
130{
131 return cpumask_of_cpu(0);
132}
133
134static void physflat_send_IPI_mask(cpumask_t cpumask, int vector)
135{
136 send_IPI_mask_sequence(cpumask, vector);
137}
138
139static void physflat_send_IPI_allbutself(int vector)
140{
141 cpumask_t allbutme = cpu_online_map;
142 int me = get_cpu();
143 cpu_clear(me, allbutme);
144 physflat_send_IPI_mask(allbutme, vector);
145 put_cpu();
146}
147
148static void physflat_send_IPI_all(int vector)
149{
150 physflat_send_IPI_mask(cpu_online_map, vector);
151}
152
153static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
154{
155 int cpu;
156
157 /*
158 * We're using fixed IRQ delivery, can only return one phys APIC ID.
159 * May as well be the first.
160 */
161 cpu = first_cpu(cpumask);
162 if ((unsigned)cpu < NR_CPUS)
163 return x86_cpu_to_apicid[cpu];
164 else
165 return BAD_APICID;
166}
167
168struct genapic apic_physflat = {
169 .name = "physical flat",
170 .int_delivery_mode = dest_LowestPrio,
171 .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
172 .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST,
173 .target_cpus = physflat_target_cpus,
174 .apic_id_registered = flat_apic_id_registered,
175 .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
176 .send_IPI_all = physflat_send_IPI_all,
177 .send_IPI_allbutself = physflat_send_IPI_allbutself,
178 .send_IPI_mask = physflat_send_IPI_mask,
179 .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid,
180 .phys_pkg_id = phys_pkg_id,
181};