// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2012 Intel Corporation
 *    Author: Liu Jinsong <jinsong.liu@intel.com>
 *    Author: Jiang Yunhong <yunhong.jiang@intel.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/cpu.h>
#include <linux/acpi.h>
#include <linux/uaccess.h>
#include <acpi/processor.h>
#include <xen/acpi.h>
#include <xen/interface/platform.h>
#include <asm/xen/hypercall.h>

#define PREFIX "ACPI:xen_cpu_hotplug:"

#define INSTALL_NOTIFY_HANDLER		0
#define UNINSTALL_NOTIFY_HANDLER	1

static acpi_status xen_acpi_cpu_hotadd(struct acpi_processor *pr);

/* --------------------------------------------------------------------------
				Driver Interface
-------------------------------------------------------------------------- */

static int xen_acpi_processor_enable(struct acpi_device *device)
{
	acpi_status status = 0;
	unsigned long long value;
	union acpi_object object = { 0 };
	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
	struct acpi_processor *pr = acpi_driver_data(device);

	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
		/* Declared with "Processor" statement; match ProcessorID */
		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
		if (ACPI_FAILURE(status)) {
			pr_err(PREFIX "Evaluating processor object\n");
			return -ENODEV;
		}

		pr->acpi_id = object.processor.proc_id;
	} else {
		/* Declared with "Device" statement; match _UID */
		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
						NULL, &value);
		if (ACPI_FAILURE(status)) {
			pr_err(PREFIX "Evaluating processor _UID\n");
			return -ENODEV;
		}

		pr->acpi_id = value;
	}

	pr->id = xen_pcpu_id(pr->acpi_id);

	if (invalid_logical_cpuid(pr->id))
		/* This cpu is not presented at hypervisor, try to hotadd it */
		if (ACPI_FAILURE(xen_acpi_cpu_hotadd(pr))) {
			pr_err(PREFIX "Hotadd CPU (acpi_id = %d) failed.\n",
					pr->acpi_id);
			return -ENODEV;
		}

	return 0;
}

static int xen_acpi_processor_add(struct acpi_device *device)
{
	int ret;
	struct acpi_processor *pr;

	if (!device)
		return -EINVAL;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	ret = xen_acpi_processor_enable(device);
	if (ret)
		pr_err(PREFIX "Error when enabling Xen processor\n");

	return ret;
}

static int xen_acpi_processor_remove(struct acpi_device *device)
{
	struct acpi_processor *pr;

	if (!device)
		return -EINVAL;

	pr = acpi_driver_data(device);
	if (!pr)
		return -EINVAL;

	kfree(pr);
	return 0;
}

/*--------------------------------------------------------------
		Acpi processor hotplug support
--------------------------------------------------------------*/

static int is_processor_present(acpi_handle handle)
{
	acpi_status status;
	unsigned long long sta = 0;


	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);

	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
		return 1;

	/*
	 * _STA is mandatory for a processor that supports hot plug
	 */
	if (status == AE_NOT_FOUND)
		pr_info(PREFIX "Processor does not support hot plug\n");
	else
		pr_info(PREFIX "Processor Device is not present");
	return 0;
}

static int xen_apic_id(acpi_handle handle)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj;
	struct acpi_madt_local_apic *lapic;
	int apic_id;

	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;
	}

	apic_id = (uint32_t)lapic->id;
	kfree(buffer.pointer);
	buffer.length = ACPI_ALLOCATE_BUFFER;
	buffer.pointer = NULL;

	return apic_id;
}

static int xen_hotadd_cpu(struct acpi_processor *pr)
{
	int cpu_id, apic_id, pxm;
	struct xen_platform_op op;

	apic_id = xen_apic_id(pr->handle);
	if (apic_id < 0) {
		pr_err(PREFIX "Failed to get apic_id for acpi_id %d\n",
				pr->acpi_id);
		return -ENODEV;
	}

	pxm = xen_acpi_get_pxm(pr->handle);
	if (pxm < 0) {
		pr_err(PREFIX "Failed to get _PXM for acpi_id %d\n",
				pr->acpi_id);
		return pxm;
	}

	op.cmd = XENPF_cpu_hotadd;
	op.u.cpu_add.apic_id = apic_id;
	op.u.cpu_add.acpi_id = pr->acpi_id;
	op.u.cpu_add.pxm = pxm;

	cpu_id = HYPERVISOR_platform_op(&op);
	if (cpu_id < 0)
		pr_err(PREFIX "Failed to hotadd CPU for acpi_id %d\n",
				pr->acpi_id);

	return cpu_id;
}

static acpi_status xen_acpi_cpu_hotadd(struct acpi_processor *pr)
{
	if (!is_processor_present(pr->handle))
		return AE_ERROR;

	pr->id = xen_hotadd_cpu(pr);
	if (invalid_logical_cpuid(pr->id))
		return AE_ERROR;

	/*
	 * Sync with Xen hypervisor, providing new /sys/.../xen_cpuX
	 * interface after cpu hotadded.
	 */
	xen_pcpu_hotplug_sync();

	return AE_OK;
}

static int acpi_processor_device_remove(struct acpi_device *device)
{
	pr_debug(PREFIX "Xen does not support CPU hotremove\n");

	return -ENOSYS;
}

