|
@@ -189,24 +189,31 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void acpi_register_lapic(int id, u8 enabled)
|
|
|
+/**
|
|
|
+ * acpi_register_lapic - register a local apic and generates a logic cpu number
|
|
|
+ * @id: local apic id to register
|
|
|
+ * @enabled: this cpu is enabled or not
|
|
|
+ *
|
|
|
+ * Returns the logic cpu number which maps to the local apic
|
|
|
+ */
|
|
|
+static int acpi_register_lapic(int id, u8 enabled)
|
|
|
{
|
|
|
unsigned int ver = 0;
|
|
|
|
|
|
if (id >= MAX_LOCAL_APIC) {
|
|
|
printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
|
|
|
- return;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (!enabled) {
|
|
|
++disabled_cpus;
|
|
|
- return;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (boot_cpu_physical_apicid != -1U)
|
|
|
ver = apic_version[boot_cpu_physical_apicid];
|
|
|
|
|
|
- generic_processor_info(id, ver);
|
|
|
+ return generic_processor_info(id, ver);
|
|
|
}
|
|
|
|
|
|
static int __init
|
|
@@ -614,84 +621,27 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-static int _acpi_map_lsapic(acpi_handle handle, int *pcpu)
|
|
|
+static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
|
|
|
{
|
|
|
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
|
- union acpi_object *obj;
|
|
|
- struct acpi_madt_local_apic *lapic;
|
|
|
- cpumask_var_t tmp_map, new_map;
|
|
|
- u8 physid;
|
|
|
int cpu;
|
|
|
- int retval = -ENOMEM;
|
|
|
-
|
|
|
- if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- if (!buffer.length || !buffer.pointer)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- obj = buffer.pointer;
|
|
|
- if (obj->type != ACPI_TYPE_BUFFER ||
|
|
|
- obj->buffer.length < sizeof(*lapic)) {
|
|
|
- kfree(buffer.pointer);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
|
|
|
- lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer;
|
|
|
-
|
|
|
- if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC ||
|
|
|
- !(lapic->lapic_flags & ACPI_MADT_ENABLED)) {
|
|
|
- kfree(buffer.pointer);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- physid = lapic->id;
|
|
|
-
|
|
|
- kfree(buffer.pointer);
|
|
|
- buffer.length = ACPI_ALLOCATE_BUFFER;
|
|
|
- buffer.pointer = NULL;
|
|
|
- lapic = NULL;
|
|
|
-
|
|
|
- if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL))
|
|
|
- goto out;
|
|
|
-
|
|
|
- if (!alloc_cpumask_var(&new_map, GFP_KERNEL))
|
|
|
- goto free_tmp_map;
|
|
|
-
|
|
|
- cpumask_copy(tmp_map, cpu_present_mask);
|
|
|
- acpi_register_lapic(physid, ACPI_MADT_ENABLED);
|
|
|
-
|
|
|
- /*
|
|
|
- * If acpi_register_lapic successfully generates a new logical cpu
|
|
|
- * number, then the following will get us exactly what was mapped
|
|
|
- */
|
|
|
- cpumask_andnot(new_map, cpu_present_mask, tmp_map);
|
|
|
- if (cpumask_empty(new_map)) {
|
|
|
- printk ("Unable to map lapic to logical cpu number\n");
|
|
|
- retval = -EINVAL;
|
|
|
- goto free_new_map;
|
|
|
+ cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED);
|
|
|
+ if (cpu < 0) {
|
|
|
+ pr_info(PREFIX "Unable to map lapic to logical cpu number\n");
|
|
|
+ return cpu;
|
|
|
}
|
|
|
|
|
|
acpi_processor_set_pdc(handle);
|
|
|
-
|
|
|
- cpu = cpumask_first(new_map);
|
|
|
acpi_map_cpu2node(handle, cpu, physid);
|
|
|
|
|
|
*pcpu = cpu;
|
|
|
- retval = 0;
|
|
|
-
|
|
|
-free_new_map:
|
|
|
- free_cpumask_var(new_map);
|
|
|
-free_tmp_map:
|
|
|
- free_cpumask_var(tmp_map);
|
|
|
-out:
|
|
|
- return retval;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/* wrapper to silence section mismatch warning */
|
|
|
-int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu)
|
|
|
+int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)
|
|
|
{
|
|
|
- return _acpi_map_lsapic(handle, pcpu);
|
|
|
+ return _acpi_map_lsapic(handle, physid, pcpu);
|
|
|
}
|
|
|
EXPORT_SYMBOL(acpi_map_lsapic);
|
|
|
|