Commit f88f2b4f authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Ingo Molnar

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: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarCyrill 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: default avatarIngo Molnar <mingo@elte.hu>
parent 9636bc05
...@@ -246,6 +246,7 @@ static int modern_apic(void) ...@@ -246,6 +246,7 @@ static int modern_apic(void)
*/ */
void apic_disable(void) void apic_disable(void)
{ {
pr_info("APIC: switched to apic NOOP\n");
apic = &apic_noop; apic = &apic_noop;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Though in case if apic is disabled (for some reason) we try * Though in case if apic is disabled (for some reason) we try
* to not uglify the caller's code and allow to call (some) apic routines * to not uglify the caller's code and allow to call (some) apic routines
* like self-ipi, etc... and issue a warning if an operation is not allowed * like self-ipi, etc...
*/ */
#include <linux/threads.h> #include <linux/threads.h>
...@@ -30,76 +30,88 @@ ...@@ -30,76 +30,88 @@
#include <asm/acpi.h> #include <asm/acpi.h>
#include <asm/e820.h> #include <asm/e820.h>
/* static void noop_init_apic_ldr(void) { }
* some operations should never be reached with static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
* noop apic if it's not turned off, this mostly static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) { }
* means the caller forgot to disable apic (or static void noop_send_IPI_allbutself(int vector) { }
* check the apic presence) before doing a call static void noop_send_IPI_all(int vector) { }
*/ static void noop_send_IPI_self(int vector) { }
static void warn_apic_enabled(void) static void noop_apic_wait_icr_idle(void) { }
static void noop_apic_icr_write(u32 low, u32 id) { }
static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip)
{ {
WARN_ONCE((cpu_has_apic || !disable_apic), return -1;
"APIC: Called for NOOP operation with apic enabled\n");
} }
/* static u32 noop_safe_apic_wait_icr_idle(void)
* To check operations but do not bloat source code {
*/ return 0;
#define NOOP_FUNC(func) func { warn_apic_enabled(); } }
#define NOOP_FUNC_RET(func, ret) func { warn_apic_enabled(); return ret; }
static u64 noop_apic_icr_read(void)
NOOP_FUNC(static void noop_init_apic_ldr(void)) {
NOOP_FUNC(static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector)) return 0;
NOOP_FUNC(static void noop_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)) }
NOOP_FUNC(static void noop_send_IPI_allbutself(int vector))
NOOP_FUNC(static void noop_send_IPI_all(int vector)) static physid_mask_t noop_ioapic_phys_id_map(physid_mask_t phys_map)
NOOP_FUNC(static void noop_send_IPI_self(int vector)) {
NOOP_FUNC_RET(static int noop_wakeup_secondary_cpu(int apicid, unsigned long start_eip), -1) return phys_map;
NOOP_FUNC(static void noop_apic_write(u32 reg, u32 v)) }
NOOP_FUNC(void noop_apic_wait_icr_idle(void))
NOOP_FUNC_RET(static u32 noop_safe_apic_wait_icr_idle(void), 0) static int noop_cpu_to_logical_apicid(int cpu)
NOOP_FUNC_RET(static u64 noop_apic_icr_read(void), 0) {
NOOP_FUNC(static void noop_apic_icr_write(u32 low, u32 id)) return 0;
NOOP_FUNC_RET(static physid_mask_t noop_ioapic_phys_id_map(physid_mask_t phys_map), phys_map) }
NOOP_FUNC_RET(static int noop_cpu_to_logical_apicid(int cpu), 1)
NOOP_FUNC_RET(static int noop_default_phys_pkg_id(int cpuid_apic, int index_msb), 0) static int noop_phys_pkg_id(int cpuid_apic, int index_msb)
NOOP_FUNC_RET(static unsigned int noop_get_apic_id(unsigned long x), 0) {
return 0;
}
static unsigned int noop_get_apic_id(unsigned long x)
{
return 0;
}
static int noop_probe(void) static int noop_probe(void)
{ {
/* should not ever be enabled this way */ /*
* NOOP apic should not ever be
* enabled via probe routine
*/
return 0; return 0;
} }
static int noop_apic_id_registered(void) static int noop_apic_id_registered(void)
{ {
warn_apic_enabled(); /*
return physid_isset(read_apic_id(), phys_cpu_present_map); * if we would be really "pedantic"
* we should pass read_apic_id() here
* but since NOOP suppose APIC ID = 0
* lets save a few cycles
*/
return physid_isset(0, phys_cpu_present_map);
} }
static const struct cpumask *noop_target_cpus(void) static const struct cpumask *noop_target_cpus(void)
{ {
warn_apic_enabled();
/* only BSP here */ /* only BSP here */
return cpumask_of(0); return cpumask_of(0);
} }
static unsigned long noop_check_apicid_used(physid_mask_t bitmap, int apicid) static unsigned long noop_check_apicid_used(physid_mask_t bitmap, int apicid)
{ {
warn_apic_enabled();
return physid_isset(apicid, bitmap); return physid_isset(apicid, bitmap);
} }
static unsigned long noop_check_apicid_present(int bit) static unsigned long noop_check_apicid_present(int bit)
{ {
warn_apic_enabled();
return physid_isset(bit, phys_cpu_present_map); return physid_isset(bit, phys_cpu_present_map);
} }
static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
{ {
warn_apic_enabled();
if (cpu != 0) if (cpu != 0)
pr_warning("APIC: Vector allocated for non-BSP cpu\n"); pr_warning("APIC: Vector allocated for non-BSP cpu\n");
cpumask_clear(retmask); cpumask_clear(retmask);
...@@ -108,22 +120,21 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) ...@@ -108,22 +120,21 @@ static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask)
int noop_apicid_to_node(int logical_apicid) int noop_apicid_to_node(int logical_apicid)
{ {
warn_apic_enabled();
/* we're always on node 0 */ /* we're always on node 0 */
return 0; return 0;
} }
static u32 noop_apic_read(u32 reg) static u32 noop_apic_read(u32 reg)
{ {
/*
* noop-read is always safe until we have
* non-disabled unit
*/
WARN_ON_ONCE((cpu_has_apic && !disable_apic)); WARN_ON_ONCE((cpu_has_apic && !disable_apic));
return 0; return 0;
} }
static void noop_apic_write(u32 reg, u32 v)
{
WARN_ON_ONCE((cpu_has_apic || !disable_apic));
}
struct apic apic_noop = { struct apic apic_noop = {
.name = "noop", .name = "noop",
.probe = noop_probe, .probe = noop_probe,
...@@ -157,7 +168,7 @@ struct apic apic_noop = { ...@@ -157,7 +168,7 @@ struct apic apic_noop = {
.check_phys_apicid_present = default_check_phys_apicid_present, .check_phys_apicid_present = default_check_phys_apicid_present,
.enable_apic_mode = NULL, .enable_apic_mode = NULL,
.phys_pkg_id = noop_default_phys_pkg_id, .phys_pkg_id = noop_phys_pkg_id,
.mps_oem_check = NULL, .mps_oem_check = NULL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment