xref: /OK3568_Linux_fs/kernel/drivers/xen/xen-acpi-processor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright 2012 by Oracle Inc
4*4882a593Smuzhiyun  * Author: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This code borrows ideas from https://lkml.org/lkml/2011/11/30/249
7*4882a593Smuzhiyun  * so many thanks go to Kevin Tian <kevin.tian@intel.com>
8*4882a593Smuzhiyun  * and Yu Ke <ke.yu@intel.com>.
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/cpumask.h>
14*4882a593Smuzhiyun #include <linux/cpufreq.h>
15*4882a593Smuzhiyun #include <linux/freezer.h>
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/kthread.h>
18*4882a593Smuzhiyun #include <linux/init.h>
19*4882a593Smuzhiyun #include <linux/module.h>
20*4882a593Smuzhiyun #include <linux/types.h>
21*4882a593Smuzhiyun #include <linux/syscore_ops.h>
22*4882a593Smuzhiyun #include <linux/acpi.h>
23*4882a593Smuzhiyun #include <acpi/processor.h>
24*4882a593Smuzhiyun #include <xen/xen.h>
25*4882a593Smuzhiyun #include <xen/interface/platform.h>
26*4882a593Smuzhiyun #include <asm/xen/hypercall.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun static int no_hypercall;
29*4882a593Smuzhiyun MODULE_PARM_DESC(off, "Inhibit the hypercall.");
30*4882a593Smuzhiyun module_param_named(off, no_hypercall, int, 0400);
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun  * Note: Do not convert the acpi_id* below to cpumask_var_t or use cpumask_bit
34*4882a593Smuzhiyun  * - as those shrink to nr_cpu_bits (which is dependent on possible_cpu), which
35*4882a593Smuzhiyun  * can be less than what we want to put in. Instead use the 'nr_acpi_bits'
36*4882a593Smuzhiyun  * which is dynamically computed based on the MADT or x2APIC table.
37*4882a593Smuzhiyun  */
38*4882a593Smuzhiyun static unsigned int nr_acpi_bits;
39*4882a593Smuzhiyun /* Mutex to protect the acpi_ids_done - for CPU hotplug use. */
40*4882a593Smuzhiyun static DEFINE_MUTEX(acpi_ids_mutex);
41*4882a593Smuzhiyun /* Which ACPI ID we have processed from 'struct acpi_processor'. */
42*4882a593Smuzhiyun static unsigned long *acpi_ids_done;
43*4882a593Smuzhiyun /* Which ACPI ID exist in the SSDT/DSDT processor definitions. */
44*4882a593Smuzhiyun static unsigned long *acpi_id_present;
45*4882a593Smuzhiyun /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */
46*4882a593Smuzhiyun static unsigned long *acpi_id_cst_present;
47*4882a593Smuzhiyun /* Which ACPI P-State dependencies for a enumerated processor */
48*4882a593Smuzhiyun static struct acpi_psd_package *acpi_psd;
49*4882a593Smuzhiyun 
push_cxx_to_hypervisor(struct acpi_processor * _pr)50*4882a593Smuzhiyun static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	struct xen_platform_op op = {
53*4882a593Smuzhiyun 		.cmd			= XENPF_set_processor_pminfo,
54*4882a593Smuzhiyun 		.interface_version	= XENPF_INTERFACE_VERSION,
55*4882a593Smuzhiyun 		.u.set_pminfo.id	= _pr->acpi_id,
56*4882a593Smuzhiyun 		.u.set_pminfo.type	= XEN_PM_CX,
57*4882a593Smuzhiyun 	};
58*4882a593Smuzhiyun 	struct xen_processor_cx *dst_cx, *dst_cx_states = NULL;
59*4882a593Smuzhiyun 	struct acpi_processor_cx *cx;
60*4882a593Smuzhiyun 	unsigned int i, ok;
61*4882a593Smuzhiyun 	int ret = 0;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	dst_cx_states = kcalloc(_pr->power.count,
64*4882a593Smuzhiyun 				sizeof(struct xen_processor_cx), GFP_KERNEL);
65*4882a593Smuzhiyun 	if (!dst_cx_states)
66*4882a593Smuzhiyun 		return -ENOMEM;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	for (ok = 0, i = 1; i <= _pr->power.count; i++) {
69*4882a593Smuzhiyun 		cx = &_pr->power.states[i];
70*4882a593Smuzhiyun 		if (!cx->valid)
71*4882a593Smuzhiyun 			continue;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 		dst_cx = &(dst_cx_states[ok++]);
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 		dst_cx->reg.space_id = ACPI_ADR_SPACE_SYSTEM_IO;
76*4882a593Smuzhiyun 		if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
77*4882a593Smuzhiyun 			dst_cx->reg.bit_width = 8;
78*4882a593Smuzhiyun 			dst_cx->reg.bit_offset = 0;
79*4882a593Smuzhiyun 			dst_cx->reg.access_size = 1;
80*4882a593Smuzhiyun 		} else {
81*4882a593Smuzhiyun 			dst_cx->reg.space_id = ACPI_ADR_SPACE_FIXED_HARDWARE;
82*4882a593Smuzhiyun 			if (cx->entry_method == ACPI_CSTATE_FFH) {
83*4882a593Smuzhiyun 				/* NATIVE_CSTATE_BEYOND_HALT */
84*4882a593Smuzhiyun 				dst_cx->reg.bit_offset = 2;
85*4882a593Smuzhiyun 				dst_cx->reg.bit_width = 1; /* VENDOR_INTEL */
86*4882a593Smuzhiyun 			}
87*4882a593Smuzhiyun 			dst_cx->reg.access_size = 0;
88*4882a593Smuzhiyun 		}
89*4882a593Smuzhiyun 		dst_cx->reg.address = cx->address;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 		dst_cx->type = cx->type;
92*4882a593Smuzhiyun 		dst_cx->latency = cx->latency;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 		dst_cx->dpcnt = 0;
95*4882a593Smuzhiyun 		set_xen_guest_handle(dst_cx->dp, NULL);
96*4882a593Smuzhiyun 	}
97*4882a593Smuzhiyun 	if (!ok) {
98*4882a593Smuzhiyun 		pr_debug("No _Cx for ACPI CPU %u\n", _pr->acpi_id);
99*4882a593Smuzhiyun 		kfree(dst_cx_states);
100*4882a593Smuzhiyun 		return -EINVAL;
101*4882a593Smuzhiyun 	}
102*4882a593Smuzhiyun 	op.u.set_pminfo.power.count = ok;
103*4882a593Smuzhiyun 	op.u.set_pminfo.power.flags.bm_control = _pr->flags.bm_control;
104*4882a593Smuzhiyun 	op.u.set_pminfo.power.flags.bm_check = _pr->flags.bm_check;
105*4882a593Smuzhiyun 	op.u.set_pminfo.power.flags.has_cst = _pr->flags.has_cst;
106*4882a593Smuzhiyun 	op.u.set_pminfo.power.flags.power_setup_done =
107*4882a593Smuzhiyun 		_pr->flags.power_setup_done;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	set_xen_guest_handle(op.u.set_pminfo.power.states, dst_cx_states);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	if (!no_hypercall)
112*4882a593Smuzhiyun 		ret = HYPERVISOR_platform_op(&op);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (!ret) {
115*4882a593Smuzhiyun 		pr_debug("ACPI CPU%u - C-states uploaded.\n", _pr->acpi_id);
116*4882a593Smuzhiyun 		for (i = 1; i <= _pr->power.count; i++) {
117*4882a593Smuzhiyun 			cx = &_pr->power.states[i];
118*4882a593Smuzhiyun 			if (!cx->valid)
119*4882a593Smuzhiyun 				continue;
120*4882a593Smuzhiyun 			pr_debug("     C%d: %s %d uS\n",
121*4882a593Smuzhiyun 				 cx->type, cx->desc, (u32)cx->latency);
122*4882a593Smuzhiyun 		}
123*4882a593Smuzhiyun 	} else if ((ret != -EINVAL) && (ret != -ENOSYS))
124*4882a593Smuzhiyun 		/* EINVAL means the ACPI ID is incorrect - meaning the ACPI
125*4882a593Smuzhiyun 		 * table is referencing a non-existing CPU - which can happen
126*4882a593Smuzhiyun 		 * with broken ACPI tables. */
127*4882a593Smuzhiyun 		pr_err("(CX): Hypervisor error (%d) for ACPI CPU%u\n",
128*4882a593Smuzhiyun 		       ret, _pr->acpi_id);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	kfree(dst_cx_states);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	return ret;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun static struct xen_processor_px *
xen_copy_pss_data(struct acpi_processor * _pr,struct xen_processor_performance * dst_perf)135*4882a593Smuzhiyun xen_copy_pss_data(struct acpi_processor *_pr,
136*4882a593Smuzhiyun 		  struct xen_processor_performance *dst_perf)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun 	struct xen_processor_px *dst_states = NULL;
139*4882a593Smuzhiyun 	unsigned int i;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	BUILD_BUG_ON(sizeof(struct xen_processor_px) !=
142*4882a593Smuzhiyun 		     sizeof(struct acpi_processor_px));
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	dst_states = kcalloc(_pr->performance->state_count,
145*4882a593Smuzhiyun 			     sizeof(struct xen_processor_px), GFP_KERNEL);
146*4882a593Smuzhiyun 	if (!dst_states)
147*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	dst_perf->state_count = _pr->performance->state_count;
150*4882a593Smuzhiyun 	for (i = 0; i < _pr->performance->state_count; i++) {
151*4882a593Smuzhiyun 		/* Fortunatly for us, they are both the same size */
152*4882a593Smuzhiyun 		memcpy(&(dst_states[i]), &(_pr->performance->states[i]),
153*4882a593Smuzhiyun 		       sizeof(struct acpi_processor_px));
154*4882a593Smuzhiyun 	}
155*4882a593Smuzhiyun 	return dst_states;
156*4882a593Smuzhiyun }
xen_copy_psd_data(struct acpi_processor * _pr,struct xen_processor_performance * dst)157*4882a593Smuzhiyun static int xen_copy_psd_data(struct acpi_processor *_pr,
158*4882a593Smuzhiyun 			     struct xen_processor_performance *dst)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	struct acpi_psd_package *pdomain;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	BUILD_BUG_ON(sizeof(struct xen_psd_package) !=
163*4882a593Smuzhiyun 		     sizeof(struct acpi_psd_package));
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* This information is enumerated only if acpi_processor_preregister_performance
166*4882a593Smuzhiyun 	 * has been called.
167*4882a593Smuzhiyun 	 */
168*4882a593Smuzhiyun 	dst->shared_type = _pr->performance->shared_type;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	pdomain = &(_pr->performance->domain_info);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* 'acpi_processor_preregister_performance' does not parse if the
173*4882a593Smuzhiyun 	 * num_processors <= 1, but Xen still requires it. Do it manually here.
174*4882a593Smuzhiyun 	 */
175*4882a593Smuzhiyun 	if (pdomain->num_processors <= 1) {
176*4882a593Smuzhiyun 		if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
177*4882a593Smuzhiyun 			dst->shared_type = CPUFREQ_SHARED_TYPE_ALL;
178*4882a593Smuzhiyun 		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
179*4882a593Smuzhiyun 			dst->shared_type = CPUFREQ_SHARED_TYPE_HW;
180*4882a593Smuzhiyun 		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
181*4882a593Smuzhiyun 			dst->shared_type = CPUFREQ_SHARED_TYPE_ANY;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 	memcpy(&(dst->domain_info), pdomain, sizeof(struct acpi_psd_package));
185*4882a593Smuzhiyun 	return 0;
186*4882a593Smuzhiyun }
xen_copy_pct_data(struct acpi_pct_register * pct,struct xen_pct_register * dst_pct)187*4882a593Smuzhiyun static int xen_copy_pct_data(struct acpi_pct_register *pct,
188*4882a593Smuzhiyun 			     struct xen_pct_register *dst_pct)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	/* It would be nice if you could just do 'memcpy(pct, dst_pct') but
191*4882a593Smuzhiyun 	 * sadly the Xen structure did not have the proper padding so the
192*4882a593Smuzhiyun 	 * descriptor field takes two (dst_pct) bytes instead of one (pct).
193*4882a593Smuzhiyun 	 */
194*4882a593Smuzhiyun 	dst_pct->descriptor = pct->descriptor;
195*4882a593Smuzhiyun 	dst_pct->length = pct->length;
196*4882a593Smuzhiyun 	dst_pct->space_id = pct->space_id;
197*4882a593Smuzhiyun 	dst_pct->bit_width = pct->bit_width;
198*4882a593Smuzhiyun 	dst_pct->bit_offset = pct->bit_offset;
199*4882a593Smuzhiyun 	dst_pct->reserved = pct->reserved;
200*4882a593Smuzhiyun 	dst_pct->address = pct->address;
201*4882a593Smuzhiyun 	return 0;
202*4882a593Smuzhiyun }
push_pxx_to_hypervisor(struct acpi_processor * _pr)203*4882a593Smuzhiyun static int push_pxx_to_hypervisor(struct acpi_processor *_pr)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	int ret = 0;
206*4882a593Smuzhiyun 	struct xen_platform_op op = {
207*4882a593Smuzhiyun 		.cmd			= XENPF_set_processor_pminfo,
208*4882a593Smuzhiyun 		.interface_version	= XENPF_INTERFACE_VERSION,
209*4882a593Smuzhiyun 		.u.set_pminfo.id	= _pr->acpi_id,
210*4882a593Smuzhiyun 		.u.set_pminfo.type	= XEN_PM_PX,
211*4882a593Smuzhiyun 	};
212*4882a593Smuzhiyun 	struct xen_processor_performance *dst_perf;
213*4882a593Smuzhiyun 	struct xen_processor_px *dst_states = NULL;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	dst_perf = &op.u.set_pminfo.perf;
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	dst_perf->platform_limit = _pr->performance_platform_limit;
218*4882a593Smuzhiyun 	dst_perf->flags |= XEN_PX_PPC;
219*4882a593Smuzhiyun 	xen_copy_pct_data(&(_pr->performance->control_register),
220*4882a593Smuzhiyun 			  &dst_perf->control_register);
221*4882a593Smuzhiyun 	xen_copy_pct_data(&(_pr->performance->status_register),
222*4882a593Smuzhiyun 			  &dst_perf->status_register);
223*4882a593Smuzhiyun 	dst_perf->flags |= XEN_PX_PCT;
224*4882a593Smuzhiyun 	dst_states = xen_copy_pss_data(_pr, dst_perf);
225*4882a593Smuzhiyun 	if (!IS_ERR_OR_NULL(dst_states)) {
226*4882a593Smuzhiyun 		set_xen_guest_handle(dst_perf->states, dst_states);
227*4882a593Smuzhiyun 		dst_perf->flags |= XEN_PX_PSS;
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 	if (!xen_copy_psd_data(_pr, dst_perf))
230*4882a593Smuzhiyun 		dst_perf->flags |= XEN_PX_PSD;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	if (dst_perf->flags != (XEN_PX_PSD | XEN_PX_PSS | XEN_PX_PCT | XEN_PX_PPC)) {
233*4882a593Smuzhiyun 		pr_warn("ACPI CPU%u missing some P-state data (%x), skipping\n",
234*4882a593Smuzhiyun 			_pr->acpi_id, dst_perf->flags);
235*4882a593Smuzhiyun 		ret = -ENODEV;
236*4882a593Smuzhiyun 		goto err_free;
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	if (!no_hypercall)
240*4882a593Smuzhiyun 		ret = HYPERVISOR_platform_op(&op);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (!ret) {
243*4882a593Smuzhiyun 		struct acpi_processor_performance *perf;
244*4882a593Smuzhiyun 		unsigned int i;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 		perf = _pr->performance;
247*4882a593Smuzhiyun 		pr_debug("ACPI CPU%u - P-states uploaded.\n", _pr->acpi_id);
248*4882a593Smuzhiyun 		for (i = 0; i < perf->state_count; i++) {
249*4882a593Smuzhiyun 			pr_debug("     %cP%d: %d MHz, %d mW, %d uS\n",
250*4882a593Smuzhiyun 			(i == perf->state ? '*' : ' '), i,
251*4882a593Smuzhiyun 			(u32) perf->states[i].core_frequency,
252*4882a593Smuzhiyun 			(u32) perf->states[i].power,
253*4882a593Smuzhiyun 			(u32) perf->states[i].transition_latency);
254*4882a593Smuzhiyun 		}
255*4882a593Smuzhiyun 	} else if ((ret != -EINVAL) && (ret != -ENOSYS))
256*4882a593Smuzhiyun 		/* EINVAL means the ACPI ID is incorrect - meaning the ACPI
257*4882a593Smuzhiyun 		 * table is referencing a non-existing CPU - which can happen
258*4882a593Smuzhiyun 		 * with broken ACPI tables. */
259*4882a593Smuzhiyun 		pr_warn("(_PXX): Hypervisor error (%d) for ACPI CPU%u\n",
260*4882a593Smuzhiyun 			ret, _pr->acpi_id);
261*4882a593Smuzhiyun err_free:
262*4882a593Smuzhiyun 	if (!IS_ERR_OR_NULL(dst_states))
263*4882a593Smuzhiyun 		kfree(dst_states);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	return ret;
266*4882a593Smuzhiyun }
upload_pm_data(struct acpi_processor * _pr)267*4882a593Smuzhiyun static int upload_pm_data(struct acpi_processor *_pr)
268*4882a593Smuzhiyun {
269*4882a593Smuzhiyun 	int err = 0;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	mutex_lock(&acpi_ids_mutex);
272*4882a593Smuzhiyun 	if (__test_and_set_bit(_pr->acpi_id, acpi_ids_done)) {
273*4882a593Smuzhiyun 		mutex_unlock(&acpi_ids_mutex);
274*4882a593Smuzhiyun 		return -EBUSY;
275*4882a593Smuzhiyun 	}
276*4882a593Smuzhiyun 	if (_pr->flags.power)
277*4882a593Smuzhiyun 		err = push_cxx_to_hypervisor(_pr);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	if (_pr->performance && _pr->performance->states)
280*4882a593Smuzhiyun 		err |= push_pxx_to_hypervisor(_pr);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	mutex_unlock(&acpi_ids_mutex);
283*4882a593Smuzhiyun 	return err;
284*4882a593Smuzhiyun }
get_max_acpi_id(void)285*4882a593Smuzhiyun static unsigned int __init get_max_acpi_id(void)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	struct xenpf_pcpuinfo *info;
288*4882a593Smuzhiyun 	struct xen_platform_op op = {
289*4882a593Smuzhiyun 		.cmd = XENPF_get_cpuinfo,
290*4882a593Smuzhiyun 		.interface_version = XENPF_INTERFACE_VERSION,
291*4882a593Smuzhiyun 	};
292*4882a593Smuzhiyun 	int ret = 0;
293*4882a593Smuzhiyun 	unsigned int i, last_cpu, max_acpi_id = 0;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	info = &op.u.pcpu_info;
296*4882a593Smuzhiyun 	info->xen_cpuid = 0;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	ret = HYPERVISOR_platform_op(&op);
299*4882a593Smuzhiyun 	if (ret)
300*4882a593Smuzhiyun 		return NR_CPUS;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	/* The max_present is the same irregardless of the xen_cpuid */
303*4882a593Smuzhiyun 	last_cpu = op.u.pcpu_info.max_present;
304*4882a593Smuzhiyun 	for (i = 0; i <= last_cpu; i++) {
305*4882a593Smuzhiyun 		info->xen_cpuid = i;
306*4882a593Smuzhiyun 		ret = HYPERVISOR_platform_op(&op);
307*4882a593Smuzhiyun 		if (ret)
308*4882a593Smuzhiyun 			continue;
309*4882a593Smuzhiyun 		max_acpi_id = max(info->acpi_id, max_acpi_id);
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun 	max_acpi_id *= 2; /* Slack for CPU hotplug support. */
312*4882a593Smuzhiyun 	pr_debug("Max ACPI ID: %u\n", max_acpi_id);
313*4882a593Smuzhiyun 	return max_acpi_id;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun /*
316*4882a593Smuzhiyun  * The read_acpi_id and check_acpi_ids are there to support the Xen
317*4882a593Smuzhiyun  * oddity of virtual CPUs != physical CPUs in the initial domain.
318*4882a593Smuzhiyun  * The user can supply 'xen_max_vcpus=X' on the Xen hypervisor line
319*4882a593Smuzhiyun  * which will band the amount of CPUs the initial domain can see.
320*4882a593Smuzhiyun  * In general that is OK, except it plays havoc with any of the
321*4882a593Smuzhiyun  * for_each_[present|online]_cpu macros which are banded to the virtual
322*4882a593Smuzhiyun  * CPU amount.
323*4882a593Smuzhiyun  */
324*4882a593Smuzhiyun static acpi_status
read_acpi_id(acpi_handle handle,u32 lvl,void * context,void ** rv)325*4882a593Smuzhiyun read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	u32 acpi_id;
328*4882a593Smuzhiyun 	acpi_status status;
329*4882a593Smuzhiyun 	acpi_object_type acpi_type;
330*4882a593Smuzhiyun 	unsigned long long tmp;
331*4882a593Smuzhiyun 	union acpi_object object = { 0 };
332*4882a593Smuzhiyun 	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
333*4882a593Smuzhiyun 	acpi_io_address pblk = 0;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	status = acpi_get_type(handle, &acpi_type);
336*4882a593Smuzhiyun 	if (ACPI_FAILURE(status))
337*4882a593Smuzhiyun 		return AE_OK;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	switch (acpi_type) {
340*4882a593Smuzhiyun 	case ACPI_TYPE_PROCESSOR:
341*4882a593Smuzhiyun 		status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
342*4882a593Smuzhiyun 		if (ACPI_FAILURE(status))
343*4882a593Smuzhiyun 			return AE_OK;
344*4882a593Smuzhiyun 		acpi_id = object.processor.proc_id;
345*4882a593Smuzhiyun 		pblk = object.processor.pblk_address;
346*4882a593Smuzhiyun 		break;
347*4882a593Smuzhiyun 	case ACPI_TYPE_DEVICE:
348*4882a593Smuzhiyun 		status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
349*4882a593Smuzhiyun 		if (ACPI_FAILURE(status))
350*4882a593Smuzhiyun 			return AE_OK;
351*4882a593Smuzhiyun 		acpi_id = tmp;
352*4882a593Smuzhiyun 		break;
353*4882a593Smuzhiyun 	default:
354*4882a593Smuzhiyun 		return AE_OK;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 	if (invalid_phys_cpuid(acpi_get_phys_id(handle,
357*4882a593Smuzhiyun 						acpi_type == ACPI_TYPE_DEVICE,
358*4882a593Smuzhiyun 						acpi_id))) {
359*4882a593Smuzhiyun 		pr_debug("CPU with ACPI ID %u is unavailable\n", acpi_id);
360*4882a593Smuzhiyun 		return AE_OK;
361*4882a593Smuzhiyun 	}
362*4882a593Smuzhiyun 	/* There are more ACPI Processor objects than in x2APIC or MADT.
363*4882a593Smuzhiyun 	 * This can happen with incorrect ACPI SSDT declerations. */
364*4882a593Smuzhiyun 	if (acpi_id >= nr_acpi_bits) {
365*4882a593Smuzhiyun 		pr_debug("max acpi id %u, trying to set %u\n",
366*4882a593Smuzhiyun 			 nr_acpi_bits - 1, acpi_id);
367*4882a593Smuzhiyun 		return AE_OK;
368*4882a593Smuzhiyun 	}
369*4882a593Smuzhiyun 	/* OK, There is a ACPI Processor object */
370*4882a593Smuzhiyun 	__set_bit(acpi_id, acpi_id_present);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	pr_debug("ACPI CPU%u w/ PBLK:0x%lx\n", acpi_id, (unsigned long)pblk);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	/* It has P-state dependencies */
375*4882a593Smuzhiyun 	if (!acpi_processor_get_psd(handle, &acpi_psd[acpi_id])) {
376*4882a593Smuzhiyun 		pr_debug("ACPI CPU%u w/ PST:coord_type = %llu domain = %llu\n",
377*4882a593Smuzhiyun 			 acpi_id, acpi_psd[acpi_id].coord_type,
378*4882a593Smuzhiyun 			 acpi_psd[acpi_id].domain);
379*4882a593Smuzhiyun 	}
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	status = acpi_evaluate_object(handle, "_CST", NULL, &buffer);
382*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
383*4882a593Smuzhiyun 		if (!pblk)
384*4882a593Smuzhiyun 			return AE_OK;
385*4882a593Smuzhiyun 	}
386*4882a593Smuzhiyun 	/* .. and it has a C-state */
387*4882a593Smuzhiyun 	__set_bit(acpi_id, acpi_id_cst_present);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	return AE_OK;
390*4882a593Smuzhiyun }
check_acpi_ids(struct acpi_processor * pr_backup)391*4882a593Smuzhiyun static int check_acpi_ids(struct acpi_processor *pr_backup)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	if (!pr_backup)
395*4882a593Smuzhiyun 		return -ENODEV;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	if (acpi_id_present && acpi_id_cst_present)
398*4882a593Smuzhiyun 		/* OK, done this once .. skip to uploading */
399*4882a593Smuzhiyun 		goto upload;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	/* All online CPUs have been processed at this stage. Now verify
402*4882a593Smuzhiyun 	 * whether in fact "online CPUs" == physical CPUs.
403*4882a593Smuzhiyun 	 */
404*4882a593Smuzhiyun 	acpi_id_present = bitmap_zalloc(nr_acpi_bits, GFP_KERNEL);
405*4882a593Smuzhiyun 	if (!acpi_id_present)
406*4882a593Smuzhiyun 		return -ENOMEM;
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	acpi_id_cst_present = bitmap_zalloc(nr_acpi_bits, GFP_KERNEL);
409*4882a593Smuzhiyun 	if (!acpi_id_cst_present) {
410*4882a593Smuzhiyun 		bitmap_free(acpi_id_present);
411*4882a593Smuzhiyun 		return -ENOMEM;
412*4882a593Smuzhiyun 	}
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	acpi_psd = kcalloc(nr_acpi_bits, sizeof(struct acpi_psd_package),
415*4882a593Smuzhiyun 			   GFP_KERNEL);
416*4882a593Smuzhiyun 	if (!acpi_psd) {
417*4882a593Smuzhiyun 		bitmap_free(acpi_id_present);
418*4882a593Smuzhiyun 		bitmap_free(acpi_id_cst_present);
419*4882a593Smuzhiyun 		return -ENOMEM;
420*4882a593Smuzhiyun 	}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
423*4882a593Smuzhiyun 			    ACPI_UINT32_MAX,
424*4882a593Smuzhiyun 			    read_acpi_id, NULL, NULL, NULL);
425*4882a593Smuzhiyun 	acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, read_acpi_id, NULL, NULL);
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun upload:
428*4882a593Smuzhiyun 	if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) {
429*4882a593Smuzhiyun 		unsigned int i;
430*4882a593Smuzhiyun 		for_each_set_bit(i, acpi_id_present, nr_acpi_bits) {
431*4882a593Smuzhiyun 			pr_backup->acpi_id = i;
432*4882a593Smuzhiyun 			/* Mask out C-states if there are no _CST or PBLK */
433*4882a593Smuzhiyun 			pr_backup->flags.power = test_bit(i, acpi_id_cst_present);
434*4882a593Smuzhiyun 			/* num_entries is non-zero if we evaluated _PSD */
435*4882a593Smuzhiyun 			if (acpi_psd[i].num_entries) {
436*4882a593Smuzhiyun 				memcpy(&pr_backup->performance->domain_info,
437*4882a593Smuzhiyun 				       &acpi_psd[i],
438*4882a593Smuzhiyun 				       sizeof(struct acpi_psd_package));
439*4882a593Smuzhiyun 			}
440*4882a593Smuzhiyun 			(void)upload_pm_data(pr_backup);
441*4882a593Smuzhiyun 		}
442*4882a593Smuzhiyun 	}
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	return 0;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun /* acpi_perf_data is a pointer to percpu data. */
448*4882a593Smuzhiyun static struct acpi_processor_performance __percpu *acpi_perf_data;
449*4882a593Smuzhiyun 
free_acpi_perf_data(void)450*4882a593Smuzhiyun static void free_acpi_perf_data(void)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun 	unsigned int i;
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	/* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
455*4882a593Smuzhiyun 	for_each_possible_cpu(i)
456*4882a593Smuzhiyun 		free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
457*4882a593Smuzhiyun 				 ->shared_cpu_map);
458*4882a593Smuzhiyun 	free_percpu(acpi_perf_data);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun 
xen_upload_processor_pm_data(void)461*4882a593Smuzhiyun static int xen_upload_processor_pm_data(void)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun 	struct acpi_processor *pr_backup = NULL;
464*4882a593Smuzhiyun 	unsigned int i;
465*4882a593Smuzhiyun 	int rc = 0;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	pr_info("Uploading Xen processor PM info\n");
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	for_each_possible_cpu(i) {
470*4882a593Smuzhiyun 		struct acpi_processor *_pr;
471*4882a593Smuzhiyun 		_pr = per_cpu(processors, i /* APIC ID */);
472*4882a593Smuzhiyun 		if (!_pr)
473*4882a593Smuzhiyun 			continue;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 		if (!pr_backup) {
476*4882a593Smuzhiyun 			pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
477*4882a593Smuzhiyun 			if (pr_backup)
478*4882a593Smuzhiyun 				memcpy(pr_backup, _pr, sizeof(struct acpi_processor));
479*4882a593Smuzhiyun 		}
480*4882a593Smuzhiyun 		(void)upload_pm_data(_pr);
481*4882a593Smuzhiyun 	}
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	rc = check_acpi_ids(pr_backup);
484*4882a593Smuzhiyun 	kfree(pr_backup);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	return rc;
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun 
xen_acpi_processor_resume_worker(struct work_struct * dummy)489*4882a593Smuzhiyun static void xen_acpi_processor_resume_worker(struct work_struct *dummy)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun 	int rc;
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	bitmap_zero(acpi_ids_done, nr_acpi_bits);
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	rc = xen_upload_processor_pm_data();
496*4882a593Smuzhiyun 	if (rc != 0)
497*4882a593Smuzhiyun 		pr_info("ACPI data upload failed, error = %d\n", rc);
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
xen_acpi_processor_resume(void)500*4882a593Smuzhiyun static void xen_acpi_processor_resume(void)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	static DECLARE_WORK(wq, xen_acpi_processor_resume_worker);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	/*
505*4882a593Smuzhiyun 	 * xen_upload_processor_pm_data() calls non-atomic code.
506*4882a593Smuzhiyun 	 * However, the context for xen_acpi_processor_resume is syscore
507*4882a593Smuzhiyun 	 * with only the boot CPU online and in an atomic context.
508*4882a593Smuzhiyun 	 *
509*4882a593Smuzhiyun 	 * So defer the upload for some point safer.
510*4882a593Smuzhiyun 	 */
511*4882a593Smuzhiyun 	schedule_work(&wq);
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun static struct syscore_ops xap_syscore_ops = {
515*4882a593Smuzhiyun 	.resume	= xen_acpi_processor_resume,
516*4882a593Smuzhiyun };
517*4882a593Smuzhiyun 
xen_acpi_processor_init(void)518*4882a593Smuzhiyun static int __init xen_acpi_processor_init(void)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun 	unsigned int i;
521*4882a593Smuzhiyun 	int rc;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	if (!xen_initial_domain())
524*4882a593Smuzhiyun 		return -ENODEV;
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	nr_acpi_bits = get_max_acpi_id() + 1;
527*4882a593Smuzhiyun 	acpi_ids_done = bitmap_zalloc(nr_acpi_bits, GFP_KERNEL);
528*4882a593Smuzhiyun 	if (!acpi_ids_done)
529*4882a593Smuzhiyun 		return -ENOMEM;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
532*4882a593Smuzhiyun 	if (!acpi_perf_data) {
533*4882a593Smuzhiyun 		pr_debug("Memory allocation error for acpi_perf_data\n");
534*4882a593Smuzhiyun 		bitmap_free(acpi_ids_done);
535*4882a593Smuzhiyun 		return -ENOMEM;
536*4882a593Smuzhiyun 	}
537*4882a593Smuzhiyun 	for_each_possible_cpu(i) {
538*4882a593Smuzhiyun 		if (!zalloc_cpumask_var_node(
539*4882a593Smuzhiyun 			&per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map,
540*4882a593Smuzhiyun 			GFP_KERNEL, cpu_to_node(i))) {
541*4882a593Smuzhiyun 			rc = -ENOMEM;
542*4882a593Smuzhiyun 			goto err_out;
543*4882a593Smuzhiyun 		}
544*4882a593Smuzhiyun 	}
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	/* Do initialization in ACPI core. It is OK to fail here. */
547*4882a593Smuzhiyun 	(void)acpi_processor_preregister_performance(acpi_perf_data);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	for_each_possible_cpu(i) {
550*4882a593Smuzhiyun 		struct acpi_processor *pr;
551*4882a593Smuzhiyun 		struct acpi_processor_performance *perf;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 		pr = per_cpu(processors, i);
554*4882a593Smuzhiyun 		perf = per_cpu_ptr(acpi_perf_data, i);
555*4882a593Smuzhiyun 		if (!pr)
556*4882a593Smuzhiyun 			continue;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 		pr->performance = perf;
559*4882a593Smuzhiyun 		rc = acpi_processor_get_performance_info(pr);
560*4882a593Smuzhiyun 		if (rc)
561*4882a593Smuzhiyun 			goto err_out;
562*4882a593Smuzhiyun 	}
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun 	rc = xen_upload_processor_pm_data();
565*4882a593Smuzhiyun 	if (rc)
566*4882a593Smuzhiyun 		goto err_unregister;
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	register_syscore_ops(&xap_syscore_ops);
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	return 0;
571*4882a593Smuzhiyun err_unregister:
572*4882a593Smuzhiyun 	for_each_possible_cpu(i)
573*4882a593Smuzhiyun 		acpi_processor_unregister_performance(i);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun err_out:
576*4882a593Smuzhiyun 	/* Freeing a NULL pointer is OK: alloc_percpu zeroes. */
577*4882a593Smuzhiyun 	free_acpi_perf_data();
578*4882a593Smuzhiyun 	bitmap_free(acpi_ids_done);
579*4882a593Smuzhiyun 	return rc;
580*4882a593Smuzhiyun }
xen_acpi_processor_exit(void)581*4882a593Smuzhiyun static void __exit xen_acpi_processor_exit(void)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	int i;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	unregister_syscore_ops(&xap_syscore_ops);
586*4882a593Smuzhiyun 	bitmap_free(acpi_ids_done);
587*4882a593Smuzhiyun 	bitmap_free(acpi_id_present);
588*4882a593Smuzhiyun 	bitmap_free(acpi_id_cst_present);
589*4882a593Smuzhiyun 	kfree(acpi_psd);
590*4882a593Smuzhiyun 	for_each_possible_cpu(i)
591*4882a593Smuzhiyun 		acpi_processor_unregister_performance(i);
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	free_acpi_perf_data();
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun MODULE_AUTHOR("Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>");
597*4882a593Smuzhiyun MODULE_DESCRIPTION("Xen ACPI Processor P-states (and Cx) driver which uploads PM data to Xen hypervisor");
598*4882a593Smuzhiyun MODULE_LICENSE("GPL");
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun /* We want to be loaded before the CPU freq scaling drivers are loaded.
601*4882a593Smuzhiyun  * They are loaded in late_initcall. */
602*4882a593Smuzhiyun device_initcall(xen_acpi_processor_init);
603*4882a593Smuzhiyun module_exit(xen_acpi_processor_exit);
604