static void acpi_processor_hotplug_notify(acpi_handle handle,
					  u32 event, void *data)
{
	struct acpi_processor *pr;
	struct acpi_device *device = NULL;
	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
	int result;

	acpi_scan_lock_acquire();

	switch (event) {
	case ACPI_NOTIFY_BUS_CHECK:
	case ACPI_NOTIFY_DEVICE_CHECK:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			"Processor driver received %s event\n",
			(event == ACPI_NOTIFY_BUS_CHECK) ?
			"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));

		if (!is_processor_present(handle))
			break;

		acpi_bus_get_device(handle, &device);
		if (acpi_device_enumerated(device))
			break;

		result = acpi_bus_scan(handle);
		if (result) {
			pr_err(PREFIX "Unable to add the device\n");
			break;
		}
		device = NULL;
		acpi_bus_get_device(handle, &device);
		if (!acpi_device_enumerated(device)) {
			pr_err(PREFIX "Missing device object\n");
			break;
		}
		ost_code = ACPI_OST_SC_SUCCESS;
		break;

	case ACPI_NOTIFY_EJECT_REQUEST:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));

		if (acpi_bus_get_device(handle, &device)) {
			pr_err(PREFIX "Device don't exist, dropping EJECT\n");
			break;
		}
		pr = acpi_driver_data(device);
		if (!pr) {
			pr_err(PREFIX "Driver data is NULL, dropping EJECT\n");
			break;
		}

		/*
		 * TBD: implement acpi_processor_device_remove if Xen support
		 * CPU hotremove in the future.
		 */
		acpi_processor_device_remove(device);
		break;

	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Unsupported event [0x%x]\n", event));

		/* non-hotplug event; possibly handled by other handler */
		goto out;
	}

	(void) acpi_evaluate_ost(handle, event, ost_code, NULL);

out:
	acpi_scan_lock_release();
}

static acpi_status is_processor_device(acpi_handle handle)
{
	struct acpi_device_info *info;
	char *hid;
	acpi_status status;

	status = acpi_get_object_info(handle, &info);
	if (ACPI_FAILURE(status))
		return status;

	if (info->type == ACPI_TYPE_PROCESSOR) {
		kfree(info);
		return AE_OK;	/* found a processor object */
	}

	if (!(info->valid & ACPI_VALID_HID)) {
		kfree(info);
		return AE_ERROR;
	}

	hid = info->hardware_id.string;
	if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
		kfree(info);
		return AE_ERROR;
	}

	kfree(info);
	return AE_OK;	/* found a processor device object */
}

static acpi_status
processor_walk_namespace_cb(acpi_handle handle,
			    u32 lvl, void *context, void **rv)
{
	acpi_status status;
	int *action = context;

	status = is_processor_device(handle);
	if (ACPI_FAILURE(status))
		return AE_OK;	/* not a processor; continue to walk */

	switch (*action) {
	case INSTALL_NOTIFY_HANDLER:
		acpi_install_notify_handler(handle,
					    ACPI_SYSTEM_NOTIFY,
					    acpi_processor_hotplug_notify,
					    NULL);
		break;
	case UNINSTALL_NOTIFY_HANDLER:
		acpi_remove_notify_handler(handle,
					   ACPI_SYSTEM_NOTIFY,
					   acpi_processor_hotplug_notify);
		break;
	default:
		break;
	}

	/* found a processor; skip walking underneath */
	return AE_CTRL_DEPTH;
}

static
void acpi_processor_install_hotplug_notify(void)
{
	int action = INSTALL_NOTIFY_HANDLER;
	acpi_walk_namespace(ACPI_TYPE_ANY,
			    ACPI_ROOT_OBJECT,
			    ACPI_UINT32_MAX,
			    processor_walk_namespace_cb, NULL, &action, NULL);
}

static
void acpi_processor_uninstall_hotplug_notify(void)
{
	int action = UNINSTALL_NOTIFY_HANDLER;
	acpi_walk_namespace(ACPI_TYPE_ANY,
			    ACPI_ROOT_OBJECT,
			    ACPI_UINT32_MAX,
			    processor_walk_namespace_cb, NULL, &action, NULL);
}

static const struct acpi_device_id processor_device_ids[] = {
	{ACPI_PROCESSOR_OBJECT_HID, 0},
	{ACPI_PROCESSOR_DEVICE_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, processor_device_ids);

static struct acpi_driver xen_acpi_processor_driver = {
	.name = "processor",
	.class = ACPI_PROCESSOR_CLASS,
	.ids = processor_device_ids,
	.ops = {
		.add = xen_acpi_processor_add,
		.remove = xen_acpi_processor_remove,
		},
};

static int __init xen_acpi_processor_init(void)
{
	int result = 0;

	if (!xen_initial_domain())
		return -ENODEV;

	/* unregister the stub which only used to reserve driver space */
	xen_stub_processor_exit();

	result = acpi_bus_register_driver(&xen_acpi_processor_driver);
	if (result < 0) {
		xen_stub_processor_init();
		return result;
	}

	acpi_processor_install_hotplug_notify();
	return 0;
}

static void __exit xen_acpi_processor_exit(void)
{
	if (!xen_initial_domain())
		return;

	acpi_processor_uninstall_hotplug_notify();

	acpi_bus_unregister_driver(&xen_acpi_processor_driver);

	/*
	 * stub reserve space again to prevent any chance of native
	 * driver loading.
	 */
	xen_stub_processor_init();
	return;
}

module_init(xen_acpi_processor_init);
module_exit(xen_acpi_processor_exit);
ACPI_MODULE_NAME("xen-acpi-cpuhotplug");
MODULE_AUTHOR("Liu Jinsong <jinsong.liu@intel.com>");
MODULE_DESCRIPTION("Xen Hotplug CPU Driver");
MODULE_LICENSE("GPL");
