ia64/xen-unstable

view linux-2.6-xen-sparse/arch/x86_64/kernel/genapic-xen.c @ 13647:057c4c2991fa

32-on-64: Fix an one-off error in compat_addr_ok().
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kaf24@localhost.localdomain
date Fri Jan 26 13:36:52 2007 +0000 (2007-01-26)
parents 3adf00179a63
children
line source
1 /*
2 * Copyright 2004 James Cleverdon, IBM.
3 * Subject to the GNU Public License, v.2
4 *
5 * Generic APIC sub-arch probe layer.
6 *
7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by
8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
9 * James Cleverdon.
10 */
11 #include <linux/threads.h>
12 #include <linux/cpumask.h>
13 #include <linux/string.h>
14 #include <linux/kernel.h>
15 #include <linux/ctype.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
19 #include <asm/smp.h>
20 #include <asm/ipi.h>
22 #if defined(CONFIG_ACPI)
23 #include <acpi/acpi_bus.h>
24 #endif
26 /* which logical CPU number maps to which CPU (physical APIC ID) */
27 u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
28 EXPORT_SYMBOL(x86_cpu_to_apicid);
29 u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
31 extern struct genapic apic_cluster;
32 extern struct genapic apic_flat;
33 extern struct genapic apic_physflat;
35 #ifndef CONFIG_XEN
36 struct genapic *genapic = &apic_flat;
37 #else
38 extern struct genapic apic_xen;
39 struct genapic *genapic = &apic_xen;
40 #endif
43 /*
44 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
45 */
46 void __init clustered_apic_check(void)
47 {
48 #ifndef CONFIG_XEN
49 long i;
50 u8 clusters, max_cluster;
51 u8 id;
52 u8 cluster_cnt[NUM_APIC_CLUSTERS];
53 int max_apic = 0;
55 #if defined(CONFIG_ACPI)
56 /*
57 * Some x86_64 machines use physical APIC mode regardless of how many
58 * procs/clusters are present (x86_64 ES7000 is an example).
59 */
60 if (acpi_fadt.revision > FADT2_REVISION_ID)
61 if (acpi_fadt.force_apic_physical_destination_mode) {
62 genapic = &apic_cluster;
63 goto print;
64 }
65 #endif
67 memset(cluster_cnt, 0, sizeof(cluster_cnt));
68 for (i = 0; i < NR_CPUS; i++) {
69 id = bios_cpu_apicid[i];
70 if (id == BAD_APICID)
71 continue;
72 if (id > max_apic)
73 max_apic = id;
74 cluster_cnt[APIC_CLUSTERID(id)]++;
75 }
77 /* Don't use clustered mode on AMD platforms. */
78 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
79 genapic = &apic_physflat;
80 #ifndef CONFIG_HOTPLUG_CPU
81 /* In the CPU hotplug case we cannot use broadcast mode
82 because that opens a race when a CPU is removed.
83 Stay at physflat mode in this case.
84 It is bad to do this unconditionally though. Once
85 we have ACPI platform support for CPU hotplug
86 we should detect hotplug capablity from ACPI tables and
87 only do this when really needed. -AK */
88 if (max_apic <= 8)
89 genapic = &apic_flat;
90 #endif
91 goto print;
92 }
94 clusters = 0;
95 max_cluster = 0;
97 for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
98 if (cluster_cnt[i] > 0) {
99 ++clusters;
100 if (cluster_cnt[i] > max_cluster)
101 max_cluster = cluster_cnt[i];
102 }
103 }
105 /*
106 * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode,
107 * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical
108 * else physical mode.
109 * (We don't use lowest priority delivery + HW APIC IRQ steering, so
110 * can ignore the clustered logical case and go straight to physical.)
111 */
112 if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) {
113 #ifdef CONFIG_HOTPLUG_CPU
114 /* Don't use APIC shortcuts in CPU hotplug to avoid races */
115 genapic = &apic_physflat;
116 #else
117 genapic = &apic_flat;
118 #endif
119 } else
120 genapic = &apic_cluster;
122 print:
123 #else
124 /* hardcode to xen apic functions */
125 genapic = &apic_xen;
126 #endif
127 printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
128 }
130 /* Same for both flat and clustered. */
132 #ifdef CONFIG_XEN
133 extern void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int dest);
134 #endif
136 void send_IPI_self(int vector)
137 {
138 #ifndef CONFIG_XEN
139 __send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
140 #else
141 xen_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL);
142 #endif
143 }