提交 54ac14a8 编写于 作者: Y Yinghai Lu 提交者: Ingo Molnar

x86: fix wakeup_cpu with numaq/es7000, v2, fix

Impact: fix wakeup_secondary_cpu with hotplug

We can not put that into x86_quirks, because that is __initdata.
So try to move that to genapic, and add update_genapic in x86_quirks.

later we even could use that stub to:

 1. autodetect CONFIG_ES7000_CLUSTERED_APIC
 2. more correct inquire_remote_apic with apic_verbosity setting.
Signed-off-by: NYinghai Lu <yinghai@kernel.org>
Signed-off-by: NIngo Molnar <mingo@elte.hu>
上级 569712b2
...@@ -66,6 +66,7 @@ struct genapic { ...@@ -66,6 +66,7 @@ struct genapic {
void (*send_IPI_allbutself)(int vector); void (*send_IPI_allbutself)(int vector);
void (*send_IPI_all)(int vector); void (*send_IPI_all)(int vector);
#endif #endif
int (*wakeup_cpu)(int apicid, unsigned long start_eip);
int trampoline_phys_low; int trampoline_phys_low;
int trampoline_phys_high; int trampoline_phys_high;
void (*wait_for_init_deassert)(atomic_t *deassert); void (*wait_for_init_deassert)(atomic_t *deassert);
......
...@@ -32,6 +32,8 @@ struct genapic { ...@@ -32,6 +32,8 @@ struct genapic {
unsigned int (*get_apic_id)(unsigned long x); unsigned int (*get_apic_id)(unsigned long x);
unsigned long (*set_apic_id)(unsigned int id); unsigned long (*set_apic_id)(unsigned int id);
unsigned long apic_id_mask; unsigned long apic_id_mask;
/* wakeup_secondary_cpu */
int (*wakeup_cpu)(int apicid, unsigned long start_eip);
}; };
extern struct genapic *genapic; extern struct genapic *genapic;
......
...@@ -32,11 +32,13 @@ static inline cpumask_t target_cpus(void) ...@@ -32,11 +32,13 @@ static inline cpumask_t target_cpus(void)
#define vector_allocation_domain (genapic->vector_allocation_domain) #define vector_allocation_domain (genapic->vector_allocation_domain)
#define read_apic_id() (GET_APIC_ID(apic_read(APIC_ID))) #define read_apic_id() (GET_APIC_ID(apic_read(APIC_ID)))
#define send_IPI_self (genapic->send_IPI_self) #define send_IPI_self (genapic->send_IPI_self)
#define wakeup_secondary_cpu (genapic->wakeup_cpu)
extern void setup_apic_routing(void); extern void setup_apic_routing(void);
#else #else
#define INT_DELIVERY_MODE dest_LowestPrio #define INT_DELIVERY_MODE dest_LowestPrio
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
#define TARGET_CPUS (target_cpus()) #define TARGET_CPUS (target_cpus())
#define wakeup_secondary_cpu wakeup_secondary_cpu_via_init
/* /*
* Set up the logical destination ID. * Set up the logical destination ID.
* *
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define vector_allocation_domain (genapic->vector_allocation_domain) #define vector_allocation_domain (genapic->vector_allocation_domain)
#define enable_apic_mode (genapic->enable_apic_mode) #define enable_apic_mode (genapic->enable_apic_mode)
#define phys_pkg_id (genapic->phys_pkg_id) #define phys_pkg_id (genapic->phys_pkg_id)
#define wakeup_secondary_cpu (genapic->wakeup_cpu)
extern void generic_bigsmp_probe(void); extern void generic_bigsmp_probe(void);
......
...@@ -17,6 +17,7 @@ static inline int is_visws_box(void) { return 0; } ...@@ -17,6 +17,7 @@ static inline int is_visws_box(void) { return 0; }
#endif #endif
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip); extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
/* /*
* Any setup quirks to be performed? * Any setup quirks to be performed?
*/ */
...@@ -40,7 +41,7 @@ struct x86_quirks { ...@@ -40,7 +41,7 @@ struct x86_quirks {
void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable, void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable,
unsigned short oemsize); unsigned short oemsize);
int (*setup_ioapic_ids)(void); int (*setup_ioapic_ids)(void);
int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip); int (*update_genapic)(void);
}; };
extern struct x86_quirks *x86_quirks; extern struct x86_quirks *x86_quirks;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/apicdef.h> #include <asm/apicdef.h>
#include <mach_mpparse.h> #include <mach_mpparse.h>
#include <asm/genapic.h>
#include <asm/setup.h> #include <asm/setup.h>
/* /*
...@@ -180,6 +181,13 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip) ...@@ -180,6 +181,13 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
return 0; return 0;
} }
static int __init es7000_update_genapic(void)
{
genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
return 0;
}
#endif #endif
void __init void __init
...@@ -197,8 +205,9 @@ setup_unisys(void) ...@@ -197,8 +205,9 @@ setup_unisys(void)
else else
es7000_plat = ES7000_CLASSIC; es7000_plat = ES7000_CLASSIC;
ioapic_renumber_irq = es7000_rename_gsi; ioapic_renumber_irq = es7000_rename_gsi;
#ifdef CONFIG_ES7000_CLUSTERED_APIC #ifdef CONFIG_ES7000_CLUSTERED_APIC
x86_quirks->wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip; x86_quirks->update_genapic = es7000_update_genapic;
#endif #endif
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/ipi.h> #include <asm/ipi.h>
#include <asm/genapic.h> #include <asm/genapic.h>
#include <asm/setup.h>
extern struct genapic apic_flat; extern struct genapic apic_flat;
extern struct genapic apic_physflat; extern struct genapic apic_physflat;
...@@ -53,6 +54,9 @@ void __init setup_apic_routing(void) ...@@ -53,6 +54,9 @@ void __init setup_apic_routing(void)
genapic = &apic_physflat; genapic = &apic_physflat;
printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
} }
if (x86_quirks->update_genapic)
x86_quirks->update_genapic();
} }
/* Same for both flat and physical. */ /* Same for both flat and physical. */
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <asm/numaq.h> #include <asm/numaq.h>
#include <asm/topology.h> #include <asm/topology.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/mpspec.h> #include <asm/genapic.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -235,6 +235,13 @@ static int __init numaq_setup_ioapic_ids(void) ...@@ -235,6 +235,13 @@ static int __init numaq_setup_ioapic_ids(void)
return 1; return 1;
} }
static int __init numaq_update_genapic(void)
{
genapic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
return 0;
}
static struct x86_quirks numaq_x86_quirks __initdata = { static struct x86_quirks numaq_x86_quirks __initdata = {
.arch_pre_time_init = numaq_pre_time_init, .arch_pre_time_init = numaq_pre_time_init,
.arch_time_init = NULL, .arch_time_init = NULL,
...@@ -250,7 +257,7 @@ static struct x86_quirks numaq_x86_quirks __initdata = { ...@@ -250,7 +257,7 @@ static struct x86_quirks numaq_x86_quirks __initdata = {
.mpc_oem_pci_bus = mpc_oem_pci_bus, .mpc_oem_pci_bus = mpc_oem_pci_bus,
.smp_read_mpc_oem = smp_read_mpc_oem, .smp_read_mpc_oem = smp_read_mpc_oem,
.setup_ioapic_ids = numaq_setup_ioapic_ids, .setup_ioapic_ids = numaq_setup_ioapic_ids,
.wakeup_secondary_cpu = wakeup_secondary_cpu_via_nmi, .update_genapic = numaq_update_genapic,
}; };
void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
......
...@@ -583,7 +583,18 @@ static int __init setup_elfcorehdr(char *arg) ...@@ -583,7 +583,18 @@ static int __init setup_elfcorehdr(char *arg)
early_param("elfcorehdr", setup_elfcorehdr); early_param("elfcorehdr", setup_elfcorehdr);
#endif #endif
static struct x86_quirks default_x86_quirks __initdata; static int __init default_update_genapic(void)
{
#if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
genapic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
#endif
return 0;
}
static struct x86_quirks default_x86_quirks __initdata = {
.update_genapic = default_update_genapic,
};
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks; struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
......
...@@ -615,7 +615,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) ...@@ -615,7 +615,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
return (send_status | accept_status); return (send_status | accept_status);
} }
static int __devinit int __devinit
wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
{ {
unsigned long send_status, accept_status = 0; unsigned long send_status, accept_status = 0;
...@@ -736,15 +736,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) ...@@ -736,15 +736,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
return (send_status | accept_status); return (send_status | accept_status);
} }
static int __devinit
wakeup_secondary_cpu(int apicid, unsigned long start_eip)
{
if (x86_quirks->wakeup_secondary_cpu)
return x86_quirks->wakeup_secondary_cpu(apicid, start_eip);
return wakeup_secondary_cpu_via_init(apicid, start_eip);
}
struct create_idle { struct create_idle {
struct work_struct work; struct work_struct work;
struct task_struct *idle; struct task_struct *idle;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/apicdef.h> #include <asm/apicdef.h>
#include <asm/genapic.h> #include <asm/genapic.h>
#include <asm/setup.h>
extern struct genapic apic_numaq; extern struct genapic apic_numaq;
extern struct genapic apic_summit; extern struct genapic apic_summit;
...@@ -57,6 +58,9 @@ static int __init parse_apic(char *arg) ...@@ -57,6 +58,9 @@ static int __init parse_apic(char *arg)
} }
} }
if (x86_quirks->update_genapic)
x86_quirks->update_genapic();
/* Parsed again by __setup for debug/verbose */ /* Parsed again by __setup for debug/verbose */
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册