Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d554a7b authored by Alex Chiang's avatar Alex Chiang Committed by Len Brown
Browse files

ACPI: processor: add internal processor_physically_present()



Detect if a processor is physically present before evaluating _PDC.

We want this because some BIOS will provide a _PDC even for processors
that are not present. These bogus _PDC methods then attempt to load
non-existent tables, which causes problems.

Avoid those bogus landmines.

Acked-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarAlex Chiang <achiang@hp.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 78ed8bd2
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -194,6 +194,45 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
EXPORT_SYMBOL_GPL(acpi_get_cpuid);
#endif

static bool processor_physically_present(acpi_handle handle)
{
	int cpuid, type;
	u32 acpi_id;
	acpi_status status;
	acpi_object_type acpi_type;
	unsigned long long tmp;
	union acpi_object object = { 0 };
	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };

	status = acpi_get_type(handle, &acpi_type);
	if (ACPI_FAILURE(status))
		return false;

	switch (acpi_type) {
	case ACPI_TYPE_PROCESSOR:
		status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
		if (ACPI_FAILURE(status))
			return false;
		acpi_id = object.processor.proc_id;
		break;
	case ACPI_TYPE_DEVICE:
		status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
		if (ACPI_FAILURE(status))
			return false;
		acpi_id = tmp;
		break;
	default:
		return false;
	}

	type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
	cpuid = acpi_get_cpuid(handle, type, acpi_id);

	if (cpuid == -1)
		return false;

	return true;
}

static void acpi_set_pdc_bits(u32 *buf)
{
@@ -335,6 +374,9 @@ static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
static acpi_status
early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
{
	if (processor_physically_present(handle) == false)
		return AE_OK;

	acpi_processor_set_pdc(handle);
	return AE_OK;
}