aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2009-10-15 11:04:16 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-15 11:26:53 -0400
commitf88f2b4fdb1e098433ad2b005b6f7353f7268ce1 (patch)
treee69f977869267f1220ffa533c07677faba5552fc /arch/x86/kernel/apic
parent9636bc0555e3f383c120ddcffe4b7c5c58a10b1a (diff)
x86: apic: Allow noop operations to be called almost at any time
As only apic noop is used we allow to use almost any operation caller wants (and which of them noop driver supports of course). Initially it was reported by Ingo Molnar that apic noop issue a warning for pkg id (which is actually false positive and should be eliminated). So we save checking (and warning issue) for read/write operations while allow any other ops to be freely used. Also: - fix noop_cpu_to_logical_apicid, it should be 0. - rename noop_default_phys_pkg_id to noop_phys_pkg_id (we use default_ prefix for more general routines in apic subsystem). Reported-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Maciej W. Rozycki <macro@linux-mips.org> LKML-Reference: <20091015150416.GC5331@lenovo> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/apic.c1
-rw-r--r--arch/x86/kernel/apic/apic_noop.c105
2 files changed, 59 insertions, 47 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 61a5628810da..dce93d4b0eaf 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -246,6 +246,7 @@ static int modern_apic(void)
246 */ 246 */
247void apic_disable(void) 247void apic_disable(void)
248{ 248{
249 pr_info("APIC: switched to apic NOOP\n");
249 apic = &apic_noop; 250 apic = &apic_noop;
250} 251}
251 252
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
index 0b93ec2fde0a..9ab6ffb313ac 100644
--- a/arch/x86/kernel/apic/apic_noop.c
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Though in case if apic is disabled (for some reason) we try 7 * Though in case if apic is disabled (for some reason) we try
8 * to not uglify the caller's code and allow to call (some) apic routines 8 * to not uglify the caller's code and allow to call (some) apic routines
9 * like self-ipi, etc... and issue a warning if an operation is not allowed 9 * like self-ipi, etc...
10 */ 10 */
11 11
12#include <linux/threads.h> 12#include <linux/threads.h>
@@ -30,76 +30,88 @@
30#include <asm/acpi.h> 30#include <asm/acpi.h>
31#include <asm/e820.h> 31#include <asm/e820.h>
32 32
33/* 33static void noop_init_apic_ldr(void) { }
34 * some operations should never be reached with 34static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
35 * noop apic if it's not turned off, this mostly 35static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { }
36 * means the caller forgot to disable apic (or 36static void noop_send_IPI_allbutself(int vector) { }
37 * check the apic presence) before doing a call 37static void noop_send_IPI_all(int vector) { }
38 */ 38static void noop_send_IPI_self(int vector) { }
39static void warn_apic_enabled(void) 39static void noop_apic_wait_icr_idle(void) { }
40static void noop_apic_icr_write(u32 low, u32 id) { }
41
42static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
40{ 43{
41 WARN_ONCE((cpu_has_apic || !disable_apic), 44 return -1;
42 "APIC: Called for NOOP operation with apic enabled\n");
43} 45}
44 46
45/* 47static u32 noop_safe_apic_wait_icr_idle(void)
46 * To check operations but do not bloat source code 48{
47 */ 49 return 0;
48#define NOOP_FUNC(func) func { warn_apic_enabled(); } 50}
49#define NOOP_FUNC_RET(func, ret) func { warn_apic_enabled(); return ret; } 51
50 52static u64 noop_apic_icr_read(void)
51NOOP_FUNC(static void noop_init_apic_ldr(void)) 53{
52NOOP_FUNC(static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector)) 54 return 0;
53NOOP_FUNC(static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)) 55}
54NOOP_FUNC(static void noop_send_IPI_allbutself(int vector)) 56
55NOOP_FUNC(static void noop_send_IPI_all(int vector)) 57static physid_mask_t noop_ioapic_phys_id_map(physid_mask_t phys_map)
56NOOP_FUNC(static void noop_send_IPI_self(int vector)) 58{
57NOOP_FUNC_RET(static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip), -1) 59 return phys_map;
58NOOP_FUNC(static void noop_apic_write(u32 reg, u32 v)) 60}
59NOOP_FUNC(void noop_apic_wait_icr_idle(void)) 61
60NOOP_FUNC_RET(static u32 noop_safe_apic_wait_icr_idle(void), 0) 62static int noop_cpu_to_logical_apicid(int cpu)
61NOOP_FUNC_RET(static u64 noop_apic_icr_read(void), 0) 63{
62NOOP_FUNC(static void noop_apic_icr_write(u32 low, u32 id)) 64 return 0;
63NOOP_FUNC_RET(static physid_mask_t noop_ioapic_phys_id_map(physid_mask_t phys_map), phys_map) 65}
64NOOP_FUNC_RET(static int noop_cpu_to_logical_apicid(int cpu), 1) 66
65NOOP_FUNC_RET(static int noop_default_phys_pkg_id(int cpuid_apic, int index_msb), 0) 67static int noop_phys_pkg_id(int cpuid_apic, int index_msb)
66NOOP_FUNC_RET(static unsigned int noop_get_apic_id(unsigned long x), 0) 68{
69 return 0;
70}
71
72static unsigned int noop_get_apic_id(unsigned long x)
73{
74 return 0;
75}
67 76
68static int noop_probe(void) 77static int noop_probe(void)
69{ 78{
70 /* should not ever be enabled this way */ 79 /*
80 * NOOP apic should not ever be
81 * enabled via probe routine
82 */
71 return 0; 83 return 0;
72} 84}
73 85
74static int noop_apic_id_registered(void) 86static int noop_apic_id_registered(void)
75{ 87{
76 warn_apic_enabled(); 88 /*
77 return physid_isset(read_apic_id(), phys_cpu_present_map); 89 * if we would be really "pedantic"
90 * we should pass read_apic_id() here
91 * but since NOOP suppose APIC ID = 0
92 * lets save a few cycles
93 */
94 return physid_isset(0, phys_cpu_present_map);
78} 95}
79 96
80static const struct cpumask *noop_target_cpus(void) 97static const struct cpumask *noop_target_cpus(void)
81{ 98{
82 warn_apic_enabled();
83
84 /* only BSP here */ 99 /* only BSP here */
85 return cpumask_of(0); 100 return cpumask_of(0);
86} 101}
87 102
88static unsigned long noop_check_apicid_used(physid_mask_t bitmap, int apicid) 103static unsigned long noop_check_apicid_used(physid_mask_t bitmap, int apicid)
89{ 104{
90 warn_apic_enabled();
91 return physid_isset(apicid, bitmap); 105 return physid_isset(apicid, bitmap);
92} 106}
93 107
94static unsigned long noop_check_apicid_present(int bit) 108static unsigned long noop_check_apicid_present(int bit)
95{ 109{
96 warn_apic_enabled();
97 return physid_isset(bit, phys_cpu_present_map); 110 return physid_isset(bit, phys_cpu_present_map);
98} 111}
99 112
100static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) 113static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
101{ 114{
102 warn_apic_enabled();
103 if (cpu != 0) 115 if (cpu != 0)
104 pr_warning("APIC: Vector allocated for non-BSP cpu\n"); 116 pr_warning("APIC: Vector allocated for non-BSP cpu\n");
105 cpumask_clear(retmask); 117 cpumask_clear(retmask);
@@ -108,22 +120,21 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
108 120
109int noop_apicid_to_node(int logical_apicid) 121int noop_apicid_to_node(int logical_apicid)
110{ 122{
111 warn_apic_enabled();
112
113 /* we're always on node 0 */ 123 /* we're always on node 0 */
114 return 0; 124 return 0;
115} 125}
116 126
117static u32 noop_apic_read(u32 reg) 127static u32 noop_apic_read(u32 reg)
118{ 128{
119 /*
120 * noop-read is always safe until we have
121 * non-disabled unit
122 */
123 WARN_ON_ONCE((cpu_has_apic && !disable_apic)); 129 WARN_ON_ONCE((cpu_has_apic && !disable_apic));
124 return 0; 130 return 0;
125} 131}
126 132
133static void noop_apic_write(u32 reg, u32 v)
134{
135 WARN_ON_ONCE((cpu_has_apic || !disable_apic));
136}
137
127struct apic apic_noop = { 138struct apic apic_noop = {
128 .name = "noop", 139 .name = "noop",
129 .probe = noop_probe, 140 .probe = noop_probe,
@@ -157,7 +168,7 @@ struct apic apic_noop = {
157 .check_phys_apicid_present = default_check_phys_apicid_present, 168 .check_phys_apicid_present = default_check_phys_apicid_present,
158 .enable_apic_mode = NULL, 169 .enable_apic_mode = NULL,
159 170
160 .phys_pkg_id = noop_default_phys_pkg_id, 171 .phys_pkg_id = noop_phys_pkg_id,
161 172
162 .mps_oem_check = NULL, 173 .mps_oem_check = NULL,
163 174