x86/platform: Move APIC ID validity check into platform APIC code
Move APIC ID validity check into platform APIC code, so it can be overridden when needed. For NumaChip systems, always trust MADT, as it's constructed with high APIC IDs. Behaviour verifies on standard x86 systems and on NumaChip systems with this, and compile-tested with allyesconfig. Signed-off-by: Daniel J Blueman <daniel@numascale-asia.com> Reviewed-by: Steffen Persvold <sp@numascale.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: H. Peter Anvin <hpa@linux.intel.com> Cc: Suresh Siddha <suresh.b.siddha@intel.com> Link: http://lkml.kernel.org/r/1331709454-27966-1-git-send-email-daniel@numascale-asia.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
c96a987669
Коммит
fa63030e9c
|
@ -288,6 +288,7 @@ struct apic {
|
|||
|
||||
int (*probe)(void);
|
||||
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
|
||||
int (*apic_id_valid)(int apicid);
|
||||
int (*apic_id_registered)(void);
|
||||
|
||||
u32 irq_delivery_mode;
|
||||
|
@ -532,6 +533,11 @@ static inline unsigned int read_apic_id(void)
|
|||
return apic->get_apic_id(reg);
|
||||
}
|
||||
|
||||
static inline int default_apic_id_valid(int apicid)
|
||||
{
|
||||
return x2apic_mode || (apicid < 255);
|
||||
}
|
||||
|
||||
extern void default_setup_apic_routing(void);
|
||||
|
||||
extern struct apic apic_noop;
|
||||
|
|
|
@ -180,6 +180,7 @@ static struct apic apic_flat = {
|
|||
.name = "flat",
|
||||
.probe = flat_probe,
|
||||
.acpi_madt_oem_check = flat_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = flat_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
@ -337,6 +338,7 @@ static struct apic apic_physflat = {
|
|||
.name = "physical flat",
|
||||
.probe = physflat_probe,
|
||||
.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = flat_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -124,6 +124,7 @@ struct apic apic_noop = {
|
|||
.probe = noop_probe,
|
||||
.acpi_madt_oem_check = NULL,
|
||||
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = noop_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
|
|
@ -56,6 +56,12 @@ static unsigned int read_xapic_id(void)
|
|||
return get_apic_id(apic_read(APIC_ID));
|
||||
}
|
||||
|
||||
static int numachip_apic_id_valid(int apicid)
|
||||
{
|
||||
/* Trust what bootloader passes in MADT */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int numachip_apic_id_registered(void)
|
||||
{
|
||||
return physid_isset(read_xapic_id(), phys_cpu_present_map);
|
||||
|
@ -223,10 +229,11 @@ static int __init numachip_system_init(void)
|
|||
}
|
||||
early_initcall(numachip_system_init);
|
||||
|
||||
static int numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||
static int __cpuinit numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||
{
|
||||
if (!strncmp(oem_id, "NUMASC", 6)) {
|
||||
numachip_system = 1;
|
||||
setup_force_cpu_cap(X86_FEATURE_X2APIC);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -238,6 +245,7 @@ static struct apic apic_numachip __refconst = {
|
|||
.name = "NumaConnect system",
|
||||
.probe = numachip_probe,
|
||||
.acpi_madt_oem_check = numachip_acpi_madt_oem_check,
|
||||
.apic_id_valid = numachip_apic_id_valid,
|
||||
.apic_id_registered = numachip_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -198,6 +198,7 @@ static struct apic apic_bigsmp = {
|
|||
.name = "bigsmp",
|
||||
.probe = probe_bigsmp,
|
||||
.acpi_madt_oem_check = NULL,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = bigsmp_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -625,6 +625,7 @@ static struct apic __refdata apic_es7000_cluster = {
|
|||
.name = "es7000",
|
||||
.probe = probe_es7000,
|
||||
.acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = es7000_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
@ -690,6 +691,7 @@ static struct apic __refdata apic_es7000 = {
|
|||
.name = "es7000",
|
||||
.probe = probe_es7000,
|
||||
.acpi_madt_oem_check = es7000_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = es7000_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -478,6 +478,7 @@ static struct apic __refdata apic_numaq = {
|
|||
.name = "NUMAQ",
|
||||
.probe = probe_numaq,
|
||||
.acpi_madt_oem_check = NULL,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = numaq_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
|
|
@ -92,6 +92,7 @@ static struct apic apic_default = {
|
|||
.name = "default",
|
||||
.probe = probe_default,
|
||||
.acpi_madt_oem_check = NULL,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = default_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
|
|
@ -496,6 +496,7 @@ static struct apic apic_summit = {
|
|||
.name = "summit",
|
||||
.probe = probe_summit,
|
||||
.acpi_madt_oem_check = summit_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = summit_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
|
|
@ -213,6 +213,7 @@ static struct apic apic_x2apic_cluster = {
|
|||
.name = "cluster x2apic",
|
||||
.probe = x2apic_cluster_probe,
|
||||
.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = x2apic_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_LowestPrio,
|
||||
|
|
|
@ -119,6 +119,7 @@ static struct apic apic_x2apic_phys = {
|
|||
.name = "physical x2apic",
|
||||
.probe = x2apic_phys_probe,
|
||||
.acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = x2apic_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -351,6 +351,7 @@ static struct apic __refdata apic_x2apic_uv_x = {
|
|||
.name = "UV large system",
|
||||
.probe = uv_probe,
|
||||
.acpi_madt_oem_check = uv_acpi_madt_oem_check,
|
||||
.apic_id_valid = default_apic_id_valid,
|
||||
.apic_id_registered = uv_apic_id_registered,
|
||||
|
||||
.irq_delivery_mode = dest_Fixed,
|
||||
|
|
|
@ -847,7 +847,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)
|
|||
|
||||
if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid ||
|
||||
!physid_isset(apicid, phys_cpu_present_map) ||
|
||||
(!x2apic_mode && apicid >= 255)) {
|
||||
!apic->apic_id_valid(apicid)) {
|
||||
printk(KERN_ERR "%s: bad cpu %d\n", __func__, cpu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче